我有两个程序:A
和B
。它们是不同的程序,B
不是A
的分支。 A
启动B
。问题:我可以从B
获取A
的分段错误的回溯吗?我无法修改B
程序的源代码。
答案 0 :(得分:1)
它们是不同的程序,B不是A的分支.A启动B
通过“发布”,我认为你的意思是A
执行fork
而孩子执行execvp
B
我无法修改
B
程序的源代码。
这意味着您拥有 B
的来源,但不能修改它,但可以使用{重新编译它{1}},-g
以及-O0
之类的其他内容可以获得调试符号,更有可能获得更准确的堆栈追溯。
然而,解释这一点的另一种方法是你只有-fno-omit-frame-pointer
作为二进制可执行文件并且不有源代码。
我还推断你拥有<{1}}的来源[并且可以做任何必要的事情来使事情有效]。
问题:我可以从A中获得B的分段故障的回溯吗?
是。有几种不同的方式。
B
在调用A
时可以使用A
,就像ptrace
或B
一样。当gdb
段错误时,strace
可以控制并返回堆栈并将其打印出来。
但是,这引出了一个问题:你的主要目标是[仅]调试B
吗?让A
B
A
代替fork/exec
而不仅仅是gdb B
可能更容易,因此B
可以作为堆栈执行“繁重的工作” traceback是一个简单的gdb
命令。更简单的方法是允许gdb
通过在shell命令中启用限制并在之后使用B
检查核心文件来转储核心。
另一种可能的选择。使用gdb
查看B
中的符号以及readelf
所需的共享库列表。然后,您可以决定ldd
是否有任何“挂钩”点。也就是说,它想要从共享库调用的任何符号,例如B
。
您可以在其中创建一个包含open
的特殊共享库,然后通过设置环境变量open
在B
上“强制”它。然后,当LD_PRELOAD
调用B
时,您的共享库会获得控制权。然后,您可以为open
安装信号处理程序,然后使用SIGSEGV
获取“真实”的地址,并完成dlsym
调用。
现在,当open
段错误时,特殊共享库中的信号处理程序可以通过B
et返回堆栈。人。并将结果传回__builtin_return_address
(通过管道或套接字)
另一种方法是破解A
可执行文件并添加一个与B