Где / как Apples GCC хранит DWARF внутри исполняемого файла
Где и как Apples GCC хранит DWARF внутри исполняемого файла?
Я скомпилировал двоичный файл через gcc -gdwarf-2
(Яблоки GCC). Тем не менее, ни objdump -g
ни objdump -h
действительно показывает мне любую отладочную информацию.
Также libbfd не находит никакой отладочной информации. (Я спросил об этом в списке рассылки binutils).
Однако я могу извлечь отладочную информацию через dsymutil
(в dSYM). libbfd также может читать эту отладочную информацию.
4 ответа
На Mac OS X было решение иметь компоновщик (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 - без временных меток модового файла или чего-то подобного.
Мы также можем использовать UUID, чтобы найти dSYM для двоичных файлов. Они отображаются в отчетах о сбоях, мы включили импортер Spotlight, который вы можете использовать для их поиска, например 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
и они все там. Они представлены в виде старых записей о ударах - компоновщик уже знал, как обрабатывать удары, поэтому их было проще всего использовать - но вы увидите, как это работает без особых проблем, возможно, обратитесь к документации по ударам, если вы неопределенный.
Кажется, на самом деле это не так.
Я проследил dsymutil
и он читает все *.o
файлы. objdump -h
также перечисляет всю информацию отладки в них.
Таким образом, кажется, что эта информация не копируется в двоичный файл.
Некоторые связанные комментарии об этом также можно найти здесь.
Кажется, есть два способа размещения отладочной информации в OSX:
в
.o
объектные файлы, используемые для компиляции. В двоичном файле хранится ссылка на эти файлы (по абсолютному пути).В отдельном пакете (каталоге) под названием.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 }
...
Apple хранит информацию об отладке в отдельных файлах с именем *.dSYM. Вы можете запустить dwarfdump для этих файлов и просмотреть записи отладочной информации DWARF.