我在我的一些 C/C++ 进程上应用了 Valgrind,其中包含许多来自我不感兴趣且我想抑制的库的错误。我们称它们为“禁止图书馆”。问题是我不确定堆栈匹配在抑制规则中到底是如何工作的。 例如,对于像这样发明的错误,其中 libX 是被禁止的库:
==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)
如果我写:
mysupression
Memcheck:Addr4
...
obj:/some/path/libX.so
...
如果我没记错的话,这将跳过所有错误,不仅是那些来自
库的错误,而且其堆栈包含该库。在我发明的示例中,我不感兴趣的库调用了我感兴趣的函数(例如,安装的用户定义的回调),但抑制规则将排除它,因为堆栈包含来自图书馆的框架。 你可以说,好吧,确保被禁止的库位于堆栈的顶部:
mysuppression
Memcheck:Addr4
obj:/some/path/libX.so
...
好的,但现在考虑
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)
这些未知位置在库错误中很常见,这迫使我将
...
作为第一行,然后我又回到了原来的情况。
那么,为了进一步思考如何抑制我不感兴趣的内容,匹配规则是如何运作的?我写的东西一定代表一个完整的堆栈吗?规则只要求从上到下匹配(例如,在需要的模式末尾写...
吗?)等等
简而言之,问题是,将抑制规则与堆栈帧相匹配的“算法”是什么?
其次,在抑制的末尾添加
...
是没有意义的。如果所有内容都匹配到最后一行,则匹配将停止搜索并认为抑制匹配。
接下来,我建议您使用--gen-suppressions=all
,然后复制/粘贴/调整抑制节。不过,请务必在第一行使用唯一的标签。
规则相当简单。如果 Valgrind 可以获取函数名称,它将使用fun:
。如果您可以在系统上安装 debuginfo 软件包,那么它可能会更好地工作并提供更精确的抑制。否则,如果可以找到,它将使用
obj:
和二进制文件的名称。还有src:
,但我几乎没见过用过。你可以写一个不太笼统的抑制,比如
{
mysupression
Memcheck:Addr4
obj:*
obj:*
obj:/some/path/libX.so
}
这将匹配 2 个且仅 2 个级别,然后是 libX.so 中的一个级别。
抑制语法相当简单,不支持负匹配之类的东西。