附加到进程
IntelliJ IDEA 提供了一种连接调试器到本地和远程进程的方法。
连接到进程的步骤取决于进程的启动方式和位置。
虽然 IntelliJ IDEA 调试器能够附加到任何进程,但建议在有更简单的方法时优先选择更简单的方法。 您不会想远程附加到运行在同一台机器上的“hello world”。
本主题中描述的选项在更复杂的情况下非常有用,例如当我们需要调试远程运行的进程,或以不允许调试的方式启动的进程时。
前提
虽然附加并非绝对必要,但需要满足以下先决条件以启用完整的调试功能:
远程进程应使用 debug agent启动。
该应用程序需要用 调试信息 编译。
您需要拥有 应用程序的源代码。
调试在这些条件都不满足时仍然是可能的,然而,每个条件都有其相关的限制。 这些要求将在后续章节中详细描述。
调试代理
允许调试器连接的进程由调试代理启动。 Debug agent 是宿主应用程序的一个组件,负责与调试器进行通信。 通信通过套接字连接进行,无论进程是本地还是远程。
使用调试代理启动进程
启动该进程时,在其 VM 选项中添加以下行:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005选项有以下参数:
address——将用于调试的端口server=y——指定进程应监听传入的调试器连接(作为服务器)。suspend– 指定 VM 应等待调试器连接还是立即开始执行应用程序代码
-agentlib:jdwp=transport=dt_socket,server=n,address=192.168.1.178:5005,suspend=y,onthrow=<FQ exception class name>,onuncaught=<y/n>选项有以下参数:
address- 服务器端的 IP 地址和端口。 同时支持 IPv4 和 IPv6。server=n指定该进程应连接到调试器(作为客户端)suspend=y– 指定 VM 应等待调试器连接后再执行应用程序代码。onthrow— 可选地延迟连接,直到抛出指定的异常。 使用异常的完全限定名称作为值。onuncaught- 可选地延迟连接,直到抛出未捕获的异常。 使用异常的完全限定名称作为值。
格式可能会根据 JDK 版本有所不同。 为了获取适用于您的 JDK 的格式化字符串,您可以在 Remote JVM debug 运行/调试配置中选择所需的 JDK 版本并从那里复制。
如果该进程是通过另一个进程启动的,例如像 Apache Tomcat 这样的 web 容器,则可能需要间接指定 debug agent VM 选项。 例如,其他进程可能使用配置文件将选项传递给主机 VM。 对于最受欢迎的的 Web 服务器和框架,IntelliJ IDEA 提供了 运行/调试配置来为您完成此操作。
添加 IntelliJ IDEA 的调试代理
当调试在 IntelliJ IDEA 之外启动的进程时,您可以使用 IntelliJ IDEA 的高级功能,例如 异步堆栈跟踪。 为此,您需要将 IntelliJ IDEA 的调试代理加载到进程中。
从 IntelliJ IDEA 的安装目录中添加 debugger-agent.jar ,使用
javaagentVM 选项。 例如:java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=\*:5005 -javaagent:"/Users/me.user/Applications/IntelliJ IDEA Ultimate 2024.3.app/Contents/plugins/java/lib/rt/debugger-agent.jar" Alphabet
如果本地进程未使用调试代理,您仍然可以以只读模式附加到该进程。 调试器功能将仅限于查看调用栈和检查相关的局部变量。
这种模式可能有用的一个示例是,当您的程序在批量处理某些文件时挂起。 使用只读模式,您可以找出是哪个方法导致程序挂起,以及它正在处理哪个文件。
调试信息
调试信息是一种特殊的信息,存在于应用程序字节码中。 调试器使用此信息来识别局部变量、行号等。 应用程序的字节码可能包含或不包含调试信息。
调试信息在编译时提供给程序。 这是通过 -g 编译器标志控制的。 默认情况下,编译器会包含大部分调试所需的信息,但如果不是您编译的应用程序,可能会发生这样的情况:您要调试的程序在编译时没有包含这些信息。
如果应用程序的字节码不包含调试信息,调试器仍然可以附加,但某些调试器功能可能不可用。 例如,没有行号信息时,无法查看行号或在断点处停止:

无论是否存在调试信息,始终可用的最低限度:
类名,除非代码被混淆
静态变量和实例变量
调用堆栈
有关配置调试信息生成的更多信息,请参阅 Java 编译器文档。
应用程序源文件
建议您拥有调试项目源代码的访问权限。 IntelliJ IDEA 将调试事件与源代码匹配,并在编辑器中显示与调试会话相关的信息。 这使您可以将调试会话视为正在执行的源代码。

为了让 IntelliJ IDEA 找到源文件,它们必须包含在类路径中。
附加到远程进程
连接到远程进程包括两个步骤:
创建运行/调试配置 – 运行/调试配置指定了如何建立连接。 一旦创建了运行/调试配置,它可以用于同一主机和端口的其他连接。
启动运行/调试配置 – 当您启动运行/调试配置时,IntelliJ IDEA 会根据运行/调试配置中定义的设置启动并连接调试器。
创建运行/调试配置
前往 。 或者,按 Alt+Shift+F10 ,然后按 0。
在 运行/调试配置对话框中,点击
工具栏上的按钮或按下 Alt+Insert。 选择 远程 JVM 调试 从列表中。
在 调试器模式 指定调试器是应连接到远程 JVM 还是监听传入的连接。
如果您选择 侦听远程 JVM ,请指定在远程 JVM 断开连接后是否要自动重新启动调试器。 这样,调试器将随时准备处理传入的连接。
(适用于 Windows)可选地指定所需的 传输方式。 IntelliJ IDEA 会自动选择适当的传输方式,因此除非您对通信方法有特殊要求,否则无需配置。
指定远程 JVM 的主机和端口。 同时支持 IPv4 和 IPv6。 请确保端口指定正确、未被占用且未被防火墙阻止。
指定查找源代码的模块。 IntelliJ IDEA 将首先检查选定的模块,然后是其他模块(如果有的话)。 源使用完全限定类名进行匹配。 如果完全限定名称没有匹配项,IntelliJ IDEA 会尝试通过文件名查找匹配项。
如果您尚未为调试对象 JVM 配置调试代理,您可以从 远程 JVM 的命令行参数 字段中复制所需的 VM option。

开始运行/调试配置
附加到本地进程
按 Ctrl+Alt+F5 或从主菜单中选择 。
IntelliJ IDEA 将显示正在运行的本地进程列表。 请选择要附加的进程。

使用 debug agent 启动的进程显示在 Java 下。 不使用 调试代理的列在 Java Read Only 下。 更多关于只读模式的信息 在这里。
当进程过多时,您可以通过输入进程名称或 PID 的首字母缩小列表范围。
附加到当前进程
如果您使用 IntelliJ IDEA 的调试代理运行该进程,您可以直接从控制台附加到它。
从 IntelliJ IDEA 运行带有调试代理的进程。
当控制台出现时,点击 附加调试器 嵌入提示。

从进程中分离
从远程进程分离的步骤与停止本地调试会话的步骤相同。 然而,与本地会话不同的是,目标进程在调试器分离后会继续运行。
点击 停止
按钮,位于 调试 工具窗口的工具栏上或 Debug(调试)工具窗口 中。

或者,点击 停止
主工具栏上的 Ctrl+F2 ,然后选择要关闭的会话。

终止远程进程
当您不再需要远程进程时,可以通过关闭相应的调试器选项卡来终止它。 默认情况下,IntelliJ IDEA 会询问您是否要终止进程或与其断开连接:

您可以在 外观与行为 | 系统设置 设置页面  Ctrl+Alt+S 上自定义默认选项。
