|
From: Konstantin S. <kon...@gm...> - 2009-06-30 13:22:02
|
Hello, Valgrind developers.
Currently, if memcheck is run on a program which is compiled with
inlining enabled, the stack traces are not precise.
Example:
% cat inl_test.c
#include <stdio.h>
inline void foo(int *p) {
if (*p == 777) printf("777\n");
}
__attribute__ ((noinline))
void bar (int *p) {
foo(p);
}
int main() {
int uninitialized_stack[10];
bar(&uninitialized_stack[1]);
return 0;
}
% gcc -g -O0 inl_test.c && ~/valgrind/trunk/inst/bin/valgrind -q ./a.out
==27322== Conditional jump or move depends on uninitialised value(s)
==27322== at 0x400523: foo (inl_test.c:4)
==27322== by 0x400545: bar (inl_test.c:9)
==27322== by 0x40055C: main (inl_test.c:14)
% gcc -g -O2 inl_test.c && ~/valgrind/trunk/inst/bin/valgrind -q ./a.out
==27380== Conditional jump or move depends on uninitialised value(s)
==27380== at 0x400536: bar (inl_test.c:4)
==27380== by 0x40055D: main (inl_test.c:14)
You can see that with -O0 the stack trace contains foo and with -O2 it
doers not.
But the DWARF info contains the information about inlining:
% readelf -w a.out
<1><421>: Abbrev Number: 14 (DW_TAG_subprogram)
<422> DW_AT_external : 1
<423> DW_AT_name : foo
...
<1><465>: Abbrev Number: 18 (DW_TAG_subprogram)
<466> DW_AT_external : 1
<467> DW_AT_name : bar
...
<2><492>: Abbrev Number: 20 (DW_TAG_inlined_subroutine)
<493> DW_AT_abstract_origin: <421>
<497> DW_AT_low_pc : 0x400530
<49f> DW_AT_high_pc : 0x40054a
<4a7> DW_AT_call_file : 1
<4a8> DW_AT_call_line : 9
So, it is theoreticlally possible to produce a precise stack trace
even in presence of inlining.
Or I miss something?
Shall I file a bug (feature request)?
Thanks,
--kcc
|
|
From: Julian S. <js...@ac...> - 2009-06-30 20:12:39
|
> So, it is theoreticlally possible to produce a precise stack trace > even in presence of inlining. > Or I miss something? This confused me for a long time. I the end I concluded: there's a difference between a "logical stack trace" and a "real stack trace" (let's say). The real stack trace is what V shows. It is what is really on the stack. Hence no frame for bar; it is not there. A logical stack trace would still contain the call to bar. However, that is fictional, since it is not really there. > Shall I file a bug (feature request)? If you can show that GDB does produce the same stack traces in both cases, then yes. But I doubt it can do that. J |
|
From: Ashley P. <as...@pi...> - 2009-07-02 08:08:24
|
On Tue, 2009-06-30 at 15:45 +0200, Julian Seward wrote: > > I the end I concluded: there's a difference between a "logical stack > trace" and a "real stack trace" (let's say). > > The real stack trace is what V shows. It is what is really on the > stack. Hence no frame for bar; it is not there. > > A logical stack trace would still contain the call to bar. However, > that is fictional, since it is not really there. That explains a lot, I was experimenting with -g3 for macro debugging last week and couldn't get it to make the slightest bit of difference to the observed stack, either in valgrind or gdb. Ashley, -- Ashley Pittman, Bath, UK. Padb - A parallel job inspection tool for cluster computing http://padb.pittman.org.uk |
|
From: Konstantin S. <kon...@gm...> - 2009-07-02 07:46:58
|
>> Shall I file a bug (feature request)?
>
> If you can show that GDB does produce the same stack traces in both
> cases, then yes. But I doubt it can do that.
>
I've just learned that this feature has been implemented in gdb few
days ago. :)
2009-06-27 Daniel Jacobowitz <da...@co...>
Jan Kratochvil <jan...@re...>
* NEWS: Document inlined function support.
* Makefile.in (SFILES): Add inline-frame.c.
(COMMON_OBS): Add inline-frame.o.
* block.c (contained_in): Rewrite to use lexical nesting.
...
>From NEWS:
* Inlined functions are now supported. They show up in backtraces, and
the "step", "next", and "finish" commands handle them automatically.
$ gdb64-cvs ./a.out
GNU gdb (GDB) 6.8.50.20090701-cvs
...
(gdb) b main
Breakpoint 1 at 0x4003a0: file inline_test.c, line 12.
(gdb) r
Breakpoint 1, main () at inline_test.c:12
12 int main() {
(gdb) s
14 bar(&uninitialized_stack[1]);
(gdb) s
bar (p=0x7fffffffdd04) at inline_test.c:9
9 foo(p);
(gdb) s
foo (p=0x7fffffffdd04) at inline_test.c:4
4 if (*p == 777) printf("777\n");
(gdb) bt
#0 foo (p=0x7fffffffdd04) at inline_test.c:4
#1 bar (p=0x7fffffffdd04) at inline_test.c:9
#2 0x00000000004003ae in main () at inline_test.c:14
(gdb) disas
Dump of assembler code for function bar:
0x0000000000400380 <bar+0>: cmpl $0x309,(%rdi)
0x0000000000400386 <bar+6>: je 0x400390 <bar+16>
0x0000000000400388 <bar+8>: repz retq
0x000000000040038a <bar+10>: nopw 0x0(%rax,%rax,1)
0x0000000000400390 <bar+16>: mov $0x40047c,%edi
0x0000000000400395 <bar+21>: jmpq 0x4005e8 <puts@plt>
End of assembler dump.
Disassembly clearly shows foo was inlined; yet it shows in the stack trace :-)
--kcc
|
|
From: Konstantin S. <kon...@gm...> - 2009-07-06 10:36:17
|
Submitted https://bugs.kde.org/show_bug.cgi?id=199144 --kcc On Thu, Jul 2, 2009 at 11:46 AM, Konstantin Serebryany<kon...@gm...> wrote: >>> Shall I file a bug (feature request)? >> >> If you can show that GDB does produce the same stack traces in both >> cases, then yes. But I doubt it can do that. >> > > I've just learned that this feature has been implemented in gdb few > days ago. :) > > 2009-06-27 Daniel Jacobowitz <da...@co...> > Jan Kratochvil <jan...@re...> > > * NEWS: Document inlined function support. > * Makefile.in (SFILES): Add inline-frame.c. > (COMMON_OBS): Add inline-frame.o. > * block.c (contained_in): Rewrite to use lexical nesting. > ... > > From NEWS: > > * Inlined functions are now supported. They show up in backtraces, and > the "step", "next", and "finish" commands handle them automatically. > > $ gdb64-cvs ./a.out > GNU gdb (GDB) 6.8.50.20090701-cvs > ... > (gdb) b main > Breakpoint 1 at 0x4003a0: file inline_test.c, line 12. > (gdb) r > > Breakpoint 1, main () at inline_test.c:12 > 12 int main() { > (gdb) s > 14 bar(&uninitialized_stack[1]); > (gdb) s > bar (p=0x7fffffffdd04) at inline_test.c:9 > 9 foo(p); > (gdb) s > foo (p=0x7fffffffdd04) at inline_test.c:4 > 4 if (*p == 777) printf("777\n"); > (gdb) bt > #0 foo (p=0x7fffffffdd04) at inline_test.c:4 > #1 bar (p=0x7fffffffdd04) at inline_test.c:9 > #2 0x00000000004003ae in main () at inline_test.c:14 > (gdb) disas > Dump of assembler code for function bar: > 0x0000000000400380 <bar+0>: cmpl $0x309,(%rdi) > 0x0000000000400386 <bar+6>: je 0x400390 <bar+16> > 0x0000000000400388 <bar+8>: repz retq > 0x000000000040038a <bar+10>: nopw 0x0(%rax,%rax,1) > 0x0000000000400390 <bar+16>: mov $0x40047c,%edi > 0x0000000000400395 <bar+21>: jmpq 0x4005e8 <puts@plt> > End of assembler dump. > > Disassembly clearly shows foo was inlined; yet it shows in the stack trace :-) > > > --kcc > |