Где / как 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:

  1. в .o объектные файлы, используемые для компиляции. В двоичном файле хранится ссылка на эти файлы (по абсолютному пути).

  2. В отдельном пакете (каталоге) под названием.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.

Другие вопросы по тегам