我正在开发的一个程序崩溃并生成核心转储。我认为这个问题与调用它的参数有关,其中一些参数是由另一个(相当复杂的)程序自动生成的。所以我尝试使用gdb
来调试或file core.MyApplication.1234
获取参数。
然而,该命令相当冗长,输出如下所示:
core.MyApplication.1234: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from './MyApplication -view -mwip localhost -mwnp 12345 -mwlp 12346 -mwti 12347 -Debu'
(我确实更改了此示例的名称,但您明白了。)
我知道此后还有更多参数,但在核心文件中该命令始终被截断为 80 个字符。两者gdb
并file
报告这一点。看看输出,objdump
我不确定其余部分是否已写入核心转储,因为它似乎也在“-Debu”之后被切断。
我在 RHEL6 上运行它。我发现此线程来自 2007 年描述了使用 Solaris 系统的解决方案pargs
,但这在我的系统上不是有效的命令,并且我发现 Red Hat“等效项”仅适用于正在运行的进程,而不适用于核心文件。
如何恢复用于运行程序的整个命令?这可能吗?
答案1
数据在那里(至少有 999 个条目,总共至少有 6885 个字节的编号):
> cat segfault.c
int main(int argc, char *argv[])
{
char *s = "hello world";
*s = 'H';
}
> cc -g -o segfault segfault.c
> limit coredumpsize 9999999
> ./segfault `perl -le 'print "blah$_" for 1..999'`
Segmentation fault (core dumped)
> strings core.12231 | grep -c blah
1000
然后通过一些快速的 altagoobingleduckgoing gdb
,并假设调试符号,可以通过以下方式恢复:
> gdb ./segfault core.12231
...
(gdb) p argc
$1 = 1000
(gdb) x/1000s *argv
...
另一种选择是使用一个简单的 shell 包装器,该包装器"$@"
在某处记录,然后exec
使用给定的参数记录正确的程序。
答案2
我写了一个pargs
Linux 版本。因此,给定核心文件,您也可以在 RHEL 6 下显示所有参数:
$ pargs core.MyApplication.1234
argv[0]: /usr/libexec/gvfsd-network
argv[1]: --spawner
argv[2]: :1.16
argv[3]: /org/gtk/gvfs/exec_spaw/2
或者,如果您有gdb
并且可执行文件仍然可用,您可以使用 GDB 显示所有参数:
$ gdb MyApplication core.MyApplication.1234
(gdb) bt
[..]
#4 0x000055a376101e1b in main (argc=4, argv=0x7ffca4780f08)
at daemon-main-generic.c:45
(gdb) frame 4
(gdb) set print address off
(gdb) show print pretty
(gdb) p *argv@argc
$1 = {"/usr/libexec/gvfsd-network", "--spawner", ":1.16",
"/org/gtk/gvfs/exec_spaw/2"}
比较这两种方法,pargs
只需要一个核心文件,不需要进一步的交互输入。