【问题标题】:debug a process with gdb and close the terminal使用 gdb 调试进程并关闭终端
【发布时间】:2014-12-21 09:24:08
【问题描述】:

我在远程服务器上运行的应用程序中有一个错误。执行几个小时后,应用程序会收到一个 SIGSEGV 并终止。

我想通过 ssh 使用 gdb 调试我的远程应用程序,因此当程序获得 SIGSEGV 时 gdb 将停止并允许我查看发生了什么,但我无法将 ssh 会话留给连接的服务器。我正在尝试运行:

setsid gdb my_app

但是当我关闭 ssh 终端时,gdb 和我的应用程序会立即终止。

我的问题:

  • 如何在关闭终端时让 gdb 继续运行
  • 以后如何重新连接?

strace 在 gdb 上关闭终端的那一刻显示:

read(0, 0x7fff0532895f, 1)              = -1 EIO (Input/output error)
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7fff05328930) = -1 EIO (Input/output error)
ioctl(0, SNDCTL_TMR_STOP or SNDRV_TIMER_IOCTL_GINFO or TCSETSW, {B38400 opost isig -icanon -echo ...}) = -1 EIO (Input/output error)
rt_sigaction(SIGINT, {0x5b3550, [INT], SA_RESTORER|SA_RESTART, 0x7fa0fbaa0c90}, {0x7fa0fce86ac0, [], SA_RESTORER, 0x7fa0fbaa0c90}, 8) = 0
rt_sigaction(SIGTERM, {0x5b3710, [TERM], SA_RESTORER|SA_RESTART, 0x7fa0fbaa0c90}, {0x7fa0fce86ac0, [], SA_RESTORER, 0x7fa0fbaa0c90}, 8) = 0
rt_sigaction(SIGHUP, {0x5b33d0, [HUP], SA_RESTORER|SA_RESTART, 0x7fa0fbaa0c90}, {0x7fa0fce86ac0, [], SA_RESTORER, 0x7fa0fbaa0c90}, 8) = 0
rt_sigaction(SIGQUIT, {0x5b33f0, [QUIT], SA_RESTORER|SA_RESTART, 0x7fa0fbaa0c90}, {0x7fa0fce86ac0, [], SA_RESTORER, 0x7fa0fbaa0c90}, 8) = 0
rt_sigaction(SIGALRM, {SIG_DFL, [], SA_RESTORER, 0x7fa0fbaa0c90}, {0x7fa0fce86ac0, [], SA_RESTORER, 0x7fa0fbaa0c90}, 8) = 0
rt_sigaction(SIGTSTP, {SIG_DFL, [TSTP], SA_RESTORER|SA_RESTART, 0x7fa0fbaa0c90}, {0x7fa0fce86ac0, [], SA_RESTORER, 0x7fa0fbaa0c90}, 8) = 0
rt_sigaction(SIGTTOU, {SIG_DFL, [], SA_RESTORER, 0x7fa0fbaa0c90}, {0x7fa0fce86ac0, [], SA_RESTORER, 0x7fa0fbaa0c90}, 8) = 0
rt_sigaction(SIGTTIN, {SIG_DFL, [], SA_RESTORER, 0x7fa0fbaa0c90}, {0x7fa0fce86ac0, [], SA_RESTORER, 0x7fa0fbaa0c90}, 8) = 0
rt_sigaction(SIGWINCH, {0x4efb70, [], SA_RESTORER, 0x7fa0fbaa0c90}, {0x7fa0fce86160, [], SA_RESTORER|SA_RESTART, 0x7fa0fbaa0c90}, 8) = 0
rt_sigaction(SIGTSTP, {0x5b3410, [TSTP], SA_RESTORER|SA_RESTART, 0x7fa0fae70da0}, {SIG_DFL, [TSTP], SA_RESTORER|SA_RESTART, 0x7fa0fbaa0c90}, 8) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7fff053288e0) = -1 EIO (Input/output error)
write(1, "quit\n", 5)                   = -1 EIO (Input/output error)
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigaction(SIGINT, {0x5b3550, [INT], SA_RESTORER|SA_RESTART, 0x7fa0fae70da0}, {0x5b3550, [INT], SA_RESTORER|SA_RESTART, 0x7fa0fbaa0c90}, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7fa0fbaa0c90}, {0x5b3550, [INT], SA_RESTORER|SA_RESTART, 0x7fa0fae70da0}, 8) = 0
exit_group(0)                           = ?
+++ exited with 0 +++

【问题讨论】:

    标签: linux debugging ssh gdb setsid


    【解决方案1】:

    您可以使用“screen”之类的东西,如果您从它分离(CTRL-a d)它将继续运行,然后您可以稍后使用“screen -r”重新连接。

    或者您可以使用程序名称和 PID 重新附加 gdb,例如'gdb my_app 1234',其中数字 1234 必须替换为正确的 PID。

    【讨论】:

    • Screen 是一个很好的建议(或 tmux),但如果程序已经使用 SIGSEGV 终止,则使用 gdb 重新连接将不起作用。
    【解决方案2】:

    开启核心转储:

    ulimit -c unlimited
    

    然后执行你的程序(导致seg fault),你应该看到“Segmentation fault(core dumped)”,当进程崩溃时系统会保存一个dump,你可以在需要的时候分析它,即使你失去连接。

    然后启动gdb -c core

    【讨论】:

    • 要达到这一点,您需要使用 nohup 或类似的东西来让您的应用程序在断开连接后继续运行。如果您的应用程序写入终端,则需要将其输出重定向到文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-26
    • 2016-10-28
    • 2016-10-30
    • 1970-01-01
    • 2020-08-16
    相关资源
    最近更新 更多