GDB + основной дамп файла - PullRequest
       10

GDB + основной дамп файла

2 голосов
/ 01 марта 2011

Может кто-нибудь, пожалуйста, помогите мне понять это: -

Ниже приведена выдержка из GDB. После сбоя моей программы я открыл двоичный файл и файл ядра в gdb и выдал команду info frame:

(gdb) info frame
Stack level 0, frame at 0xb75f7390:
 eip = 0x804877f in base::func() (testing.cpp:16); saved eip 0x804869a
 called by frame at 0xb75f73b0
 source language c++.
 Arglist at 0xb75f7388, args: this=0x0
 Locals at 0xb75f7388, Previous frame's sp is 0xb75f7390
 Saved registers:
  ebp at 0xb75f7388, eip at 0xb75f738c

Что означают строки «ebp», «eip», «Locals at» и «sp предыдущего кадра»? Пожалуйста, объясните

Ответы [ 2 ]

5 голосов
/ 26 мая 2013

Эта диаграмма из статьи Википедии Стек вызовов может помочь: Stack frame layout

GDB info frame соответствует функциям, вызываемым в вашей программе во время выполнения.Из выходных данных мы можем сделать вывод о макете кадра стека:

  • 0xb75f7388 : начиная с 4 байтов здесь сохраняется старое значение EBP , 0xb75f73a8 .Первое значение, выдаваемое прологом функции base::func()
  • 0xb75f738c : 4 байта, начиная с этого здесь, сохраняют адрес возврата, 0x804869a .Нажимается инструкцией call в предыдущем кадре
  • 0xb75f7390 : начиная с 4-х байтов здесь неявный аргумент this сохраняется в base::func(), 0x00000000 .

Я объясню вывод info frame построчно:

Stack level 0, frame at 0xb75f7390:

Уровень стека 0 означает, что это самый новый кадр 1040 *.Адрес после frame at называется каноническим адресом кадра (CFA).На x86 это определяется как значение указателя стека ( ESP ) в предыдущем кадре перед выполнением инструкции call .

 eip = 0x804877f in base::func() (testing.cpp:16); saved eip 0x804869a

EIP - указатель инструкции x86.saved eip - обратный адрес.Если вы попытаетесь найти функцию, которая содержит 0x804869a с info symbol 0x804869a, она должна указывать внутри функции, вызывая base::func().

 called by frame at 0xb75f73b0

called by показывает адрес канонического кадрапредыдущего кадра.Мы можем видеть, что указатель стека продвинулся на 32 байта (0xb75f73b0 - 0xb75f7390 = 32) между двумя кадрами.

 source language c++.

 Arglist at 0xb75f7388, args: this=0x0
 Locals at 0xb75f7388, Previous frame's sp is 0xb75f7390

ABI x86 передает аргументы в стек.base::func() имеет только один неявный аргумент this.Тот факт, что это 0x0 то есть NULL сулит зло.С другой стороны, Arglist и Locals, кажется, всегда имеют одинаковое значение в info frame на x86 и x86-64.

 Saved registers:
  ebp at 0xb75f7388, eip at 0xb75f738c

Saved registers отражает регистры, которые были сохранены в функциизапись.Он перечисляет, где старые значения регистра сохраняются в стеке.Сохраненный EIP является обратным адресом, поэтому если вы изучите адрес, сохраненный в 0xb75f738c с x/a 0xb75f738c, он должен дать 0x804869a .Тот факт, что EBP указан здесь, подразумевает, что ваш код, вероятно, не был скомпилирован с -fomit-frame-pointer и имеет стандартный пролог функции:

push %ebp
movl %esp, %ebp

в самом начале base::func(), чтоустанавливает EBP в качестве указателя кадра.

0 голосов
/ 28 апреля 2011

Чтобы проанализировать файл ядра, выполните:

$ исполняемое ядро ​​gdb

gdb $ bt - backtrace

или gdb $ fr 0 - самый верхний кадр встек времени выполнения gdb $ fr 1 и т. д. даст вам порядок вызовов функций, которые привели к ошибке сегмента.

Здесь информационный фрейм gdb $ предоставляет вам информацию о фрейме 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...