Можно ли «прыгать» / «пропускать» в отладчике GDB? - PullRequest
7 голосов
/ 07 ноября 2010

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

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

int main()
{
  caller_f1() {  

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

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

Ответы [ 2 ]

7 голосов
/ 04 сентября 2017

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

jump LINENUM
jump *ADDRESS

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

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

См. @ gospes's answer по связанному вопросу для удобного 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.(См. Также нижнюю часть вики для советов по отладке asm для GDB.)

7 голосов
/ 07 ноября 2010

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

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

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

...