Sun Studio 12 Update 1:使用 dbx 调试程序

开始调试 Java 应用程序

可以使用 dbx 调试以下类型的 Java 应用程序:

在上述所有情况下,dbx 均可识别其正在调试的是 Java 应用程序。

调试类文件

可以使用 dbx 调试文件扩展名为 .class 的文件,如下例所示。


(dbx) debug myclass.class

如果定义应用程序的类在包中定义,便需要如同在 JVM 软件上运行应用程序那样加入包的路径,如下例所示。


(dbx) debug java.pkg.Toy.class

也可以使用类文件的全路径名。dbx 通过在 .class 文件中进行查找来自动确定类路径的软件包部分,然后将全路径名的剩余部分添加到类路径中。例如,假定有以下路径名,dbx 会确定 pkg/Toy.class 是主类名,然后将 /home/user/java 添加到类路径中。


(dbx) debug /home/user/java/pkg/Toy.class

调试 JAR 文件

Java 应用程序可以使用 JAR(Java 归档)文件打包。可以使用 dbx 调试 JAR 文件,如下例所示。


(dbx) debug myjar.jar

开始调试文件名以 .jar 结尾的文件时,dbx 会使用在此 JAR 文件的清单中指定的 Main_Class 属性来确定主类。(主类是 JAR 文件内作为应用程序入口点的类。)如果使用全路径名或相对路径名来指定 JAR 文件,dbx 会使用目录名,并在 Main-Class 属性中将其作为类路径的前缀。

如果调试无 Main-Class 属性的 JAR 文件,可以使用 JAR URL 语法 jar:<url>!/{entry}(在 Java 2 平台标准版的 JarURLConnection 类中指定)来指定主类的名称,如以下示例所示。


(dbx) debug jar:myjar.jar!/myclass.class
(dbx) debug jar:/a/b/c/d/e.jar!/x/y/z.class
(dbx) debug jar:file:/a/b/c/d.jar!/myclass.class

对于这些示例中的每一个示例,dbx 都会执行以下操作:

调试有包装器的 Java 应用程序

Java 应用程序通常有一个用于设置环境变量的包装器。如果 Java 应用程序有包装器,需要通过设置 jvm_invocation 环境变量将要使用包装器脚本这一情况告知 dbx(请参见定制 JVM 软件的启动)。

dbx 连接到正在运行的 Java 应用程序

可以将 dbx 连接到正在运行的 Java 应用程序,前提是在启动该应用程序时指定了下例所示的选项。启动应用程序后,可以将 dbx 命令(请参见dbx 命令) 与正在运行的 Java 进程的进程 ID 结合使用以开始调试。


$ java -Djava.compiler=NONE -Xdebug -Xnoagent -Xrundbx_agent myclass.class
$ dbx - 2345

为了使 JVM 软件能够找到 libdbx_agent.so,需要在运行 Java 应用程序前将适当路径添加到 LD_LIBRARY_PATH 中:

installation_directory 是 Sun Studio 软件的安装位置。

dbx 连接到正在运行的应用程序时,dbx 会以 Java 模式开始调试应用程序。

如果 Java 应用程序需要 64 位目标库,请在启动应用程序时包括 -d64 选项。之后,将 dbx 连接到应用程序时,dbx 将使用运行该应用程序的 64 位 JVM 软件。


$ java -Djava.compiler=NONE -Xdebug -Xnoagent -Xrundbx_agent -d64 myclass.class
$ dbx - 2345

调试内嵌 Java 应用程序的 C 应用程序或 C++ 应用程序

可以使用 JNI_CreateJavaVM 接口调试内嵌 Java 应用程序的 C 应用程序或 C++ 应用程序。C 应用程序或 C++ 应用程序必须通过为 JVM 软件指定以下选项,才能启动 Java 应用程序:


-Xdebug -Xnoagent -Xrundbx_agent

为了使 JVM 软件能够找到 libdbx_agent.so,需要在运行 Java 应用程序前将适当路径添加到 LD_LIBRARY_PATH 中:

installation_directory 是 Sun Studio 软件的安装位置。

将参数传递给 JVM 软件

在 Java 模式下使用 run 命令时,会将提供的参数传递给应用程序,而非 JVM 软件。要将参数传递给 JVM 软件,请参见定制 JVM 软件的启动

指定 Java 源文件的位置

有时 Java 源文件与 .class.jar 文件不在同一目录中。可以使用 $JAVASRCPATH 环境变量指定 dbx 查找 Java 源文件的目录。例如,JAVASRCPATH=.:/mydir/mysrc:/mydir/mylibsrc:/mydir/myutils 会使 dbx 在与正被调试的类文件对应的源文件的列出目录中查找。

指定 C 源文件或 C++ 源文件的位置

在以下情况下,dbx 可能找不到 C 源文件或 C++ 源文件:

在此类情况下,请使用 pathmap 命令(请参见pathmap 命令)将一个路径名映射到另一个路径名,以便 dbx 可以找到您的文件。

为使用自定义类加载器的类文件指定路径

应用程序可以有从可能不属于常规类路径的位置装入类文件的定制类加载器。在这种情况下,dbx 找不到类文件。使用环境变量 CLASSPATHX 可以为 dbx 指定由定制类加载器装入的类文件的路径。例如,CLASSPATHX=.:/myloader/myclass:/mydir/mycustom 会使 dbx 在尝试查找类文件时到列出的目录中查找。

在 Java 方法中设置断点

与本地应用程序不同,Java 应用程序不包含便于访问的名称索引。因此不能简单地键入:


(dbx) stop in myMethod

而是需要使用方法的完整路径:


(dbx) stop in com.any.library.MyClass.myMethod

使用 MyClass 的某个方法停止时是一种例外情况,在这种情况下,使用 myMethod 就应足可以了。

避免包含该方法的完整路径的一种方式是,使用 stop inmethod


(dbx) stop inmethod myMethod

但是这样做可能会导致在多个方法名称 myMethod 中停止。

在本地 (JNI) 代码中设置断点

包含 JNI C 或 C++ 代码的共享库由 JVM 动态装入,在这些库中设置断点需要一些其他步骤。有关更多信息,请参见在动态装入的库中设置断点