只是好奇:当我在gdb中加载核心文件时,回溯看起来像这样:
...
Thread 2 (Thread 1109):
#0 0x2b03d968 in ?? ()
Thread 1 (Thread 23490):
#0 0x2b0c3624 in ?? ()
(gdb)
但是在使用'file'加载二进制文件后,我得到了这个:
...
#0 __pthread_cond_wait (cond=0x46b810, mutex=0x46b7f0) at pthread_cond_wait.c:156
#1 0x004076a8 in main (argc=1, argv=0x7fa66784) at idpoint.c:258
...
#0 0x2b0c3624 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:67
#1 0x2b0c8464 in *__GI_abort () at abort.c:88
#2 0x2b0faeec in __libc_message (do_abort=2, fmt=0x2b1d0840 "*** glibc detected *** %s: %s: 0x%s ***\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:173
#3 0x2b107e3c in malloc_printerr (action=3, str=0x2b1d0930 "free(): invalid next size (fast)", ptr=<value optimized out>) at malloc.c:5994
...
问题:为什么gdb甚至不会尝试在加载符号之前显示调用堆栈?我的猜测是它不知道哪些段放在内存中并且无法知道哪些堆栈数据被解释为数据与地址?这是对的吗?
如果有可能让gdb:s尽可能地显示没有符号的调用堆栈,了解堆栈深度,或者以后的解释,那将是很好的...
答案 0 :(得分:3)
因为二进制文件包含允许调试器理解的符号信息(调试符号),例如,每个函数的堆栈帧有多大[在函数中的任何给定时间!]。代码启动时,此信息不会加载到内存中,因此无法将其存储在core
文件中。
你当然可以使用x/200 $esp
(或者调用堆栈指针 - 我猜x86 - 如果它是ARM,那么它从内存中称为$R15
)。遗憾的是,如果无法访问符号,gdb
将无法真正知道堆栈中的内容,并且只能提供堆栈的原始转储 - 这在大多数情况下甚至会有所帮助比没有显示任何东西,因为显示随机数据的负载(并且大多数堆栈将是 - 特别是如果帧指针被关闭 - 使用帧指针你有一些机会取消嵌套堆栈)在大多数情况下都是无用的。