Дождитесь подключения 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, и некоторые веб-поиска, похоже, указывают на то, что вы обнаруживаете, отлаживается ли программа, поэтому вы можете зацикливаться до тех пор, пока она не вернется.