Как gdb интерпретирует `main`, когда не загружены символы отладки?

#c #gdb

#c #gdb

Вопрос:

 <http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/ctest/printf...(no debugging symbols found)...done.
(gdb) disas main
Dump of assembler code for function main:
0x0000000000400498 <main 0>:    push   %rbp
0x0000000000400499 <main 1>:    mov    %rsp,%rbp
0x000000000040049c <main 4>:    sub    $0x10,%rsp
  

Как gdb интерпретирует main , когда не загружены символы отладки?

Ответ №1:

GDB не «интерпретирует» main .

Если ваш вопрос «как GDB узнает, где находится main», ответ будет: «потому что его адрес находится в таблице символов» (см. Вывод из nm /root/ctest/printf ). В UNIX (в отличие от Windows) символы отладки не нужны для того, чтобы иметь имена функций и глобальных переменных в исполняемом файле (или общей библиотеке) — они сохраняются по умолчанию (для упрощения отладки). Если вы хотите скрыть свои main , вы могли бы запустить strip printf , чтобы удалить его (и все другие символы) из исполняемого файла.

Что касается вашего второго вопроса, main он не искажен, потому что у него есть extern "C" связь. У него должна быть такая связь, чтобы его можно было вызвать из сборки (обычно она вызывается при запуске среды выполнения C crt1.o ).

Комментарии:

1. У меня два вопроса: 1. почему все еще существует main символ, когда символы отладки не загружены? 2. почему имя main не искажено?

Ответ №2:

main это не символ отладки, поэтому он не удаляется. Он имеет внешнюю привязку, поэтому он сохраняется, если явная команда strip или link не удалит его. Это не искажено, потому что на большинстве платформ в C ABI нет искажения имени (за исключением, возможно, добавления символа подчеркивания или подобного).

Компоновщик и другие инструменты способны определять, какие символы являются символами отладки, а какие внешними или частными и т.д., Потому что они помечены по-разному в таблице символов. Например, в Mac OS X мы могли бы увидеть что-то вроде этого:

                  U _constantFromAnotherModule
0000000000000018 T _externFunction
0000000000000410 s _privateInt
0000000000000000 t _staticFunction
  

Разные буквы в среднем столбце перед названиями символов указывают на разные типы компоновки, и инструменты по-разному обрабатывают их.

Даже если символы искажены, инструменты часто знают, как отменить искажение, поэтому отладчик должен быть в состоянии найти имя функции в таблице символов, даже если оно было искажено, при условии, что оно было создано средствами, совместимыми с отладчиком. Помимо этого, main( ) в C есть привязка к C и следует C ABI платформы, поэтому обычно он не искажается.

Комментарии:

1. У меня два соответствующих вопроса: 1. Как ссылка определяет, является ли символ символом отладки или нет? 2.So для c ABI disas main не будет работать?

2. В чем разница между символами отладки и другими символами? Разве не все символы предназначены для отладки? Скажем, это все еще работает, если вы strip используете его символы.

3. @kernel: Нет, все символы не предназначены для отладки. Символы (или какая-либо другая форма ведения бухгалтерского учета) необходимы для функционирования компоновщика. Ни один из символов в моем примере не является символами отладки.

4. но конечному исполняемому файлу не нужен компоновщик для работы, верно?