Bug 407904 - Inlined member operators lose class name in logs and generated suppressions
Summary: Inlined member operators lose class name in logs and generated suppressions
Status: RESOLVED NOT A BUG
Alias: None
Product: valgrind
Classification: Developer tools
Component: general (show other bugs)
Version: 3.13.0
Platform: RedHat Enterprise Linux Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-05-24 13:56 UTC by Daniel
Modified: 2019-12-28 16:15 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel 2019-05-24 13:56:35 UTC
SUMMARY
When class provide overloaded operators which are inlined somewhere, in logs and for --gen-suppressions they lose class name.

STEPS TO REPRODUCE
1. Create file with this code:
[code]
class Test
{
    int* p;
    int n;
public:
    Test(int* p, int n) : p(p), n(n) {}
    
    operator bool();
};

//__attribute__((noinline))
Test::operator bool() { return p[n] > 0; }

int main()
{
    int* p = new int[2];
    Test* t = new Test(p, 2);
    return (bool)*t;
}
[/code]

2. Compile using
g++ -o test test.cc -O3 -g

3. Run
valgrind --gen-suppressions=all ./test

OBSERVED RESULT
When operator bool() is inlined, it prints this:

==21714== Invalid read of size 4
==21714==    at 0x4004EF: operator bool (test.cc:12)
==21714==    by 0x4004EF: main (test.cc:18)
==21714==  Address 0x5a22048 is 0 bytes after a block of size 8 alloc'd
==21714==    at 0x4C2A888: operator new[](unsigned long) (vg_replace_malloc.c:423)
==21714==    by 0x4004DA: main (test.cc:16)
==21714== 
{
   <insert_a_suppression_name_here>
   Memcheck:Addr4
   fun:operator bool
   fun:main
}
==21714== 


EXPECTED RESULT
When operator bool() is not inlined (after uncommenting line with noinline attribute), it prints this:

==21687== Invalid read of size 4
==21687==    at 0x4005F7: Test::operator bool() (test.cc:12)
==21687==    by 0x4004F9: main (test.cc:18)
==21687==  Address 0x5a22048 is 0 bytes after a block of size 8 alloc'd
==21687==    at 0x4C2A888: operator new[](unsigned long) (vg_replace_malloc.c:423)
==21687==    by 0x4004DA: main (test.cc:16)
==21687== 
{
   <insert_a_suppression_name_here>
   Memcheck:Addr4
   fun:_ZN4TestcvbEv
   fun:main
}


SOFTWARE/OS VERSIONS
OS: CentOS Linux release 7.6.1810 (Core)
Valgrind: valgrind-3.13.0
g++ used to compile example code: g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
Comment 1 Tom Hughes 2019-05-24 14:58:24 UTC
This is almost certainly a bug in the (ancient) version of gcc you are using - clearly the mangled name produced by the compiler is missing the class when it has been inlined.

There isn't really much we can do about that...
Comment 2 Tom Hughes 2019-05-24 14:59:42 UTC
Indeed I rather suspect the compiler has put the function in the symbol table as "operator bool" without any mangling at all, given that valgrind has printed it without any mangling.
Comment 3 Tom Hughes 2019-05-24 15:02:38 UTC
Actually I guess when it's inlined there is no symbol table entry for that function so we must be getting the name from the debug data.

It's going to be very messy though - recognising the inline function at all is a fairly recent thing I think and trying to suppress on one is probably not the best plan.
Comment 4 Daniel 2019-05-24 15:32:31 UTC
I checked that gdb also shows it in the same way, so this is gcc issue.

Unfortunately this gcc version is default for RedHat and CentOS 7. RedHat 8 will have new gcc. However migration to it will need time.

Helgrind does not recognize atomics and reports race conditions on them. I wanted to create suppression file to filter out them. Fortunately we need it only for our tests, so we can compile them without optimization.
Comment 5 Julian Seward 2019-12-28 16:15:01 UTC
This seems to be a problem caused by compilers emitting incomplete
names in the Dwarf unwind info, if I understand correctly.  Not sure
there's anything we can do about that.