llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.96k stars 11.94k forks source link

Missing or invalid line-related debug infos on Linux x86 #8115

Open llvmbot opened 14 years ago

llvmbot commented 14 years ago
Bugzilla Link 7743
Version trunk
OS Linux
Reporter LLVM Bugzilla Contributor
CC @davidchisnall

Extended Description

With GDB on Ubuntu 9.04 x86, it is not possible to set a breakpoint on a file line or step through a function/method for a C or ObjC program compiled with Clang (trunk r109551).

With a test source file named testffi.c:

include

int main(int argc, char **argv) { return 1; }

$ clang -g -o testffi testffi.c

$ gdb testffi GNU gdb 6.8-debian This GDB was configured as "i486-linux-gnu"... (gdb) b testffi.c:5 No line 5 in file "testffi.c".

Here is a more complex example with an ObjC program debugged with GDB 6.8:

Breakpoint 3, 0x08053426 in -[ETFCGIWebApp handleServerData:] (self=0xa25dd98, _cmd=0xb6fede88, notification=0xa04ea48) (gdb) n Single stepping until exit from function _i_ETFCGIWebApp_handleServerData, which has no line number information. -[NSNotificationCenter _postAndRelease:] (self=0xa04dd88, _cmd=0xb6feded0, notification=0xa25dd98) at NSNotificationCenter.m:1163 1163 NS_HANDLER (gdb) bt

​0 -[NSNotificationCenter _postAndRelease:] (self=0xa04dd88, _cmd=0xb6feded0,

notification=0xa25dd98) at NSNotificationCenter.m:1163

​1 0xb6e7253d in -[NSNotificationCenter postNotification:] (self=0xa04dd88,

_cmd=0xb6fee708, notification=0xa25dd98) at NSNotificationCenter.m:1190

​2 0xb6e73934 in notify (center=0xa04dd88, list=0xa2de890, mode=0xb7001498,

zone=0xb7022dc0) at NSNotificationQueue.m:625

​3 0xb6e739dd in GSPrivateNotifyASAP (mode=0xb7001498)

at NSNotificationQueue.m:649

​4 0xb6f82b20 in -[GSRunLoopCtxt pollUntil:within:] (self=0xa298be8,

_cmd=0xb7001d50, milliseconds=28958, contexts=0xa2dbdd0)
at GSRunLoopCtxt.m:641

​5 0xb6ebd91f in -[NSRunLoop acceptInputForMode:beforeDate:] (self=0xa327680,

_cmd=0xb7001d78, mode=0xb7001498, limit_date=0xa2de880) at NSRunLoop.m:1197

​6 0xb6ebdd40 in -[NSRunLoop runMode:beforeDate:] (self=0xa327680,

_cmd=0xb7001d88, mode=0xb7001498, date=0xa2da5d8) at NSRunLoop.m:1265

​7 0xb6ebdefb in -[NSRunLoop runUntilDate:] (self=0xa327680, _cmd=0xb7001d80,

date=0xa2da5d8) at NSRunLoop.m:1296

​8 0xb6ebdddf in -[NSRunLoop run] (self=0xa327680, _cmd=0x806f860)

at NSRunLoop.m:1279

​9 0x0805ae24 in main ()

(gdb) b ETFCGIWebApp.m:76 No line 76 in file "ETFCGIWebApp.m".

Here is the verbose output for the compilation of the first program:

$ clang -v -g -o testffi testffi.c

clang version 2.8 (trunk 109551) Target: i386-pc-linux-gnu Thread model: posix "/home/qmathe/reps/llvm/Release+Debug+Asserts/bin/clang" -cc1 -triple i386-pc-linux-gnu -S -disable-free -main-file-name testffi.c -mrelocation-model static -mdisable-fp-elim -mconstructor-aliases -target-cpu pentium4 -v -g -resource-dir /home/qmathe/reps/llvm/Release+Debug+Asserts/lib/clang/2.8 -ferror-limit 19 -fmessage-length 80 -fgnu-runtime -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/cc-zteC7E.s -x c testffi.c clang -cc1 version 2.8 based upon llvm 2.8svn hosted on i386-pc-linux-gnu

include "..." search starts here:

include <...> search starts here:

/usr/local/include /home/qmathe/reps/llvm/Release+Debug+Asserts/lib/clang/2.8/include /usr/lib/gcc/i486-linux-gnu/4.3.3/include /usr/lib/gcc/i486-linux-gnu/4.3.3/include-fixed /usr/include/i486-linux-gnu /usr/include End of search list. "/usr/bin/gcc" -v -g -c -m32 -o /tmp/cc-EK7Gc8.o -x assembler /tmp/cc-zteC7E.s Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.3.3-5ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.3.3 (Ubuntu 4.3.3-5ubuntu4) COLLECT_GCC_OPTIONS='-v' '-g' '-c' '-m32' '-o' '/tmp/cc-EK7Gc8.o' '-mtune=generic' as --gdwarf2 -V -Qy --32 -o /tmp/cc-EK7Gc8.o /tmp/cc-zteC7E.s GNU assembler version 2.19.1 (i486-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.19.1 COMPILER_PATH=/usr/lib/gcc/i486-linux-gnu/4.3.3/:/usr/lib/gcc/i486-linux-gnu/4.3.3/:/usr/lib/gcc/i486-linux-gnu/:/usr/lib/gcc/i486-linux-gnu/4.3.3/:/usr/lib/gcc/i486-linux-gnu/:/usr/lib/gcc/i486-linux-gnu/4.3.3/:/usr/lib/gcc/i486-linux-gnu/ LIBRARY_PATH=/usr/lib/gcc/i486-linux-gnu/4.3.3/:/usr/lib/gcc/i486-linux-gnu/4.3.3/:/usr/lib/gcc/i486-linux-gnu/4.3.3/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/i486-linux-gnu/4.3.3/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-g' '-c' '-m32' '-o' '/tmp/cc-EK7Gc8.o' '-mtune=generic' "/usr/bin/gcc" -v -g -m32 -o testffi /tmp/cc-EK7Gc8.o Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.3.3-5ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.3.3 (Ubuntu 4.3.3-5ubuntu4) COMPILER_PATH=/usr/lib/gcc/i486-linux-gnu/4.3.3/:/usr/lib/gcc/i486-linux-gnu/4.3.3/:/usr/lib/gcc/i486-linux-gnu/:/usr/lib/gcc/i486-linux-gnu/4.3.3/:/usr/lib/gcc/i486-linux-gnu/:/usr/lib/gcc/i486-linux-gnu/4.3.3/:/usr/lib/gcc/i486-linux-gnu/ LIBRARY_PATH=/usr/lib/gcc/i486-linux-gnu/4.3.3/:/usr/lib/gcc/i486-linux-gnu/4.3.3/:/usr/lib/gcc/i486-linux-gnu/4.3.3/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/i486-linux-gnu/4.3.3/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-g' '-m32' '-o' 'testffi' '-mtune=generic' /usr/lib/gcc/i486-linux-gnu/4.3.3/collect2 --eh-frame-hdr -m elf_i386 --hash-style=both -dynamic-linker /lib/ld-linux.so.2 -o testffi -z relro /usr/lib/gcc/i486-linux-gnu/4.3.3/../../../../lib/crt1.o /usr/lib/gcc/i486-linux-gnu/4.3.3/../../../../lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.3.3/crtbegin.o -L/usr/lib/gcc/i486-linux-gnu/4.3.3 -L/usr/lib/gcc/i486-linux-gnu/4.3.3 -L/usr/lib/gcc/i486-linux-gnu/4.3.3/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/i486-linux-gnu/4.3.3/../../.. /tmp/cc-EK7Gc8.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i486-linux-gnu/4.3.3/crtend.o /usr/lib/gcc/i486-linux-gnu/4.3.3/../../../../lib/crtn.o

davidchisnall commented 14 years ago

In r112833, I've fixed the Objective-C-specific issues. I can now confirm that this problem only applies to position-independent code. When I compile a simple program, I can step through it line by line without issues. When I compile a library, the line number info is either missing or wrong for everything in the library.

Since the debug info is correctly emitted for non-PIC code, I think this must be a back end issue - as far as I know, there are no differences in the IR between debug info for PIC and non-PIC code.

davidchisnall commented 14 years ago

If testffi.c is fixed for you guys. But you are having trouble debugging objc then probably you should open a separate PR to avoid confusion. BTW, doesclang objc FE for linux emit debug info while generating llvm IR ?

Clang does emit debug info for Objective-C, however it seems that it is generating an incorrect DW_TAG_subprogram entry. I can probably fix that - it is assuming that the symbol name is the mangled name (which is not a valid assumption, because a lot of platforms - e.g. Linux/PowerPC - require the name to be mangled.

That's orthogonal to the original problem though. Look at frame 3 in my trace:

​3 0x28b07c4c in GSObjCGetVal (sel=0x2939fdd0, offset=684201664,

type=dwarf2_read_address: Corrupted DWARF expression. ) from /usr/local/GNUstep/Local/Library/Libraries/libgnustep-base.so.1.21

Although this is in an Objective-C source file (I think), it is a C function, not an Objective-C method. In spite of this, the line number information is not present and some of the other DWARF data is invalid. I can provide the bitcode that clang generates for this file, if it would help.

llvmbot commented 14 years ago

If testffi.c is fixed for you guys. But you are having trouble debugging objc then probably you should open a separate PR to avoid confusion. BTW, doesclang objc FE for linux emit debug info while generating llvm IR ?

davidchisnall commented 14 years ago

An example of such a (partial) backtrace on FreeBSD:

​0 0x289c6fb6 in _i_NSException__raise (self=0x2a289828) from /usr/local/GNUstep/Local/Library/Libraries/libgnustep-base.so.1.21

​1 0x289c6590 in _c_NSException__raise_formatarguments (self=0x28bc8f50, name=0x28bc9158, format=0x28bc9128, argList=0x28bc9128 "g\001")

from /usr/local/GNUstep/Local/Library/Libraries/libgnustep-base.so.1.21

​2 0x289c64ab in _c_NSException__raiseformat (self=0x289c6fb0, name=0x28bc8d10, format=0x28bc8d10)

from /usr/local/GNUstep/Local/Library/Libraries/libgnustep-base.so.1.21

​3 0x28b07c4c in GSObjCGetVal (sel=0x2939fdd0, offset=684201664, type=dwarf2_read_address: Corrupted DWARF expression.

) from /usr/local/GNUstep/Local/Library/Libraries/libgnustep-base.so.1.21

​4 0x289fae90 in _i_NSObject_KeyValueCodingvalueForKey (aKey=0x2877c468, self=0x29382568)

from /usr/local/GNUstep/Local/Library/Libraries/libgnustep-base.so.1.21

​5 0x28949d00 in _i_NSArray_valueForKey (key=0x2877c468, self=0x2a284908)

from /usr/local/GNUstep/Local/Library/Libraries/libgnustep-base.so.1.21

​6 0x2865e2d9 in _i_GSToolbarView___handleViewsVisibility (self=0x2a11c608) at ../Headers/AppKit/DPSOperators.h:1116

​7 0x2865ec89 in _i_GSToolbarView___reload (self=0x2a11c608) at ../Headers/AppKit/DPSOperators.h:1116

​8 0x2857d3f3 in _i_NSToolbar___build (self=0x2995e708) at ../Headers/AppKit/DPSOperators.h:1116

​9 0x2857c78e in _i_NSToolbar_setDelegate (self=0x2995e708, delegate=0x2974ce08) at ../Headers/AppKit/DPSOperators.h:1116

​10 0x280e4240 in -[GormDocument awakeFromNib] (self=0x2974ce08, _cmd=0x28776bd0) at GormDocument.m:346

​11 0x28643748 in _i_GSNibContainer_awakeWithContext (self=0x29858288, context=0x298584c8) at ../Headers/AppKit/DPSOperators.h:1116

​12 0x28668c56 in _i_GSGormLoader__loadModelData_externalNameTablewithZone (data=0x2a1ab208, zone=0x298584c8, context=0x298584c8,

self=0x298fd6e8) at ../Headers/AppKit/DPSOperators.h:1116

A few things to note:

1) GDB is displaying the mangled function name, rather than the ObjC version. This implies that gdb can not find the description of the unmangled name. It is possible that gdb is using the relocation symbol entry here, rather than the DWARF function name.

2) There is no line number information found for any of the things in the libgnustep-base.so library (frames 0-5).

3) All of the frames corresponding to methods in the libgnustep-gui.so library appear to come from line 1116 of DPSOperators.h, in spite of the fact that none of them actually do (frames 6-12, except 10).

4) Frame 3, according to gdb, has an invalid DWARF expression describing it. GDB doesn't always catch these gracefully - often doing a backtrace of clang-compiled code results in gdb crashing.

5) When setting the breakpoint, gdb issued this warning (repeatedly):

warning: debugging symbol "_i_NSException__raise" does not match minimal symbol ("-[NSException raise]"); ignoring

Frame 10 here was compiled with GCC (this is what it's supposed to look like). Compiling that file with clang gives this:

​10 0x28199685 in _i_GormDocument__awakeFromNib (self=0x298fce08) at /usr/local/GNUstep/Local/Library/Headers/Foundation/NSGeometry.h:222

Again, the line number appears to be within a header that was included, rather than anywhere near the real source location.

Something changed recently means that the parameter values are now set correctly (previously they were nonsense), so at least some of the debug info is correct for each frame, but it does look like the relocation info is either being mangled, or is being incorrectly emitted in the first place.

davidchisnall commented 14 years ago

I'm currently away for vacations, so I won't be able to provide more feedback in the next two weeks.

I'm back. If you need further infos or testing, let me know… It would be handy to get ObjC debugging on Linux and FreeBSD working for the 2.8 release.

A little further testing shows that this problem seems to only be present in position-independent code for me. I can step through Objective-C code in the main executable, but not code in a library. This makes me suspect that the DWARF writer is emitting incorrect relocation information for ELF targets.

When I reach a breakpoint in a library, gdb thinks that every single function / method in that library is in the same source file, at the same line number, irrespective of its actual location, for some libraries, and complains that it has no line number information for others.

llvmbot commented 14 years ago

I'm currently away for vacations, so I won't be able to provide more feedback in the next two weeks.

I'm back. If you need further infos or testing, let me know… It would be handy to get ObjC debugging on Linux and FreeBSD working for the 2.8 release.

davidchisnall commented 14 years ago

However the fix doesn't work with ObjC code. I cannot set a breakpoint in a .m file either by giving a line or a symbol name (e.g. b -[NSObject init]).

Debug info doesn't work at all for me in Objective-C. The method names are all shown in their mangled form in clang-compiled code and the parameter values are all wrong (for example, showing 0x20 as the value for self in every frame on the stack - if this were the case, every message send would have failed).

llvmbot commented 14 years ago

I can now set a breakpoint on a line in testffi.c and step through the code. I should probably test it with a real C program to see if everything works as expected.

However the fix doesn't work with ObjC code. I cannot set a breakpoint in a .m file either by giving a line or a symbol name (e.g. b -[NSObject init]).

I'm currently away for vacations, so I won't be able to provide more feedback in the next two weeks.

llvmbot commented 14 years ago

I just fixed 6218, can someone see if this bug is fixed?

llvmbot commented 14 years ago

This looks like a duplicate of PR 6218.

llvmbot commented 14 years ago

I attached the generated llvm bitcode with and without the -g option (not sure that's useful though).

clang -c -g -emit-llvm -o testffi+g.bc testffi.c and clang -c -emit-llvm -o testffi.bc testffi.c

I had to add -c in the options otherwise clang was complaining: clang: error: 'i386-pc-linux-gnu': unable to pass LLVM bit-code files to linker

llvmbot commented 14 years ago

testffi.c llvm bitcode without -g

llvmbot commented 14 years ago

testffi.c llvm bitcode with -g

llvmbot commented 14 years ago

I think this is a dup, at least I believe some other bug identified the passing of -g to the gcc driver during assembly as a problem.

llvmbot commented 14 years ago

This seems to work on Darwin. Can you attached llvm bitcode (--emit-llvm) generated by clang for your test case ?

davidchisnall commented 14 years ago

I can confirm the same behaviour on FreeBSD. In gdb, all of the clang-compiled functions show up as coming from the same line in the same file.