Понимание формата GDB - PullRequest
0 голосов
/ 11 октября 2019

Я пытаюсь ознакомиться с gdb, и у меня возникло несколько вопросов, основанных на его формате и показаниях:

─── Assembly ────
 0x00000000004004ed  main+0  push   %rbp
 0x00000000004004ee  main+1  mov    %rsp,%rbp
!0x00000000004004f1  main+4  movl   $0x539,-0x4(%rbp)
  • Что означает адрес памяти в левом столбце,и почему каждая инструкция имеет переменную ширину "между" следующим адресом?
  • Что означает второй столбец?

.

─── Registers ───────────────────────
rax 0x00000000004004ed         
rbx 0x0000000000000000      
rcx 0x0000000000000000
  • Является ли значение рядом с регистром местом его памяти или значением, содержащимся в реестре?

.

─── Stack ───────────────────
[0] from 0x000000000040058c in main+47 at main.c:7
  • Что говорит нам эта строка:стек начинается с адреса памяти 0x000000000040058c, и что означает main+47?

Ответы [ 2 ]

1 голос
/ 11 октября 2019

@ daShier ответ в основном правильный, но совершенно неверный в этой части:

Что говорит нам эта строка: начинается ли стек с адреса памяти 0x000000000040058c и что делает основной + 47обратитесь к?

Я думаю, что это значение qword в стеке (на которое указывает RSP). Вероятно, это адрес возврата main или, может быть, просто значение, которое было в RBP, когда main выдвинул его.

(Но адрес возврата вероятен: main, начинающийся с 0x4004ed, находится недалеко от 0x40058c).

main + 47 = 0x40051c - это кодовый адрес внутри main, соответствующий источнику C в строке 7 из main.c. (main.c:7). symbol+number - это способ GDB печатать адреса понятным для человека способом относительно ближайшего символа над ними. т.е. в какой функции они находятся; Я думаю, что это точка останова, на которой вы остановились на , когда вы копировали / вставляли это. Он говорит вам, где сейчас казнь. Или когда был сделан этот снимок данных в стеке.

Я не уверен, как вы получили GDB для печати этого дампа стека. Это немного другой формат от info stack или backtrace. Режим TUI layout reg или любой другой макет не включает в себя панель стека.


Но в любом случае 0x000000000040058c, скорее всего, не является стеком address ;он находится на той же странице виртуальной памяти размером 4 КБ, что и main, поэтому он находится в разделе .text. (На самом деле это всего 0x70 байт за main + 47). Эта виртуальная страница будет исполняемой и недоступной для записи.

Значения RSP (указатель стека) - это такие вещи, как 0x7ffff7fd4100, в верхней части нижних 48 бит виртуального адресного пространства. (Верхняя часть части пользовательского пространства используемой (канонической) части виртуального адресного пространства в x86-64).


Как я уже сказал, main+47 - это просто кодовый адрес внутри main. Он не имеет ничего общего с 47 или 48 байтами стекового пространства.

1 голос
/ 11 октября 2019

Что означает адрес памяти в левом столбце и почему каждая инструкция имеет переменную ширину "между" следующим адресом?

Инструкции машинного кода x86 имеют переменную длину,Таким образом, некоторые инструкции занимают один байт, в то время как, например, movabs $0x12345678abcdef, %rax занимает 10. Жесткий предел составляет 15 байтов, но только преднамеренное заполнение с избыточными префиксами может доходить до 15.

Многие другие архитектуры являются RISC иимеют инструкции фиксированной ширины.

Что означает второй столбец?

Он сообщает вам относительный адрес из символа main. Обратите внимание, что фактическое местоположение в памяти не назначается во время компиляции.

(Примечание редактора: это не исполняемый файл PIE, поэтому абсолютный адрес установлен во время соединения. Мы можем сказать,потому что адрес - 0x00400... в младших 32 битах адресного пространства, а не 0x55555555....)

Является ли значение рядом с регистром местом его памяти или значением, содержащимся в реестре?

Регистры не хранятся в памяти (кроме редких архитектур);регистры не имеют адресов и являются отдельным пространством от памяти. Также не отображается значение , на которое указывает регистр, который содержит действительный адрес.

Показанное значение является значением в самом резисторе. Обратите внимание, что rbx и rcx оба показывают 0x0.

О чем говорит эта строка: начинается ли стек с адреса памяти 0x000000000040058c, и на что ссылаются main + 47?

(примечание редактора: эта часть неверна, но я не совсем уверен, что именно заменить ее чем-то другим. Но 0x40058c определенно не является приемлемым значением для RSP. main+47кодовый адрес где-то внутри main, как всегда для GDB symbol+number).

Это расположение стека. Ваш код маленький, поэтому main занимает всего 48 адресов. Обратите внимание, что память обычно выделяется в блоках, поэтому стек не будет отображаться в main+7 или в том, что сразу следует инструкции movl.

...