gcc LTO, кажется, удаляет символы отладки

У меня есть проект, работающий на процессоре ARM Cortex-M4, где я пытаюсь включить функцию оптимизации времени компоновки gcc (LTO).

В настоящее время мои флаги компиляции и связывания:

CFLAGS = -ggdb -ffunction-sections -Og
LDFLAGS = -Wl,-gc-sections

С этими флагами все работает нормально, и я могу правильно отлаживать проект.

Затем я попытался добавить -flto в CFLAGS. Хотя программа работает нормально, я больше не могу отлаживать проект, поскольку gdb жалуется на отсутствие символов отладки. Запуск objdump -g в файле ELF (с включенным LTO) дает следующий результат:

xxx.elf:     file format elf32-littlearm

Contents of the .debug_frame section:

00000000 0000000c ffffffff CIE
  Version:               1
  Augmentation:          ""
  Code alignment factor: 2
  Data alignment factor: -4
  Return address column: 14

  DW_CFA_def_cfa: r13 ofs 0

00000010 00000018 00000000 FDE cie=00000000 pc=08002a3c..08002a88
  DW_CFA_advance_loc: 2 to 08002a3e
  DW_CFA_def_cfa_offset: 16
  DW_CFA_offset: r4 at cfa-16
  DW_CFA_offset: r5 at cfa-12
  DW_CFA_offset: r6 at cfa-8
  DW_CFA_offset: r14 at cfa-4
  DW_CFA_nop

0000002c 0000000c ffffffff CIE
  Version:               1
  Augmentation:          ""
  Code alignment factor: 2
  Data alignment factor: -4
  Return address column: 14

  DW_CFA_def_cfa: r13 ofs 0

0000003c 0000000c 0000002c FDE cie=0000002c pc=08002a88..08002a98

Обратите внимание на отсутствующий раздел .debug_info. Возврат к настройкам проекта и удаление только -flto из CFLAGS решает проблему. objdump -g в файле ELF без LTO теперь показывает раздел .debug_info, заполненный правильными ссылками на функции в моем проекте, и отладка снова работает нормально.

Как заставить символы LTO и отладки хорошо работать вместе?

Изменить: забыл включить информацию о gcc. Я использую GNU ARM Embedded Toolchain, и тест проводился на версиях 5.4-2016q2 и 5.4-2016кв3.


person swineone    schedule 22.11.2016    source источник
comment
Здесь есть некоторая информация, которая может вас заинтересовать: gcc.gnu.org/wiki/early -отладка   -  person Pyves    schedule 04.12.2016
comment
Вы когда-нибудь догадывались об этом?   -  person Trygve Laugstøl    schedule 09.03.2017
comment
Еще нет. Однако я не тестировал более новую версию gcc.   -  person swineone    schedule 09.03.2017
comment
Обновление @TrygveLaugstøl: я только что проверил это на последней версии GNU ARM Embedded Toolchain (обновление 6-2017-q1), и, по крайней мере, согласно objdump, символы отладки вернулись. К сожалению, поскольку сейчас выходные, у меня нет доступа к моему оборудованию, чтобы протестировать его. Я отчитаюсь, когда сделаю.   -  person swineone    schedule 30.04.2017
comment
@swineone хорошо, спасибо, что сообщили мне!   -  person Trygve Laugstøl    schedule 30.04.2017
comment
GCC 8.2.0 больше не утверждает, что -flto и -g несовместимы, а Gold сохраняет разделы DWARF с --gc-sections. Однако традиционный компоновщик BFD этого не делает, но для предотвращения удаления можно использовать сценарий компоновщика.   -  person alecov    schedule 07.01.2019


Ответы (3)


Ситуация должна была улучшиться к настоящему времени. GCC 8, наконец, получил ранние улучшения отладочной информации: http://hubicka.blogspot.com/2018/06/gcc-8-link-time-and-interprocedural.html

Хотя было возможно выполнить сборку с помощью LTO и -g и отладить полученный двоичный файл, отладочная информация была несколько испорчена C, а не отладочная информация, соответствующая языку, на котором изначально была написана программа. Это, наконец, решено. [...] Основная идея состоит в том, чтобы создать DWARF на ранней стадии компиляции, сохранить его в объектных файлах, а во время компоновки просто скопировать необходимые фрагменты в окончательные объектные файлы без необходимости компилятору анализировать и обновлять его.

Но обратите внимание, что -gsplit-dwarf не будет работать с LTO.

person Trass3r    schedule 04.02.2019
comment
Я решил принять ответ, несмотря на то, что на самом деле не пробовал его с более новой версией gcc. Если кто-то пытается и все еще имеет проблемы, пожалуйста, оставьте комментарий ниже. - person swineone; 24.03.2020

Это потому, что gcc не поддерживает объединение -flto с -g.

Подробную информацию можно найти в онлайн-документах GCC — параметры оптимизации.

«Объединение -flto с -g в настоящее время является экспериментальным и, как ожидается, даст неожиданные результаты».

Когда вы используете -flto, -g будет игнорироваться.

person alpha    schedule 28.07.2017
comment
В настоящее время 7.3.0 читает Оптимизация времени компоновки плохо работает с генерацией отладочной информации. Комбинация -flto с -g в настоящее время является экспериментальной и, как ожидается, приведет к неожиданным результатам. - person Gareth A. Lloyd; 18.04.2018

Можно попробовать использовать attribute((used)) или, в качестве альтернативы, можно попробовать использовать отладочные символы так, чтобы их значения не менялись.

person user1787252    schedule 19.08.2018