Ответ 1
Кажется, есть команда перехода, которая именно то, что вы ищете:
http://idlebox.net/2010/apidocs/gdb-7.0.zip/gdb_18.html#SEC163
Я новичок в GDB (и отладке вообще). Можно ли перейти к некоторому местоположению/адресу в коде/исполняемом файле во время отладки в GDB?
Скажем, у меня есть что-то похожее на следующие
int main()
{
caller_f1() {
f1(); // breakpoint
f2() } // want to skip f2() and jump
caller_f2() { // jump to this this location ??
f1();
f2(); }
}
Спасибо!
Кажется, есть команда перехода, которая именно то, что вы ищете:
http://idlebox.net/2010/apidocs/gdb-7.0.zip/gdb_18.html#SEC163
Чтобы возобновить исполнение по новому адресу, используйте jump
(короткая форма: j
):
jump LINENUM
jump *ADDRESS
Руководство GDB предлагает использовать tbreak
(временную точку останова) перед прыжком.
Белье может быть любым выражением linespec
, например +1
для следующей строки.
См. @gospes answer по соответствующему вопросу для удобного макроса skip
, который делает именно это.
Использование jump
только "безопасно" в неуправляемом коде (-O0
), и даже тогда только внутри текущей функции. Он только изменяет счетчик программ; он не меняет никаких других регистров или памяти.
Только gcc -O0
компилирует каждый оператор источника (или строку?) в отдельный блок инструкций, который загружает значения переменных из памяти и сохраняет результаты. Это позволяет изменять значения переменных с помощью отладчика в любой точке останова и делает jump
между строками в машинных кодах работать как прыжок между строками в источнике C.
Это часть того, почему -O0
делает такой медленный код: компилятор не только не тратит время на оптимизацию, он должен делать медленный код, который разливает/перезагружает все после каждого утверждения для поддержки асинхронной модификации переменных и даже программ -counter. (Задержка хранения/перезагрузки составляет около 5 циклов на типичном x86, поэтому 1 цикл add
занимает 6 циклов в строках -O0
).
Руководство gcc предлагает использовать -Og
для обычного цикла редактирования-компиляции-отладки, но даже этот уровень освещенности будет разорван jump
и асинхронная модификация переменных. Если вы не хотите делать это во время отладки, это хороший выбор, особенно для проектов, где -O0
работает так медленно, что это проблема.
Чтобы установить программный счетчик/указатель инструкции на новый адрес без возобновления, вы также можете использовать это:
set $pc = 0x4005a5
Копировать/вставить адреса из окна разборки (layout asm
/layout reg
).
Это эквивалентно tbreak
+ jump
, но вы не можете использовать номера строк, только адреса инструкций. (И вы не получите предупреждение + запрос подтверждения для перехода за пределы текущей функции).
Тогда вы можете stepi
оттуда. $pc
- это общее имя gdb для любого регистра, который действительно вызывается в целевой архитектуре. например RIP в x86-64. (См. Также нижнюю часть x86 wiki для советов по отладке asm для gdb.)