Вопрос или проблема
Я повторял то, что описано здесь о отладке многопроцессных приложений в GDB
. Странно, но GDB
не срабатывает на exec
catchpoint в дочернем процессе, выполняющем команду cat
(последняя порождена из bash
).
ubuntu@ubuntu:~$ echo $$
670639
ubuntu@ubuntu:~$ cat /etc/issue
root@ubuntu:~# gdb -q -p 670639
Подключение к процессу 670639
Чтение символов из /usr/bin/bash...
(Отладочные символы не найдены в /usr/bin/bash)
Чтение символов из /lib/x86_64-linux-gnu/libtinfo.so.6...
(Отладочные символы не найдены в /lib/x86_64-linux-gnu/libtinfo.so.6)
Чтение символов из /lib/x86_64-linux-gnu/libc.so.6...
Чтение символов из /usr/lib/debug/.build-id/49/0fef8403240c91833978d494d39e537409b92e.debug...
Чтение символов из /lib64/ld-linux-x86-64.so.2...
Чтение символов из /usr/lib/debug/.build-id/41/86944c50f8a32b47d74931e3f512b811813b64.debug...
[Отладка потоков с использованием libthread_db включена]
Используется библиотека хоста libthread_db "/lib/x86_64-linux-gnu/libthread_db.so.1".
pselect64_syscall (sigmask=0x564025a0c820 <_rl_orig_sigset>, timeout=<оптимизировано>, exceptfds=0x0, writefds=0x0, readfds=0x7ffe468736e0, nfds=1) в ../sysdeps/unix/sysv/linux/pselect.c:34
34 ../sysdeps/unix/sysv/linux/pselect.c: Нет такого файла или директории.
(gdb) catch fork
Точка останова 1 (fork)
(gdb) catch exec
Точка останова 2 (exec)
(gdb) c
Продолжение.
Точка останова 1 (порождённый процесс 719946), arch_fork (ctid=0x7fbccdc6fa10) в ../sysdeps/unix/sysv/linux/arch-fork.h:52
52 ../sysdeps/unix/sysv/linux/arch-fork.h: Нет такого файла или директории.
(gdb) info inferiors
Num Описание Соединение Исполняемый файл
* 1 процесс 670639 1 (родной) /usr/bin/bash
(gdb) set detach-on-fork off
(gdb) nexti
[Новый процесс 2 (приложение 719946)]
[Отладка потоков с использованием libthread_db включена]
Используется библиотека хоста libthread_db "/lib/x86_64-linux-gnu/libthread_db.so.1".
52 в ../sysdeps/unix/sysv/linux/arch-fork.h
(gdb) c
Продолжение.
В чем причина этого? Спасибо.
Ответ или решение
Проблема, которую вы описали, связана с тем, что отладчик GDB не срабатывает на "catchpoint" при выполнении команды exec
в дочернем процессе, который был создан с помощью fork
в процессе отладки. Давайте разберем несколько ключевых моментов, которые могут помочь вам понять и решить эту проблему.
1. Основы работы GDB с процессами
Когда вы запускаете GDB и прикасаетесь к существующему процессу, например, через gdb -p
, вы работаете с этим процессом как с "отладчиком" относительно его текущего состояния. GDB позволяет отслеживать события, такие как fork
и exec
, которые происходят в процессе.
2. Настройки catchpoint
Вы правильно установили catch fork
и catch exec
. Эти команды позволяют GDB отслеживать события fork и exec. Однако, важно помнить о том, как GDB управляет новыми процессами, которые он создает через такие системные вызовы.
3. Detach on fork
Когда вы используете команду set detach-on-fork off
, вы указываете GDB оставаться подключенным к родительскому процессу при создании нового дочернего процесса. Это именно то, что вам нужно, так как вы хотите отладить и следить за дочерним процессом.
4. Важные моменты при отладке exec
Находясь в контексте GDB, важно понимать, что exec
в дочернем процессе может быть вызван по-разному в зависимости от архитектуры и используемого компилятора. Если GDB не захватывает exec
в дочернем процессе, возможно, это вызвано следующими причинами:
-
Дочерний процесс не находится под контролем GDB: После вызова
fork
, GDB начинает отслеживать новый процесс, но вам нужно явно указать GDB, чтобы он начал отслеживаниеexec
в этом процессе. -
Отсутствие разрешений: Убедитесь, что у вас есть все необходимые разрешения для отслеживания дочерних процессов. Иногда отсутствие отладочных символов может также привести к проблемам.
5. Решения и рекомендации:
-
Проверьте наличие прав доступа: Убедитесь, что GDB имеет необходимые права доступа для отладки дочернего процесса.
-
Используйте
info inferiors
: Вы уже использовали командуinfo inferiors
, чтобы получить информацию о дочерних процессах. Это хорошая практика, чтобы убедиться, что дочерний процесс на самом деле "управляется" GDB. -
Пробуйте перезапустить GDB: Иногда, перезапуск GDB может решить проблемы с отслеживанием. После запуска, выполните команды снова.
-
Убедитесь, что символы отладки загружены: Попробуйте скомпилировать bash и все необходимые библиотеки с отладочными символами, если вы используете их.
-
Изучите другие системы отладки: Если проблема продолжает возникать, можете рассмотреть использование других отладчиков, таких как LLDB, которые могут дать другую перспективу.
В итоге, если GDB не реагирует на exec catchpoint
в дочернем процессе, обязательно убедитесь, что GDB отслеживает этот процесс правильно и что ошибки не возникают из-за недостатка разрешений или отсутствия символов отладки. Удачи в отладке!