从GDB中查看/打印函数代码

16

我试图开发一个简单的基于文本的用户界面来运行一些 gdb 命令。我希望用户能够在代码的特定区域设置和打断点,并运行一些调试命令。

我想让用户输入需要调试的函数名称。然后,我将获取这个函数名称并打印出函数的源代码,然后要求用户选择要设置断点/跟踪点的代码行。目前,使用 disassemble 命令,我可以为用户打印出内存地址,但我希望打印实际的源代码。

在gdb中是否能够实现这一点?

当前的情况:

Dump of assembler code for function test_function:
   0x03800f70 <test_function+0>:  push   %ebp
   0x03800f71 <test_function+1>:  mov    %esp,%ebp
   0x03800f73 <test_function+3>:  sub    $0x48,%esp

我要的是:

void main()
{
  printf("Hello World\n");
}

谢谢!

编辑: 我得到了这个:

(gdb) list myFunction
941     directory/directory_etc/sourcefile.c: No such file or directory.
        in directory/directory_etc/sourcefile.c

然后我尝试指定行号:

(gdb) list directory/directory_etc/sourcefile.c:941
936     in directory/directory_etc/sourcefile.c

所以行为与您描述的类似,但“list filename:linenum”仍然不起作用。

谢谢!


当前函数:https://dev59.com/smcs5IYBdhLWcg3wdz1m - Ciro Santilli OurBigBook.com
2个回答

15

使用:

(gdb) list FUNCTION

请查看 list 命令的在线帮助以获取详细信息:

Translated:

请查看 list 命令的在线帮助以获取详细信息:

(gdb) help list
List specified function or line.
With no argument, lists ten more lines after or around previous listing.
"list -" lists the ten lines before a previous ten-line listing.
One argument specifies a line, and ten lines are listed around that line.
Two arguments with comma between specify starting and ending lines to list.
Lines can be specified in these ways:
  LINENUM, to list around that line in current file,
  FILE:LINENUM, to list around that line in that file,
  FUNCTION, to list around beginning of that function,
  FILE:FUNCTION, to distinguish among like-named static functions.
  *ADDRESS, to list around the line containing that address.
With two args if one is empty it stands for ten lines away from the other arg.

对于任何非玩具项目,您可能会遇到这样的情况:

$ gdb /bin/true
<...>
(gdb) start
<...>
(gdb) list printf
file: "/usr/include/bits/stdio2.h", line number: 104
file: "printf.c", line number: 29

列出代码库中函数的多个定义。在上面的 printf() 例子中,非重载的纯 C 函数有两个定义。其中一个定义在 stdio2.h 中。您可以使用 list FILE:LINENUM 的形式来指定您想要列出哪一个:

(gdb) list printf.c:29
24  
25  /* Write formatted output to stdout from the format string FORMAT.  */
26  /* VARARGS1 */
27  int
28  __printf (const char *format, ...)
29  {
30    va_list arg;
31    int done;
32  
33    va_start (arg, format);

对于你看到的"sourcefile.c: No such file or directory"错误,你需要告诉GDB在哪里查找源代码。请参阅GDB手册:源路径。显然,你需要实际在你的计算机上拥有想要列出函数的源代码。


谢谢,当我在一个简单的文件(HelloWorld.exe)上运行这个命令时,它没有问题。然而,我正在尝试使用gdb来调试一个大型实时系统。我想查看的函数在许多c文件中的一个中,这些文件被编译成一个.elf文件,当我在那里运行它时,我得到了:(gdb) list FUNCTION 941 在directory/directory_etc/code.c中。 - user2342775
1
@user2342775,我已经修改了我的答案,针对当gdb的list命令显示一个函数名的多个定义的情况。这是你所看到的吗? - scottt
我已经编辑了我的原始问题,试图使其更易读,谢谢! - user2342775
有没有办法询问 gdb 函数定义的位置? - x-yuri
@x-yuri,是的!请尝试“(gdb) info line MY_FUNCTION”命令。我在这里写了一些有关使用GDB帮助浏览Linux内核代码的笔记:https://docs.google.com/document/d/1w1nPmCLpeRN3kEYglzHwozhWXY0ddT9oe6JCZocsPNE/edit#要真正使用这些功能,您需要阅读GDB手册中的“第9章查看源文件”。 - scottt

1

对于gcc:

在编译源代码时添加一个调试选项标志-g:

gcc -g test.c

测试时,请使用:

gdb ./a.out
(gdb) list

如果您需要更多功能,请查看手册页面:

man gcc
man gdb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接