Дождитесь подключения gdb

Я использую gdb обычно для 1 или 2 проектов. То есть Я вызываю gdb --args prog args. gdb работает в том же tty, что и программа, которую я отлаживаю.

Однако мой последний проект модифицирует утилиту dtach. Это программа, подобная экрану, поэтому tty перенаправляются в другом месте, поэтому мне нужно использовать функциональность gdb attach.

Проблема с приложением gdb заключается в том, что вы не можете с самого начала присоединяться, так как вам нужно сначала запустить программу, чтобы подключить pid.

Есть ли способ заставить программу ждать в точке до привязки gdb?

Я не могу использовать gdbserver, поскольку я на cygwin. Также я попытался использовать pause(), но это просто зависало, когда я пытался продолжить.

Ответ 1

Вот как я решаю эту проблему. Я видел, как другие люди тоже делают этот трюк.

Выберите место, где вы хотите, чтобы ваша программа остановилась, и подождите, пока вы присоедините отладчик. Для большинства программ это будет самым началом, но если есть какая-то работа с init, вам нужно сделать это, вы можете закончить это, а затем сделать это.

Поместите в цикл, подобный этому:

#ifdef DEBUG

int i = 0;

while (i == 0)
{
    usleep(100000);  // sleep for 0.1 seconds
}

#endif // DEBUG

После того, как вы успешно подключились к процессу, вы можете использовать отладчик, чтобы изменить значение переменной i, что приведет к поломке цикла и продолжит нормальное выполнение.

Команда gdb для изменения переменной на 1: set var i = 1

Еще одна вещь, которую я делаю все время: я определяю короткую функцию с именем nop(), которая ничего не делает ( "no operation" ). Затем я вставляю вызов nop() в любом месте, которое я хочу сломать, и поставьте точку останова внутри nop().

Примечание. Если вы создаете свои отладочные сборки с помощью -O0, тогда компилятор не будет оптимизировать эту переменную. Если вам нужен этот трюк для работы с оптимизированной сборкой, я думаю, вам нужно объявить переменную как volatile.

Ответ 2

По крайней мере, с LLDB, при котором процесс отправки SIGSTOP сам по себе должен делать трюк. Затем команда Debugger continue выдает SIGCONT. Это также должно работать с GDB. Альтернативно попробуйте SIGINT вместо SIGSTOP.

Включить заголовок

#include <signal.h>
#include <csignal> // or C++ style alternative

затем

raise(SIGSTOP)

Ответ 3

На некоторых платформах могут быть команды ожидания или отладки.

Более переносимо, вы можете заставить программу ждать некоторого внешне удовлетворенного условия, такого как подключение к сокету или запись некоторых данных в fifo. Затем вы можете установить соединение или отправить фиктивные данные из третьего терминала.

Или вы могли бы поместить в программу бесконечный цикл, проверяя значение какой-либо изменчивой переменной, которую вы бы модифицировали с помощью отладчика, чтобы позволить ей продолжить.

Если я помню, вы можете использовать windows apis в программах cygwin, и некоторые веб-поиска, похоже, указывают на то, что вы обнаруживаете, отлаживается ли программа, поэтому вы можете зацикливаться до тех пор, пока она не вернется.