В GDB (реальный режим, подключенный к QEMU), в определенной точке c при определенных условиях c кажется, что stepo и nexti нарушают механизм точек останова - PullRequest
3 голосов
/ 22 апреля 2020

Минимальный рабочий пример источник:

use16
org 0x7c00

jmp 0x0000:@start


@start:
    cli
        mov ax,cs
        mov ds,ax
        mov es,ax
        mov ss,ax
        mov sp,0x7c00
    sti

    mov bp,sp

    call @fails

jmp @start

@fails:
    nop
retn

times 510-($-$$) db 0
dw 0xAA55

Выше собрана в двоичный файл через FASM или NASM и записана в MBR VHD (x.vhd). QEMU запускается с включенной поддержкой отладки: qemu-system-i386.exe -m 512 -boot c -net nic -net user -hda x.vhd -no-acpi -s -S -cpu 486

В Cygwin , с GDB 9.1-1 , затем выдаются следующие команды для запуска GDB и присоединения к QEMU, определите архитектуру, пропустите код B IOS и установите точку останова в начале MBR, загруженную в 0x7c00, перед продолжением:

gdb
target remote localhost:1234
set architecture i8086
stepi 11
break *0x7c00
continue
nexti 10

В этот момент $ ip находится в nop строка.

@fails:
    nop  ;  <---
retn

Здесь возникает проблема. Используя stepi, временная точка останова помещается в строку retn, выполнение продолжается до nop и прерывается там, где и должно. Использование stepo или nexti, однако выполнение продолжается без проблем, но точка останова не достигается . ГБД просто вступает в бесконечное ожидание. Если точка останова вставляется вручную после nop (например, retn или jmp @start, инструкция, к которой вызов возвращается с retn), GDB прерывается на этом без проблем. Перечисление всех точек останова на этом этапе не приводит к появлению новых, поэтому, похоже, nexti нигде не установил временную точку останова (или временные точки останова не указаны?).

После большого исследования, вот странные "исправления" для проблемы , позволяющие nexti автоматически просто пропустить nop и прорваться туда как следует: (1) set $ebp = 0x7bfa, а затем nexti или (2) закомментируйте строку mov bp,sp.

Вопросы:

  1. Почему nexti, кажется, нарушает механизм останова в этом конкретном месте? Возможно, точка останова ставится между инструкциями? Или у nexti есть проблемы с 16-битным кодом?
  2. Почему работают странные "исправления", описанные выше? Как $ ebp вообще может быть связан с чем-либо, если он не используется ни в какой точке после инициализации? GDB использует это внутренне?

1 Ответ

2 голосов
/ 25 апреля 2020

Следующая команда gdb включает удаленную отладку протокола и приводит к отображению обмена между gdb и QEMU gdbserver: set debug remote 1. Ответы QEMU в обмене выглядят разумно, однако GDB в конечном итоге устанавливает точку останова по адресу 0x5ea7c17, что неверно. Похоже, он интерпретирует 4 байта в sp как адрес возврата, а не только 2. 0x7c17 - это фактический адрес возврата, 0xea и 0x5 - первые два байта кода загрузочного сектора.

...