我了解 strace 和 ltrace,但这仅告诉我进程正在执行哪些系统调用和库调用。我想确切地知道进程正在执行什么指令。要么是汇编,要么是 C 语言和汇编之间的某种中间立场(如果可能的话)。假设二进制文件尚未使用调试符号进行编译,因此更有可能倾向于第一个选项。
使用案例:进程似乎挂起,strace 或 ltrace 没有输出。确定进程是否正在做“某事”。我意识到这可能很难确定,因为我认为这类似于解决停止问题。然而,也许可以收集有用的数据。
第二个用例:好奇心。将整个汇编指令列表转储到文本列表中会很有趣。
我的猜测是我可以使用 gdb 来执行此操作,但不确定如何操作,因为这不是关于调试我编写的程序,而是更多关于使用 gdb 检查正在运行的进程的运行状况。
操作系统是CentOS 6。
答案1
您可以使用gdb
: 命令来执行此操作ni
并si
一次运行一条指令。对于“next”的大多数值,命令n
运行下一行代码。对于n
(以及相应的s
),您必须进行编译,以便调试符号出现在可执行文件中。
这个 stackoverflow 答案给出了几种或多或少在视觉上做到这一点的方法。
命令gdb
:display/i $pc
在执行之前向您显示指令。display $pc
显示之前的代码行n
或s
执行它。
答案2
运行ps -l
进程 ID 并检查S
(“状态”)列。如果状态为R
,则您的进程正在执行代码。如果进程保持在状态R
并且strace
不显示它执行任何系统调用,则进程将陷入非常长的、可能是无限的计算中。如果进程处于并保持状态D
,则它在系统调用中被阻止。有关进程状态的更多信息,请参见这个进程STAT表示什么?,“可中断睡眠”状态表示什么?和如果“kill -9”不起作用怎么办?。
如果进程正在运行长时间计算,您可以使用 Gdb(或其他调试器)来查看它在做什么。如果可执行文件缺少调试信息(如果您没有专门编译程序,通常会出现这种情况),那么调试器将只能向您显示机器指令;如果可执行文件包含调试信息,您将能够在堆栈跟踪等中看到函数名称。要将 Gdb 连接到进程,请运行gdb /path/to/executable 1234
where 1234
is the process ID。该命令s
允许您一次执行一个指令。除非您是一名程序员并且对程序应该执行的操作有些熟悉,否则在这种情况下您几乎不可能从 Gdb 中获得有用的信息。