Я - целевой исполняемый файл внешнего gdb, и у меня даже нет стека, который соответствует той цели. Я хочу к одноэтапному так или иначе, так, чтобы я мог проверить то, что продолжается в моем ассемблерном коде, потому что я не эксперт при x86 блоке. К сожалению, gdb отказывается делать эту простую отладку на уровне ассемблера. Это позволяет мне устанавливать и останавливаться на соответствующей точке останова, но как только я пробую к одноэтапному вперед, gdb сообщает, что ошибка "Не может найти границы текущей функции", и EIP не изменяется.
Дополнительные детали:
Машинный код был сгенерирован gcc asm операторы, и я скопировал его в местоположение памяти ядра, где он выполняется от вывода objdump-d. Я не возражал бы против простого способа использовать загрузчик, чтобы загрузить мой объектный код в перемещенный адрес, но принять во внимание, что загрузка должна быть сделана в модуле ядра.
Я предполагаю, что другая альтернатива должна была бы произвести поддельный модуль ядра или файл информации об отладке, чтобы дать gdb, заставить его полагать, что эта область в рамках кода программы. gdb хорошо работает на самом исполняемом файле ядра.
(Для тех, кто действительно хочет знать, я ввожу код во времени выполнения в пространство данных ядра Linux в VM VMware и отлаживаю его от gdb удаленной отладки ядра через встроенный gdb тупик VMware Workstation. Обратите внимание, что я не пишу использование ядра; я - аспирант безопасности, пишущий прототип.)
(Я могу установить точку останова на каждой инструкции в моем блоке. Это работает, но стало бы довольно трудоемким через некоторое время, так как размер x86 инструкций по сборке варьируется, и местоположение блока изменится каждый раз, когда я перезагружаю.)
Вы можете использовать stepi
или nexti
(что может быть сокращено до si
или ni
) для пошагового выполнения машинного кода.
Самое полезное, что вы можете сделать здесь, это display / i $ pc
, прежде чем использовать stepi
как уже предложил в ответе R Samuel Klatchko. Это указывает GDB дизассемблировать текущую инструкцию каждый раз перед печатью приглашения; тогда вы можете просто нажимать Enter, чтобы повторить команду stepi
.
(Подробнее см. мой ответ на другой вопрос - контекст этого вопроса был другим, но принцип тот же.)
Вместо gdb
запустите gdbtui
. Или запустите gdb
с ключом -tui
. Или нажмите C-x C-a после ввода gdb
. Теперь вы находитесь в режиме TUI GDB.
Введите layout asm
, чтобы в верхнем окне отобразилась сборка - она будет автоматически следовать за указателем команд, хотя вы также можете менять кадры или прокручивать их во время отладки. Нажмите C-x s, чтобы войти в режим SingleKey, где run continue up down finish
и т.д. сокращаются до одной клавиши, позволяя вам очень быстро пройтись по вашей программе.
+---------------------------------------------------------------------------+ B+>|0x402670 <main> push %r15 | |0x402672 <main+2> mov %edi,%r15d | |0x402675 <main+5> push %r14 | |0x402677 <main+7> push %r13 | |0x402679 <main+9> mov %rsi,%r13 | |0x40267c <main+12> push %r12 | |0x40267e <main+14> push %rbp | |0x40267f <main+15> push %rbx | |0x402680 <main+16> sub $0x438,%rsp | |0x402687 <main+23> mov (%rsi),%rdi | |0x40268a <main+26> movq $0x402a10,0x400(%rsp) | |0x402696 <main+38> movq $0x0,0x408(%rsp) | |0x4026a2 <main+50> movq $0x402510,0x410(%rsp) | +---------------------------------------------------------------------------+ child process 21518 In: main Line: ?? PC: 0x402670 (gdb) file /opt/j64-602/bin/jconsole Reading symbols from /opt/j64-602/bin/jconsole...done. (no debugging symbols found)...done. (gdb) layout asm (gdb) start (gdb)