如何检查程序在 valgrind 下 运行 时生成的核心文件

How to examine a core file generated when program is running under valgrind

我有一个程序 myprog 我一直在 valgrind 下 运行ning:

/usr/bin/valgrind --tool=massif --tool=memcheck --leak-check=yes --track-origins=yes --log-file=/tmp/valgrind%p /opt/bin/myprog

我不太确定 valgrind 如何在幕后工作的细节,但是当 运行 以这种方式我看到 valgrind 有一个 pid,但是 myprog才不是。因此,我假设 valgrind 运行s myprog 在同一个进程中 space 并使用一些魔法来加载目标程序。

myprog 似乎命中了 assert() 并生成了核心文件。我想使用 GDB 检查这个核心文件,这样我就可以深入了解 assert() 的原因。我正在尝试弄清楚如何从使用 GDB 所需的 myprog 加载符号。

如果我使用 file valgrind,那么这只会加载 valgrind 符号,而不是 myprog

如果我使用 file myprog,则核心文件(由 valgrind 生成)将与可执行文件 (myprog) 不匹配。

有什么方法可以告诉 GDB,即使这里的 "host" 进程是 valgrind,我们也想加载 myprog 符号,因为这是程序我们到底有兴趣吗?

查看 GDB documentation,我猜我需要类似 add-symbol-file filename address 的内容,但我不确定如何确定地址。

I'm trying to figure out how to load symbols from myprog necessary to use GDB.

通常的方式:gdb ./myprog vgcore.1234.

If I use file myprog, then the corefile (generated by valgrind) won't match the executable (myprog).

应该匹配。要么你做错了什么(请 确切地告诉 你在做什么),要么你在 valgrindgdb.

中有错误

示例:

$ cat foo.c
int foo() { abort(); }
int bar() { return foo(); }
int main() { return bar(); }

$ gcc -g -w foo.c
$ valgrind ./a.out

==84263== Using Valgrind-3.9.0.SVN and LibVEX; rerun with -h for copyright info
==84263== Command: ./a.out
==84263==
==84263==
==84263== HEAP SUMMARY:
==84263==     in use at exit: 0 bytes in 0 blocks
==84263==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
...

$ ls -lrt
total 2116
-rw-r----- 1 er eng      80 Dec 15 20:18 foo.c
-rwxr-x--- 1 er eng    9558 Dec 15 20:21 a.out
-rw------- 1 er eng 4243434 Dec 15 20:21 vgcore.84263

$ gdb -q ./a.out vgcore.84263    
Reading symbols from ./a.out...done.
[New LWP 84263]
Core was generated by `'.
Program terminated with signal SIGABRT, Aborted.
#0  0x0000000004a5bc37 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56  ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x0000000004a5bc37 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x0000000004a5f028 in __GI_abort () at abort.c:89
#2  0x0000000000400536 in foo () at foo.c:1
#3  0x0000000000400544 in bar () at foo.c:2
#4  0x0000000000400554 in main () at foo.c:3