problems with dwarf/gdb

I'm having trouble debugging x86 code generated by LLVM.
GDB does work with the code, but not correctly, for example,
the "next" command does not skip over a function call.

Here's an example.

Source program gdb1.c:

int x;

void foo(){
  x++;
}

void bar(){
  x--;
}

int main(){
  foo();
  bar();
  return 0;
}

commands:

$ llvm-gcc -g -emit-llvm -c gdb1.c -o gdb1.bc
$ llc gdb1.bc
$ gcc -m32 gdb1.s -o gdb1
$ gdb ./gdb1
GNU gdb Red Hat Linux (6.6-16.fc7rh)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu"...
Using host libthread_db library "/lib64/libthread_db.so.1".
(gdb) b main
Breakpoint 1 at 0x80483a0: file
/home/mcmillan/projects/impact2/test//gdb1.c, line 11.
(gdb) run
Starting program: /home/mcmillan/projects/impact2/test/gdb1

Breakpoint 1, main () at /home/mcmillan/projects/impact2/test//gdb1.c:11
11 int main(){
(gdb) next
main () at /home/mcmillan/projects/impact2/test//gdb1.c:12
12 foo();
(gdb)
foo () at /home/mcmillan/projects/impact2/test//gdb1.c:4
4 x++;
(gdb)
5 }
(gdb)
main () at /home/mcmillan/projects/impact2/test//gdb1.c:13
13 bar();
(gdb)
bar () at /home/mcmillan/projects/impact2/test//gdb1.c:8
8 x--;
(gdb)
9 }
(gdb)

Notice the "next" causes gdb to step into "foo" instead of stepping
over it.

Also, notice that I used -m32 on the gcc command line to assemble
the LLVM-generated source file. This seems to be needed, though
I don't know why LLVM would be generating 32-bit code on my
64-bit machine.

Versions: LLVM 2.5 (though got same result with 2.2), gcc 4.1.2,
gdb 6.6, running on x86 Linux (Fedora 7).

Has anyone had similar issues with gdb? Is debugging with gdb
known to work properly on other platforms?

Thanks for any help --

Ken McMillan

This is a known limitation on debug info generated by llvm, at least as per Darwin Gdb.

Hi Ken,

Ken McMillan wrote:

I'm having trouble debugging x86 code generated by LLVM.
GDB does work with the code, but not correctly, for example,
the "next" command does not skip over a function call.

Here's an example.

Source program gdb1.c:

int x;

void foo(){
  x++;
}

void bar(){
  x--;
}

int main(){
  foo();
  bar();
  return 0;
}

commands:

$ llvm-gcc -g -emit-llvm -c gdb1.c -o gdb1.bc
$ llc gdb1.bc
  
Try
llc -disable-fp-elim gdb1.bc

-Argiris

Argiris Kirtzidis wrote:

...

Try
llc -disable-fp-elim gdb1.bc

Thanks, I would never have guessed that :-).

Are there any other optimizations that are harmful to
debug info that I should know about?

Thanks -- Ken

Lots of them. Partly this is because the job of most optimizations is to change the code from something that corresponds fairly closely to the source, to something that doesn't; good, or even usable, debug info with optimization is an active research area. And partly it's because we haven't done a lot of work on it yet in llvm.

But I don't think anything else run by default makes life as difficult as fp elimination.

I see. Here's another interesting issue:

(gdb) b gdb1.c:4
No line 4 in file "gdb1.c".
(gdb) step
foo () at /home/mcmillan/projects/impact2/test//gdb1.c:4
4 x++;
(gdb)

You can see that I can step to line 4, but I can't set a breakpoint there.
(I used -disable-fp-elim in the compilation).

Have you seen this before?

Thanks -- Ken

Dale Johannesen wrote:

Ken McMillan wrote:

I see. Here's another interesting issue:

(gdb) b gdb1.c:4
No line 4 in file "gdb1.c".
(gdb) step
foo () at /home/mcmillan/projects/impact2/test//gdb1.c:4
4 x++;
(gdb)

You can see that I can step to line 4, but I can't set a breakpoint there.
  
Works fine here (llvm 2.5, 32 bit, gdb 6.8)

Try

llc -disable-fp-elim -fast gdb1.bc

If you do
llvm-gcc -g gdb1.c -o gdb1

does it have the same issue ?

-Argiris

Well...

$ ~/software/llvm-gcc4.2-2.5-x86-linux-RHEL4/bin/llvm-gcc -g gdb1.c -o gdb1
/tmp/ccbAj8x9.s: Assembler messages:
/tmp/ccbAj8x9.s:35: Error: suffix or operands invalid for `push'
/tmp/ccbAj8x9.s:44: Error: suffix or operands invalid for `pop'
/tmp/ccbAj8x9.s:56: Error: suffix or operands invalid for `push'
/tmp/ccbAj8x9.s:65: Error: suffix or operands invalid for `pop'
/tmp/ccbAj8x9.s:77: Error: suffix or operands invalid for `push'
/tmp/ccbAj8x9.s:94: Error: suffix or operands invalid for `pop'

Don't know what that's about. If I use the -S option and then
compile the .s file with gcc, it works fine (but again, can't set
breakpoints in gdb).

I am currently using gdb 6.6. Will try 6.8...

Thanks -- Ken

Argiris Kirtzidis wrote:

Well...

$ ~/software/llvm-gcc4.2-2.5-x86-linux-RHEL4/bin/llvm-gcc -g gdb1.c -o gdb1
/tmp/ccbAj8x9.s: Assembler messages:
/tmp/ccbAj8x9.s:35: Error: suffix or operands invalid for `push'
/tmp/ccbAj8x9.s:44: Error: suffix or operands invalid for `pop'
/tmp/ccbAj8x9.s:56: Error: suffix or operands invalid for `push'
/tmp/ccbAj8x9.s:65: Error: suffix or operands invalid for `pop'
/tmp/ccbAj8x9.s:77: Error: suffix or operands invalid for `push'
/tmp/ccbAj8x9.s:94: Error: suffix or operands invalid for `pop'

Don't know what that's about. If I use the -S option and then
compile the .s file with gcc, it works fine (but again, can't set
breakpoints in gdb).

This means your llvm-gcc is producing 64-bit code and invoking the assembler with a 32-bit option, or vice versa. Run gcc -v to see the option you need to pass. Other people have reported this, I don't recall how it is fixed (doesn't affect my system).

Here is the previous post:
http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-March/020979.html