Valgrind --tool=exp-sgcheck

This is Ubuntu 14.04.4 LTS / x86_64 / g++ 4.8.4 and Valgrind-3.10.1 (the default version on Ubuntu 14.04.4 LTS), Valgrind 3.11.0 (the current release) and the current svn trunk (in all cases I get the same problem) here …

It seems that, as soon as ROOT related libraries are linked in, the valgrind’s “exp-sgcheck” experimental stack and global array overrun detector refuses to work (one does not even need to #include anything from ROOT).

Try a simple “main.cxx”:

#include <cstdio>
int main(void) {
  printf("... main ...\n");
  return 0;
}

If one compiles it using: `root-config --cxx --cflags` -g main.cxx then “ldd ./a.out” will NOT show any ROOT related libraries and: valgrind --tool=exp-sgcheck ./a.out works fine.
Note: one gets some “evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93” warnings, but they do not seem to pose any problems (one cannot get rid of them, even if one tries “-gdwarf-2”).

However, as soon as one compiles it using: `root-config --cxx --cflags` -g main.cxx -Wl,--no-as-needed -L${ROOTSYS}/lib -lCore then “ldd ./a.out” will show “libCore” (and also “libCint” for ROOT 5) and then valgrind says that it cannot set its own “assertion” (note: it did not run “main” at all):

[...]$ root-config --version --arch
6.06/02 linuxx8664gcc
[...]$ root-config --cxx --cflags
c++ -pthread -std=c++11 -Wno-deprecated-declarations -m64 -I/opt/ROOT/v6-06-02/include
[...]$ c++ --version
c++ (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
[...]$ `root-config --cxx --cflags` -g main.cxx -Wl,--no-as-needed -L${ROOTSYS}/lib -lCore
[...]$ valgrind --tool=exp-sgcheck ./a.out
==4748== exp-sgcheck, a stack and global array overrun detector
==4748== NOTE: This is an Experimental-Class Valgrind Tool
==4748== Copyright (C) 2003-2015, and GNU GPL'd, by OpenWorks Ltd et al.
==4748== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==4748== Command: ./a.out
==4748== 
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
--4748-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93

exp-sgcheck: sg_main.c:559 (add_blocks_to_StackTree): Assertion '!already_present' failed.

host stacktrace:
==4748==    at 0x38013B88: show_sched_status_wrk (m_libcassert.c:343)
==4748==    by 0x38013C94: report_and_quit (m_libcassert.c:415)
==4748==    by 0x38013E21: vgPlain_assert_fail (m_libcassert.c:481)
==4748==    by 0x3800A980: add_blocks_to_StackTree (sg_main.c:559)
==4748==    by 0x3800B8A9: shadowStack_new_frame.isra.22 (sg_main.c:1883)
==4748==    by 0x804F40C49: ???
==4748==    by 0x804072F2F: ???
==4748==    by 0x80206450F: ???
==4748==    by 0x5F7257A: __nscd_get_mapping (nscd_helper.c:286)
==4748==    by 0x80206450F: ???
==4748==    by 0x1BFF: ???

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable (lwpid 4748)
==4748==    at 0x5F725B8: __nscd_get_mapping (nscd_helper.c:293)
==4748==    by 0x5F72ABB: __nscd_get_map_ref (nscd_helper.c:443)
==4748==    by 0x5F6F207: nscd_getpw_r (nscd_getpw_r.c:95)
==4748==    by 0x5F6F645: __nscd_getpwuid_r (nscd_getpw_r.c:63)
==4748==    by 0x5F0038F: getpwuid_r@@GLIBC_2.2.5 (getXXbyYY_r.c:196)
==4748==    by 0x5EFFB85: getpwuid (getXXbyYY.c:116)
==4748==    by 0x50F349B: TUnixSystem::UnixHomedirectory(char const*) (TUnixSystem.cxx:3816)
==4748==    by 0x4F7CFAA: TROOT::InitSystem() (TROOT.cxx:1646)
==4748==    by 0x4F7EB7B: TROOT::TROOT(char const*, char const*, void (**)()) (TROOT.cxx:491)
==4748==    by 0x4F80079: ROOT::Internal::GetROOT1() (TROOT.cxx:312)
==4748==    by 0x4F75ABF: _GLOBAL__sub_I_TROOT.cxx (TROOT.cxx:407)
==4748==    by 0x4010139: call_init.part.0 (dl-init.c:78)
==4748==    by 0x4010222: _dl_init (dl-init.c:36)
==4748==    by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)


Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.

If that doesn't help, please report this bug to: www.valgrind.org

In the bug report, send all the above text, the valgrind
version, and what OS and version you are using.  Thanks.

Well, it seems that it was in the glibc code when it failed (again, one can probably safely disregard all “unhandled DW_OP_” warnings).

I talked to somebody on the IRC channel for Valgrind developers (#valgrind-dev at irc.freenode.net) and I was told that we needed to file a bug report using their Bugzilla report page (note: I guess they will expect to receive some help with getting the ROOT code to debug against). Could someone from the ROOT team take care of it, please.

BTW. See also: AddressSanitizer memory error detector

This is Ubuntu 14.04.5 LTS / x86_64 / g++ 4.8.4, Ubuntu 16.04.3 LTS / x86_64 / g++ 5.4.0 and the current Valgrind git head (i.e. valgrind-3.14.0.GIT) here …

It seems that the problem reported in the first post above is no longer present and one can now run "valgrind --tool=exp-sgcheck” with ROOT related macros and executables. One just needs to make sure that any source code, which one wants to analyse (i.e. a ROOT macro or a standalone executable), is compiled in debug mode (i.e. with debug symbols).

Unfortunately, currently, “valgrind --tool=exp-sgcheck” is not really a replacement for the AddressSanitizer memory error detector. Not only it is much, much slower but, it can also fail to detect and report “stack smashing” problems.