|
From: Martin L. <ml...@uc...> - 2021-05-24 19:37:22
|
Hello, I think the Valgrind stack tracer is pretty great and I would like to use it as a substitute for `backtrace` in my C++ debug builds. A blog post by Nicholas Nethercote (Using Valgrind to get stack traces) describes a similar idea: https://blog.mozilla.org/nnethercote/2011/01/11/using-valgrind-to-get-stack-traces/ However, while this is already fairly elegant, I am wondering whether this can be done without invoking the program under valgrind. If the Valgrind stack tracer were a simple #include that would be best. Alternatively, a means of including any necessary valgrind framework into the debug build would be helpful. I appreciate your feedback. Regards, Martin |
|
From: Philippe W. <phi...@sk...> - 2021-05-24 21:16:24
|
On Mon, 2021-05-24 at 10:31 -0700, Martin Licht via Valgrind-users wrote: > Hello, > > I think the Valgrind stack tracer is pretty great and I would like to use it as a substitute for `backtrace` in my C++ debug builds. > > A blog post by Nicholas Nethercote (Using Valgrind to get stack traces) describes a similar idea: > https://blog.mozilla.org/nnethercote/2011/01/11/using-valgrind-to-get-stack-traces/ > > However, while this is already fairly elegant, I am wondering whether this can be done without invoking the program under valgrind. > > If the Valgrind stack tracer were a simple #include that would be best. > Alternatively, a means of including any necessary valgrind framework into the debug build would be helpful. I appreciate your feedback. The valgrind unwinder is very fast, so having it as a "standalone" library that can be linked to a normal executable and used outside of the valgrind JIT framework would be really nice. However, I think this unwind logic/code has a lot of dependencies to other parts of valgrind (debug info reader, address space manager, valgrind own malloc library, valgrind log and debug framework, ...). So, clearly not a small task to 'cleanly' lib-ify the valgrind unwinder, in particular if this library must then be usable both in a valgrind context and in a 'native' context. Philippe |
|
From: John R. <jr...@bi...> - 2021-05-24 22:08:55
|
On 5/24/21, Martin Licht via Valgrind-users wrote:
> I think the Valgrind stack tracer is pretty great and I would like to use it as a substitute for `backtrace` in my C++ debug builds.
It would help to give an explicit list of why valgrind's backtrace() is "pretty great"
in contrast to GNU's. The comment
https://blog.mozilla.org/nnethercote/2011/01/11/using-valgrind-to-get-stack-traces/#comment-438
identifies one item: GNU backtrace() shows only global (non-static) symbols.
What else?
Also, a detailed list would make a good request for enhancement
at https://www.gnu.org/software/libc/bugs.html ,
especially if accompanied by an actual test case
that shows how much better valgrind backtrace() is currently.
--
|
|
From: Martin L. <ml...@uc...> - 2021-05-27 03:31:27
|
Addressing the first point: what Valgrind's tracer does better than others
is fetching more source code information and semantics. This can shown
immediately with the following example:
```
#include <assert.h>
#include <stdlib.h>
inline void bar()
{
abort();
}
template<typename T>
inline void foo(T)
{
bar();
}
int main()
{
foo(5);
return 0;
}
```
If compiled with -g, the debug output will display (1) C/C++ names down
into the standard library (2) source code names and signatures (3)
including template instantiations (4) file names (5) line numbers, among
other things. I would be great to have a stack tracer like that.
The prettiest alternatives without Valgrind go along the lines of
https://eli.thegreenplace.net/2015/programmatic-access-to-the-call-stack-in-c/
using libunwind and cxxabi. This still is not as close to the source as
Valgrind's output.
Best,
Martin
On Mon, May 24, 2021 at 3:09 PM John Reiser <jr...@bi...> wrote:
> On 5/24/21, Martin Licht via Valgrind-users wrote:
>
> > I think the Valgrind stack tracer is pretty great and I would like to
> use it as a substitute for `backtrace` in my C++ debug builds.
>
> It would help to give an explicit list of why valgrind's backtrace() is
> "pretty great"
> in contrast to GNU's. The comment
>
> https://urldefense.com/v3/__https://blog.mozilla.org/nnethercote/2011/01/11/using-valgrind-to-get-stack-traces/*comment-438__;Iw!!Mih3wA!UfTEqXmRbG-pQAMC4pm54vloAenaAZoBw-abVILaGfvzVPS2T4cKVx6_eFTqAPk$
> identifies one item: GNU backtrace() shows only global (non-static)
> symbols.
> What else?
>
> Also, a detailed list would make a good request for enhancement
> at
> https://urldefense.com/v3/__https://www.gnu.org/software/libc/bugs.html__;!!Mih3wA!UfTEqXmRbG-pQAMC4pm54vloAenaAZoBw-abVILaGfvzVPS2T4cKVx6_Yz5dunc$
> ,
> especially if accompanied by an actual test case
> that shows how much better valgrind backtrace() is currently.
>
> --
>
>
>
> _______________________________________________
> Valgrind-users mailing list
> Val...@li...
>
> https://urldefense.com/v3/__https://lists.sourceforge.net/lists/listinfo/valgrind-users__;!!Mih3wA!UfTEqXmRbG-pQAMC4pm54vloAenaAZoBw-abVILaGfvzVPS2T4cKVx6_dyjVF6g$
>
|
|
From: John R. <jr...@bi...> - 2021-05-27 07:20:58
|
For the example given, the backtrace command of gdb-8.3 already displays 80%
of the requested information for code compiled by g++-9.3.1 using -g.
The request:
> If compiled with -g, the debug output will display
> (1) C/C++ names down into the standard library
> (2) source code names and signatures
> (3) including template instantiations
> (4) file names
> (5) line numbers
(gdb) backtrace
#0 __GI_raise (sig=sig@entry=0x6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007ffff7aac895 in __GI_abort () at abort.c:79
#2 0x0000000000401144 in bar () at traceback-test.c:6
#3 0x0000000000401154 in foo<int> () at traceback-test.c:12
#4 0x0000000000401134 in main () at traceback-test.c:17
valgrind-3.17.0:
==16820== Process terminating with default action of signal 6 (SIGABRT): dumping core
==16820== at 0x4BFCE35: raise (raise.c:51)
==16820== by 0x4BE7894: abort (abort.c:79)
==16820== by 0x401143: bar() (traceback-test.c:6)
==16820== by 0x401153: void foo<int>(int) (traceback-test.c:12)
==16820== by 0x401133: main (traceback-test.c:17)
In this example, item (3) is the only essential difference.
valgrind:
void foo<int>(int) (traceback-test.c:12)
contains result type and argument type, while
gdb:
in foo<int> () at traceback-test.c:12
lacks "void" and "(int)".
For items (1), (2), (4), and (5) the gdb output contains the same information
as the valgrind output. In addition, gdb gives more information for (1):
the complete internal path for standard library code
../sysdeps/unix/sysv/linux/raise.c:50
in contrast to valgrind's
(raise.c:51)
So, any request for a better backtrace should be much more explicit than what was posted originally.
On 5/26/21, Martin Licht via Valgrind-users wrote:
> Addressing the first point: what Valgrind's tracer does better than others is fetching more source code information and semantics. This can shown immediately with the following example:
>
> ```
> #include <assert.h>
> #include <stdlib.h>
>
> inline void bar()
> {
> abort();
> }
>
> template<typename T>
> inline void foo(T)
> {
> bar();
> }
>
> int main()
> {
> foo(5);
> return 0;
> }
> ```
>
> If compiled with -g, the debug output will display (1) C/C++ names down into the standard library (2) source code names and signatures (3) including template instantiations (4) file names (5) line numbers, among other things. I would be great to have a stack tracer like that.
>
> The prettiest alternatives without Valgrind go along the lines of
> https://eli.thegreenplace.net/2015/programmatic-access-to-the-call-stack-in-c/
> using libunwind and cxxabi. This still is not as close to the source as Valgrind's output.
|