Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC 4.8 inserts version 4 in a compilation unit header even with -gdwarf-2

Tags:

c

gcc

elf

dwarf

I compiled an application with GCC 4.8 and I'm trying to debug it on an older system that does not have GDB 7.5+ (which supposedly added support for DWARF-4). Upgrading GDB on that system is not an option. I can't debug it because GDB outputs the following message:

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

I tried compiling with -gdwarf-2 -gstrict-dwarf as suggested in other questions but the compiler keeps inserting a couple of compilation unit headers with version 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

This happens even if you compile a minimal C program as follows:

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

Am I missing something here? What's the point of having the -gdwarf-2 option if it's not going to generate binaries that can be debugged by older GDB versions that only support DWARF-2?

Edit: Employed Russian's answer is correct. The version-4 compilation units were coming from /usr/lib/crt1.o and /usr/lib/libc_nonshared.a. To fix the issue, I copied them into a local directory and removed their debugging symbols with strip -g. Then, I linked the executable as follows:

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

The resulting executable does not contain any version-4 compilation units and GDB stopped complaining about that.

like image 892
MuchToLearn Avatar asked Aug 12 '15 21:08

MuchToLearn


1 Answers

This happens even if you compile a minimal C program as follows:

Even this minimal program will statically link parts of libc (namely, crt1.o, crtbegin.o, etc.).

You should verify that the compilation units that have version 4 are really coming from your program, and not from a library (just look at their DW_AT_name and DW_AT_comp_dir).

My gcc-4.8: gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 produces version 2 when I ask it to:

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

If the version 4 objects are really just crt1.o or similar, note that you can safely run strip -g on these objects -- you will not lose much (unless you have to debug libc startup issues, which is unlikely).

like image 167
Employed Russian Avatar answered Oct 24 '22 11:10

Employed Russian