Погружение в технику и философию gdb Крис Касперски Хакер, номер #093, стр. 093-122-5 (gdb) display/3i $pc 1: x/3i $pc 0x200008: mov $0x2a,%bl 0x20000a: jmp 0x200040 0x20000f: add %al,(%edx) (gdb) ni 0x0020000a in ?? () ... Для автоматического отображения значения регистров достаточно дать команду "display регистр", где регистр — $eax, $ebx, $ecx и т.д. Для регистра-указателя текущего положения стека существует специальное имя — $sp, которое можно использовать наравне с $esp (точно так же, как $pc <--> $eip). Автоматических отображений может быть создано сколько угодно, и любое из них всегда может быть удалено командой "undisplay n1 n2 .. nn", где nx – номер отображения, который можно узнать по команде "info display". Временно выключить отображение помогает команда "disable display n1 n2 ... nn", а "enable display" – включает обратно. [переключение режима дизассемблирования] По умолчанию gdb использует синтаксис AT&T, но может выводить инструкции и в формате Intel. Для этого достаточно дать команду "set disassembly-flavor intel", а чтобы вернуться назад: "set disassembly-flavor att". Для наглядности сравним с предыдущим листингом. (gdb) set disassembly-flavor intel (gdb) display/3i $pc 1: x/3i $pc 0x200008: mov bl,0x2a 0x20000a: jmp 0x200040 0x20000f: add BYTE PTR [edx],al (gdb) ni 0x0020000a in ?? () ... [перенаправление ввода/вывода] По умолчанию gdb связывает со стандартным вводом/выводом отлаживаемой программы текущую консоль, в результате чего сообщения программы перемешиваются с сообщениями отладчика. Чтобы навести порядок, необходимо перенаправить ввод/вывод программы на отдельную консоль, что осуществляется командой "tty консоль". Открываем новую консоль, даем *nix-команду "tty" для определения ее имени (получаем, например, "/dev/ps/6"), возвращаемся к консоли отладчика и говорим: (gdb) tty /dev/ps/6 [вывод выражения на экран] Для вывода выражений используется команда "print" (псевдоним "p"). Продемонстрируем некоторые ее возможности: # gdb в качестве простейшего калькулятора (gdb) p 2*2 $1 = 4 (gdb) p $1 + 3 $2 = 7 # вывод значения $sp (gdb) p $sp $3 = (void *) 0xbffffb40 # вывод ячейки, на которую указывает $sp в hex-формате (gdb) p/x *(unsigned int*) $sp $4 = 0x1 # вывод ячейки, на которую указывает $sp в unsigned dec-формате (gdb) p/u *(unsigned int*) $sp $5 = 1 # вывод содержимого ячейки в dec-формате (по умолчанию) (gdb) p *0xbffffB3F $6 = 256 # вывод содержимого ячейки в hex-формате (gdb) p/x *0xbffffB3F $7 = 0x100 Как видно, при каждом выводе значения "print" создает переменную, которую затем с успехом можно использовать в последующих выражениях. Также доступна функция "printf" со стандартным набором спецификаторов, она особенно удобна в командных файлах. Например, следующая запись выводит значение сразу трех регистров (обрати внимание на отсутствие круглых скобок вокруг нее!): |