GCC 4.8 вставляет версию 4 в заголовок модуля компиляции даже с -gdwarf-2

Я скомпилировал приложение с помощью GCC 4.8 и пытаюсь отладить его в более старой системе, в которой нет GDB 7.5+ (в которой предположительно добавлена ​​поддержка DWARF-4). Обновление GDB в этой системе не вариант. Я не могу отладить его, потому что GDB выводит следующее сообщение:

Dwarf Error: wrong version in compilation unit header (is 4, should be 2) [in module a.out]

Я попытался скомпилировать с помощью -gdwarf-2 -gstrict-dwarf, как предложено в других вопросах, но компилятор продолжает вставлять пару заголовков модулей компиляции с версией 4:

/tmp> readelf --debug-dump=info a.out | grep -A2 'Compilation Unit @'
readelf: Warning: CU at offset 6b contains corrupt or unsupported version number: 4.
readelf: Warning: CU at offset 1eb contains corrupt or unsupported version number: 4.
  Compilation Unit @ offset 0x0:
   Length:        0x67 (32-bit)
   Version:       2
--
  Compilation Unit @ offset 0x6b:
   Length:        0x84 (32-bit)
   Version:       4
--
  Compilation Unit @ offset 0xf3:
   Length:        0x62 (32-bit)
   Version:       2
--
  Compilation Unit @ offset 0x159:
   Length:        0x8e (32-bit)
   Version:       2
--
  Compilation Unit @ offset 0x1eb:
   Length:        0x136 (32-bit)
   Version:       4
--
  Compilation Unit @ offset 0x325:
   Length:        0x62 (32-bit)
   Version:       2

Это происходит, даже если вы компилируете минимальную программу на C следующим образом:

/home/MuchToLearn/src> cat main.c
int main(void)
{
  return 0;
}
/home/MuchToLearn/src> gcc -gdwarf-2 -gstrict-dwarf main.c

Я что-то здесь упускаю? Какой смысл иметь опцию -gdwarf-2, если она не собирается генерировать двоичные файлы, которые могут быть отлажены более старыми версиями GDB, которые поддерживают только DWARF-2?

Редактировать: Занятый русский ответ правильный. Единицы компиляции версии 4 были из /usr/lib/crt1.o а также /usr/lib/libc_nonshared.a, Чтобы решить эту проблему, я скопировал их в локальный каталог и удалил их символы отладки с помощью strip -g, Затем я связал исполняемый файл следующим образом:

ld -o main -dynamic-linker /lib/ld-linux.so.2 crt1.o /usr/lib/crti.o main.o /lib/libc.so.6 libc_nonshared.a /usr/lib/crtn.o

Полученный исполняемый файл не содержит никаких модулей компиляции версии 4, и GDB перестал жаловаться на это.

1 ответ

Решение

Это происходит, даже если вы компилируете минимальную программу на C следующим образом:

Даже эта минимальная программа будет статически связывать части libc (а именно, crt1.o, crtbegin.o, так далее.).

Вы должны убедиться, что модули компиляции, имеющие версию 4, действительно исходят из вашей программы, а не из библиотеки (просто посмотрите на их DW_AT_name а также DW_AT_comp_dir).

Мой gcc-4.8: gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 выдает версию 2, когда я спрашиваю ее:

gcc -g -c t.c
readelf -wi t.o | grep -A2 'Compilation Unit'
  Compilation Unit @ offset 0x0:
   Length:        0x4e (32-bit)
   Version:       4

gcc -gdwarf-2 -c t.c
readelf -wi t.o | grep -A2 'Compilation Unit'
  Compilation Unit @ offset 0x0:
   Length:        0x52 (32-bit)
   Version:       2

Если объекты версии 4 действительно просто crt1.o или аналогичный, обратите внимание, что вы можете безопасно запустить strip -g на этих объектах - вы не потеряете много (если вам не придется отлаживать проблемы запуска libc, что маловероятно).

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