Вопрос по gcc, macos – где / как Apples GCC хранит DWARF внутри исполняемого файла

9

Где и как Apples GCC хранит DWARF внутри исполняемого файла?

Я скомпилировал двоичный файл черезgcc -gdwarf-2 (Яблоки GCC). Тем не менее, ниobjdump -g ниobjdump -h действительно показывает мне любую отладочную информацию.

Также libbfd не находит никакой отладочной информации. (Я спросил об этом в списке рассылки binutilsВот.)

Однако я могу извлечь отладочную информацию черезdsymutil (в dSYM). libbfd также может читать эту отладочную информацию.

Ваш Ответ

4   ответа
0

. Вы можете запустить dwarfdump для этих файлов и просмотреть записи отладочной информации DWARF.

Ну, твой вопрос был расплывчатым. Я интерпретировал это, чтобы указать, где хранится отладочная информация, когда используется с исполняемым файлом в отладчике.
Нет вы можетеcreate DSYM черезdsymutil, Но мой вопрос был, где находится отладочная информация. То есть где жеdsymutil получить это от. Но у меня уже есть ответ (см. Мой собственный ответ). Они на самом деле не находятся в двоичном файле, двоичный файл ссылается на*.o файлы, и это также гдеdsymutil получает данные от. Albert
Да, это был мой вопрос. И ответ, он хранится в*.o файлы. И когда вы создаете dSYM, тогда, конечно, у вас есть еще одна копия в dSYM. Но до создания dSYM dSYM не существует. Вот что я сказал в своем вопросе. ("Однако я могу извлечь отладочную информацию черезdsymutil. & quot;) Вы автоматически не получаете dSYM. Вы должны позвонитьdsymutil, (Я думаю, что когда вы используете XCode, XCode делает это автоматически.) Или я ошибаюсь? Albert
0

In the .o object files used for compilation. The binary stores a reference to these files (by absolute path).

In a separate bundle (directory) called .dSYM

Если я скомпилирую с Apple Clang, используяg++ -g main.cpp -o foo Я получаю комплект под названиемfoo.dSYM, Однако, если я использую CMake, я получаю отладочную информацию в объектных файлах. Я думаю, потому что это делает отдельныйgcc -c main.cpp -o main.o шаг?

В любом случае я нашел эту команду очень полезной для случая 1:

$ dsymutil -dump-debug-map main
---
triple:          'x86_64-apple-darwin'
binary-path:     main
objects:         
  - filename:        /Users/tim/foo/build/CMakeFiles/main.dir/main.cpp.o
    timestamp:       1485951213
    symbols:         
      - { sym: __ZNSt3__111char_traitsIcE11eq_int_typeEii, objAddr: 0x0000000000000D50, binAddr: 0x0000000100001C90, size: 0x00000020 }
      - { sym: __ZNSt3__111char_traitsIcE6lengthEPKc, ,objAddr: 0x0000000000000660, binAddr: 0x00000001000015A0, size: 0x00000020 }
      - { sym: GCC_except_table3, objAddr: 0x0000000000000DBC, binAddr: 0x0000000100001E2C, size: 0x00000000 }
      - { sym: _main, objAddr: 0x0000000000000000, binAddr: 0x0000000100000F40, size: 0x00000090 }
      - { sym: __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m, objAddr: 0x00000000000001F0, binAddr: 0x0000000100001130, size: 0x00000470 }
      - { sym: ___clang_call_terminate, objAddr: 0x0000000000000D40, binAddr: 0x0000000100001C80, size: 0x00000010 }
      - { sym: GCC_except_table5, objAddr: 0x0000000000000E6C, binAddr: 0x0000000100001EDC, size: 0x00000000 }
      - { sym: __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_, objAddr: 0x0000000000000680, binAddr: 0x00000001000015C0, size: 0x000006C0 }
      - { sym: __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_, objAddr: 0x00000000000000E0, binAddr: 0x0000000100001020, size: 0x00000110 }
      - { sym: GCC_except_table2, objAddr: 0x0000000000000D7C, binAddr: 0x0000000100001DEC, size: 0x00000000 }
      - { sym: __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc, objAddr: 0x0000000000000090, binAddr: 0x0000000100000FD0, size: 0x00000050 }
      - { sym: __ZNSt3__111char_traitsIcE3eofEv, objAddr: 0x0000000000000D70, binAddr: 0x0000000100001CB0, size: 0x0000000B }
...
2

Я проследилdsymutil и он читает все*.o файлы.objdump -h также перечисляет всю информацию отладки в них.

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

Некоторые связанные комментарии об этом также можно найтиВот.

40

ldне обрабатывать всю отладочную информацию, когда вы связываете свою программу. Отладочная информация часто в 10 раз больше исполняемого файла программы, поэтому компоновщик обрабатывает всю отладочную информацию и включает ее в исполняемый двоичный файл, что является серьезным ущербом для времени соединения. Для итеративной разработки - компиляция, ссылка, компиляция, ссылка, отладка, ссылка компиляции - это был настоящий хит.

Вместо этого компилятор генерирует отладочную информацию DWARF в файлах .s, ассемблер выводит ее в файлах .o, а компоновщик включает в себя «карту отладки»; в исполняемом двоичном файле, который сообщает пользователям отладочной информации, где все символы были перемещены во время ссылки.

Потребитель (выполняющий отладку .o-файла) загружает карту отладки из исполняемого файла и обрабатывает все DWARF-файлы в файлах .o по мере необходимости, переназначая символы в соответствии с инструкциями карты отладки.

dsymutil может рассматриваться как компоновщик отладочной информации. Он выполняет тот же процесс - читает карту отладки, загружает DWARF из файлов .o, перемещает все адреса - и затем выводит один двоичный файл из всех DWARF по их окончательным, связанным адресам. Это комплект dSYM.

Как только у вас есть пакет dSYM, вы получаете простой старый стандартный DWARF, который может обрабатывать любой инструмент чтения карликов (который может работать с двоичными файлами Mach-O).

Есть дополнительное уточнение, которое делает всю эту работу, UUID, включенные в двоичные файлы Mach-O. Каждый раз, когда компоновщик создает двоичный файл, он испускает 128-битный UUID в команде загрузки LC_UUID (v.otool -hlv или жеdwarfdump --uuid). Это однозначно идентифицирует этот двоичный файл. когдаdsymutil создает dSYM, он включает этот UUID. Отладчики будут связывать dSYM и исполняемый файл только в том случае, если они имеют совпадающие UUID - без временных меток модового файла или чего-то подобного.

We can also use the UUIDs to locate the dSYMs for binaries. They show up in crash reports, we include a Spotlight importer that you can use to search for them, e.g. mdfind "com_apple_xcode_dsym_uuids == E21A4165-29D5-35DC-D08D-368476F85EE1" если dSYM находится в индексированном месте Spotlight. У вас даже может быть хранилище dSYM для вашей компании и программа, которая может получить правильный dSYM с заданным UUID - может быть, небольшая база данных mysql или что-то в этом роде - так что вы запускаете отладчик на случайном исполняемом файле и сразу получаете все отладчики. Информация для этого исполняемого файла. Есть несколько довольно изящных вещей, которые вы можете сделать с помощью UUID.

Но в любом случае, чтобы ответить на ваш исходный вопрос: бинарный файл без разметки имеет карту отладки, файлы .o имеют DWARF, и когдаdsymutil при запуске они объединяются для создания пакета dSYM.

Если вы хотите увидеть записи карты отладки, выполнитеnm -pa executable и они все там. Они представлены в виде старых записей списка удач - компоновщик уже знал, как обрабатывать удары, поэтому их было проще всего использовать - но вы увидите, как это работает без особых проблем, возможно, обратитесь к документации по ударам, если вы неопределенный.

Спасибо за этот подробный и полезный ответ.
@JasonMolenda Какой отличный ответ, спасибо! Помимо твоего иthis анекдотические рецензии, кажется, я не могу найти формальные, знаете ли вы их?
Благодарю. Хех, я написал ту другую анекдотическую рецензию, на которую вы тоже ссылались. :) T официально никогда не был задокументирован в какой-либо форме, потому что аудитория для него настолько мала. Все соответствующие части имеют открытый исходный код (компилятор, компоновщик, отладчик), поэтому, конечно, весь исходный код доступен. Комитет по стандартам DWARF работает над различными ускоренными предложениями таблиц и карликов в файле .o. Когда это все решает & amp; стандартизирован, я думаю, мы посмотрим, сможем ли мы перейти к использованию инструментов. Но это ничего, что будет происходить в ближайшем будущем.
Какdsymutil знаете где находятся .o файлы? Я не вижу варианта на странице руководства, чтобы сказать это. Также мне нужно скомпилировать бинарный файл-g3и если да, могу ли я удалить его после того, какdsymutil& D, это? Благодарю.
Есть "карта отладки" записи в исполняемом файле перед его извлечением с именами файлов .o.nm -pa binary | grep OSO перечислю их. Они представлены в виде старого формата отладки ударов (потому что компоновщик уже знал, как обрабатывать этот формат). После того как вы создали свой dSYM, вы можете удалить их из исполняемого файла. Вам не нужно использовать-g3 на платформе Mac,-g должно быть достаточно. Я думаю-g3 выводит информацию макроса предварительной обработки, но lldb не читает ее в Mac OS X (и я не знаю, выводит ли ее даже clang).

Похожие вопросы