[cfe-dev] Getting clang to give dwarf info for macro expansions?
Christian Convey
christian.convey at gmail.com
Sun Nov 9 13:53:55 PST 2014
Does anyone know if/how I can get clang to generate dwarf information
that lets me trace / debug *into* macro-generated code?
It seems that when a C program invokes a macro, all of the source code
produced by that macro invocation is attributed to the line at which
the macro is called. I've seen this in both dwarfdump and gdb, as
described below. (The exception seems to be when a macro expansion
causes the definition of a new function. That new function shows up
in the dwarf info as one might hope.)
What I'd ideally like is for tracing tools to clearly describe which
branches within macro-generated code were taken. When all of the
source code generated by a macro invocation is attributed to the macro
*call* site by the dwarf information, that level of precision seems
impossible.
For example, suppose I have this code:
>>>> foo.c
#define FOO \
if (x == 3) { \
return 1; \
}
int bar(int x) {
FOO
return 0;
}
<<<<<
And I compile it with this command:
clang -c -g -Xclang -dwarf-column-info foo.c
And I look at the dwarf information using the command:
objdump -dgls foo.o
I get this:
...
Disassembly of section .text:
0000000000000000 <bar>:
bar():
/tmp/foo.c:6
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 7d f8 mov %edi,-0x8(%rbp)
/tmp/foo.c:7
7: 81 7d f8 03 00 00 00 cmpl $0x3,-0x8(%rbp)
e: 0f 85 0c 00 00 00 jne 20 <bar+0x20>
14: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%rbp)
1b: e9 07 00 00 00 jmpq 27 <bar+0x27>
/tmp/foo.c:8
20: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
/tmp/foo.c:9
27: 8b 45 fc mov -0x4(%rbp),%eax
2a: 5d pop %rbp
2b: c3 retq
...
Note that all of the reported source locations are in lines 6-9;
nothing is attributed to lines 1-3.
To double-check that I really can't get detailed trace information
from macro-generated code, I added a main() function and stepped
through the code with gdb. Here's what I got:
(gdb) list
4 }
5
6 int bar(int x) {
7 FOO
8 return 0;
9 }
10
11 int main(int argc, const char* argv[] )
12 {
13 return bar( argc );
(gdb) break main
Breakpoint 1 at 0x4004d6: file foo.c, line 13.
(gdb) run
Starting program: /tmp/a.out
Breakpoint 1, main (argc=1, argv=0x7fffffffdf98) at foo.c:13
13 return bar( argc );
(gdb) step
bar (x=1) at foo.c:7
7 FOO
(gdb) step
8 return 0;
(gdb) step
9 }
(gdb) step
__libc_start_main (main=0x4004c0 <main>, argc=1, argv=0x7fffffffdf98,
init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffdf88) at libc-start.c:321
321 libc-start.c: No such file or directory.
(gdb)
More information about the cfe-dev
mailing list