Можно ли "прыгать"/"пропускать" в отладчике GDB?

Можно ли перейти к некоторому местоположению / адресу в коде / исполняемом файле во время отладки в GDB?

Допустим, у меня есть что-то похожее на следующее

int main()
{
  caller_f1() {  

   f1();  // breakpoint  
   f2() } // want to skip f2() and jump 

  caller_f2() { // jump to this this location ??       
   f1();  
   f2(); }  
}

2 ответа

Решение

Кажется, есть команда перехода, которая именно то, что вы ищете:

http://idlebox.net/2010/apidocs/gdb-7.0.zip/gdb_18.html

Обновленная ссылка: http://web.archive.org/web/20140101193811/http://idlebox.net/2010/apidocs/gdb-7.0.zip/gdb_18.html

Чтобы возобновить выполнение по новому адресу, используйте jump (Краткая форма: j):

jump LINENUM
jump *ADDRESS

Руководство GDB предлагает использовать tbreak (временная точка останова) перед прыжком.

Белье может быть любым linespec выражение, как +1 для следующей строки.

Смотрите ответ @gospes на соответствующий вопрос для удобной skip макрос, который делает именно это.


С помощью jump только "безопасно" в неоптимизированном коде ( -O0 ) и даже тогда только в рамках текущей функции. Это только изменяет счетчик программы; это не меняет никаких других регистров или памяти.

Только gcc -O0 компилирует каждый исходный оператор (или строку?) в независимый блок инструкций, который загружает значения переменных из памяти и сохраняет результаты. Это позволяет вам изменять значения переменных с помощью отладчика в любой точке останова и делает jump Работа между строками в машинном коде работает как переход между строками в C-коде.

Это часть того, почему -O0 делает такой медленный код: компилятор не только не тратит время на оптимизацию, он также требует создания медленного кода, который проливает / перезагружает все после каждого оператора для поддержки асинхронного изменения переменных и даже счетчика программы. (Задержка сохранения / перезагрузки составляет около 5 циклов на обычном x86, поэтому 1 цикл add занимает 6 циклов в -O0 строит).

Руководство GCC предлагает использовать -Og для обычного цикла edit-compile-debug, но даже этот легкий уровень оптимизации сломается jump и асинхронная модификация переменных. Если вы не хотите делать это во время отладки, это хороший выбор, особенно для проектов, где -O0 работает так медленно, что это проблема.


Чтобы установить счетчик программы / указатель инструкции на новый адрес без возобновления, вы также можете использовать это:

set $pc = 0x4005a5

Скопируйте / вставьте адреса из окна разборки (layout asm / layout reg).

Это эквивалентно tbreak + jump, но вы не можете использовать номера строк, только адреса команд. (И вы не получите предупреждение + запрос подтверждения для перехода за пределы текущей функции).

Тогда ты можешь stepi оттуда. $pc является общим именем GDB для того, что регистр действительно вызывается в целевой архитектуре. например, RIP в x86-64. (См. Также нижнюю часть вики-тега x86 для советов по отладке asm для gdb.)

Другие вопросы по тегам