获取子进程的段错误回溯
Get segfault backtrace of child process
我有两个程序:A
和 B
。它们是不同的程序,B
不是 A
的分支。 A
启动 B
。问题:我可以从 A
获取 B
的分段错误的回溯吗?我无法修改 B
程序的源代码。
They are different programs,B is not a fork of A. A launches B
"launch",我猜你的意思是 A
做 fork
而 child 做 execvp
of B
I cannot modify source code of B
program.
这意味着您拥有B
的来源,但不能修改它,但是可以用-g
、-O0
和其他类似-fno-omit-frame-pointer
的东西重新编译它以获得调试符号和更准确的堆栈回溯的更好机会。
但是,另一种解释方式是,您只有 B
作为二进制可执行文件,没有 它的源代码。
我还推断你 有 A
的来源 [并且可以做任何必要的事情来使事情正常进行]。
Question: can I get backtrace of segmentation fault of B from A?
是的。有几种不同的方法。
A
可以在调用 B
时使用 ptrace
,就像 gdb
或 strace
一样。当 B
出现段错误时,A
可以获得控制权并返回堆栈并打印出来。
但是,这引出了一个问题:您的主要目标是 [只是] 调试 B
吗?让 A
做 gdb B
的 fork/exec
而不是仅仅 B
可能更容易,这样 gdb
就可以做 "heavy lifting" 作为堆栈回溯是一个简单的 gdb
命令。更简单的方法是通过在 shell 命令中启用限制并随后使用 gdb
检查核心文件来允许 B
转储核心。
另一个可能的选择。使用 readelf
查看 B
中的符号,并通过 ldd
查看所需的共享库列表。然后您可以决定 B
是否有任何 "hook" 点。也就是说,它想从共享库调用的任何符号,例如 open
.
您可以通过设置环境变量 LD_PRELOAD
创建一个包含 open
的特殊共享库,然后在 B
上 "force" 它。然后,当 B
调用 open
时,您的共享库获得控制权。然后,您可以为 SIGSEGV
安装信号处理程序,然后使用 dlsym
获取 "real" 打开的地址并完成 open
调用。
现在,当 B
出现段错误时,您特殊共享库中的信号处理程序可以通过 __builtin_return_address
等返回堆栈。阿尔。并将结果传回 A
(通过管道或套接字)
另一种方法是破解 B
可执行文件并添加一个与 A
通信的挂钩
我有两个程序:A
和 B
。它们是不同的程序,B
不是 A
的分支。 A
启动 B
。问题:我可以从 A
获取 B
的分段错误的回溯吗?我无法修改 B
程序的源代码。
They are different programs,B is not a fork of A. A launches B
"launch",我猜你的意思是 A
做 fork
而 child 做 execvp
of B
I cannot modify source code of
B
program.
这意味着您拥有B
的来源,但不能修改它,但是可以用-g
、-O0
和其他类似-fno-omit-frame-pointer
的东西重新编译它以获得调试符号和更准确的堆栈回溯的更好机会。
但是,另一种解释方式是,您只有 B
作为二进制可执行文件,没有 它的源代码。
我还推断你 有 A
的来源 [并且可以做任何必要的事情来使事情正常进行]。
Question: can I get backtrace of segmentation fault of B from A?
是的。有几种不同的方法。
A
可以在调用 B
时使用 ptrace
,就像 gdb
或 strace
一样。当 B
出现段错误时,A
可以获得控制权并返回堆栈并打印出来。
但是,这引出了一个问题:您的主要目标是 [只是] 调试 B
吗?让 A
做 gdb B
的 fork/exec
而不是仅仅 B
可能更容易,这样 gdb
就可以做 "heavy lifting" 作为堆栈回溯是一个简单的 gdb
命令。更简单的方法是通过在 shell 命令中启用限制并随后使用 gdb
检查核心文件来允许 B
转储核心。
另一个可能的选择。使用 readelf
查看 B
中的符号,并通过 ldd
查看所需的共享库列表。然后您可以决定 B
是否有任何 "hook" 点。也就是说,它想从共享库调用的任何符号,例如 open
.
您可以通过设置环境变量 LD_PRELOAD
创建一个包含 open
的特殊共享库,然后在 B
上 "force" 它。然后,当 B
调用 open
时,您的共享库获得控制权。然后,您可以为 SIGSEGV
安装信号处理程序,然后使用 dlsym
获取 "real" 打开的地址并完成 open
调用。
现在,当 B
出现段错误时,您特殊共享库中的信号处理程序可以通过 __builtin_return_address
等返回堆栈。阿尔。并将结果传回 A
(通过管道或套接字)
另一种方法是破解 B
可执行文件并添加一个与 A