如何从外部分离 gdb 会话?
Posted
技术标签:
【中文标题】如何从外部分离 gdb 会话?【英文标题】:How can I detach a gdb session from outside? 【发布时间】:2021-02-24 20:06:41 【问题描述】:我使用如下命令在后台启动一个 gdb 会话:
gdb --batch --command=/tmp/my_automated_breakpoints.gdb -p pid_of_proces> &> /tmp/gdb-results.log &
最后的&
让它在后台运行(随后shell 立即关闭,因为此命令由单个ssh
命令发出)。
我可以通过ps -aux | grep gdb
找到gdb
会话的pid
。
但是:我如何才能优雅地将这个 gdb 会话从正在运行的进程中分离出来,就像我使用 (gdb) detach
命令在我面前有终端会话一样?
当我使用 kill -9 gdb_pid
终止 gdb 会话(而不是正在运行的进程本身)时,之后我在运行的程序中得到了不需要的 SIGABRT
s。
重新启动服务对我来说太耗时了。
如果使用此自动化脚本成功调试会话,我可以在批处理脚本中使用分离命令。然而这不是我的情况:我想在会话期间出现一些错误时分离/退出正在运行的 gdb 会话,所以我想从另一个终端会话中手动优雅地分离 gdb。
【问题讨论】:
可能相关:unix.stackexchange.com/q/31824/291769 我假设您的批处理命令正在循环运行?否则它应该结束它的协议。如果是这种情况,一种解决方法是让循环定期检查文件的存在(或不存在)。如果检测到文件,则循环应退出并分离。然后通过创建(或删除)文件来“发出信号”gdb 将是一件简单的事情。 @kaylum 有趣的想法!但是,批处理命令只是挂在continue
中并等待断点与服务的操作相匹配。所以没有真正的循环,它只是在等待......
您能向我们展示来自 SIGABRT 的堆栈跟踪吗?据我所知,最坏的情况——GDB 不删除断点并且目标在分离后继续——将导致目标获得 SIGTRAP。
【参考方案1】:
如果您在后台从终端#1 运行gdb
命令,则始终可以通过运行命令fg
将gdb
带回前台。然后,您可以像往常一样简单地 CTRL+C 和detach
优雅地停止调试会话。
假设终端#1现在被其他东西占用而你不能使用它,你可以发送一个SIGHUP
信号给gdb
进程来分离它:
sudo kill -s SIGHUP $(pidof gdb)
(如果您有多个 gdb 实例,请将 $(pidof gdb)
替换为实际 PID)
【讨论】:
我喜欢SIGHUP
方法,但遗憾的是它没有解决服务内部的SIGABRT
信号。可能杀gdb甚至都没有因果关系,我这里只是观察到一个规律。
@ElectRocnic,我刚刚在我的机器上运行了一个快速测试,并且在底层应用程序运行时向 GDB 发送 SIGHUP 将分离它并 SIGCONT 应用程序。你能解释一下:“当会话期间出现一些错误时,我想分离/退出正在运行的 gdb 会话”。这些错误是否在调试会话中?
在我在第一个请求期间分离 gdb 后,在对调试的应用程序的第二个 API 请求进行某些 io 处理期间,错误是意外 EOF。它可能真的只是服务本身。我真的相信你的答案是正确的。以上是关于如何从外部分离 gdb 会话?的主要内容,如果未能解决你的问题,请参考以下文章