Отладить процесс с помощью GDB и закрыть терминал
У меня есть ошибка в моем приложении, которое работает на удаленном сервере. После нескольких часов выполнения приложение получает SIGSEGV и завершает работу.
Я хочу отладить мое удаленное приложение с помощью gdb через ssh, поэтому, когда программа получит 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 +++
2 ответа
Вы можете использовать что-то вроде 'screen', оно будет продолжать работать, если вы отсоединитесь от него (CTRL-a d), затем вы сможете снова подключиться с помощью 'screen -r'.
Или вы можете снова подключить gdb с именем программы и PID, например, "gdb my_app 1234", где число 1234 должно быть заменено на правильный PID.
Включите дамп ядра:
ulimit -c unlimited
Затем запустите вашу программу (вызывая ошибку сегмента), и вы увидите "Ошибка сегментации (сброшено ядро)". Когда в процессе сбоя система сохранит дамп, вы сможете проанализировать его, когда захотите, даже если вы потеряли соединение.
Тогда запусти gdb -c core