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, что маловероятно).