valgrind

Understanding stack matching rules for custom suppressions


I applied Valgrind over some C/C++ processes of mine, containing a lot of errors coming from libraries I'm not interested in and that I'd like to suppress. Let's call them banned libraries. The problem is that I'm unsure about how exactly stack matching works in suppression rules.

For example, for an invented error like this, where libX is a banned library:

==60548== Invalid write of size 4
==60548==    by 0x....: function_signature_1 (some_file1:some_line1)
==60548==    by 0x....: function_signature_2 (in /some/path/libX.so)
==60548==    by 0x....: function_signature_3 (in /some/path/libX.so)
==60548==    by 0x....: function_signature_4 (some_file2:some_line2)

If I write:

   mysupression
   Memcheck:Addr4
   ...
   obj:/some/path/libX.so
   ...

if I'm not wrong, that will skip all errors, not only those coming from the library, but whose stacks contains the library. In my invented example, the library I'm not interested in, has called a function I'm interested in (for example, an installed user-defined callback), but the suppression rule will rule it out, because the stack contains frames from the library.

You could say, well, make sure the banned library is in the top of the stack:

   mysuppression
   Memcheck:Addr4
   obj:/some/path/libX.so
   ...

OK, but now consider the invented_error2:

==60548== Invalid write of size 4
==60548==    by 0x....: ???
==60548==    by 0x....: ???
==60548==    by 0x....: function_signature_2 (in /some/path/libX.so)
==60548==    by 0x....: function_signature_3 (in /some/path/libX.so)
==60548==    by 0x....: function_signature_4 (some_file2:some_line2)

Those unknowns locations are very common within library errors, which forces me to ... as first line and I'm back to the original situation.

So, in order to think further about how to suppress what I'm not interested in, how does matching rules work? Do what I write must represents a full stack? The rules is only require to match from top to bottom (e.g., do writing ... at the end of the pattern required?), etc.

The question, in short, is, what is the "algorithm" that matches suppression rules with stackframes?


Solution

  • Firstly, fixing the issue is always the best. Not always possible in third party libraries.

    Secondly, there is no point putting ... at the end of the suppression. If everything matches up to the last line then the matching will stop searching and consider the suppression a match.

    Next, I recommend that you use --gen-suppressions=all and then copy/paste/adapt the suppression stanzas. Do always use a unique tag on the first line though.

    The rules are fairly simple. If Valgrind can get function names it will use fun:. If you can install debuginfo packages on your system that may well work better and give more precise suppressions. Otherwise it will use obj: with the name of the binary if it can find that. There is also src: but I've almost never seen that used.

    You could write a somewhat less general suppression like

    {
       mysupression
       Memcheck:Addr4
       obj:*
       obj:*
       obj:/some/path/libX.so
    }
    

    That will match 2 and only 2 levels and then one level in libX.so.

    The suppression syntax is fairly simple and doesn't support things like negative matching.