Memory leaks Valgind:只有当内存确实丢失时,才使用非零退出代码

Memory leaks Valgind:只有当内存确实丢失时,才使用非零退出代码,memory-leaks,valgrind,exit-code,Memory Leaks,Valgrind,Exit Code,我们使用valgrind作为CI流程的一部分。如果存在一些内存问题,valgrind必须返回非零代码,并报告此事件。我们是这样运行的: valgrind--error exitcode=1--tool=memcheck--leak check=full\ --泄漏类型的错误=确定--显示泄漏类型=确定\ --track origins=是。/some\u cgo\u应用程序 (...) ==25182==堆摘要: ==25182==在出口处使用:34296块中的2416970字节 ==25182

我们使用
valgrind
作为CI流程的一部分。如果存在一些内存问题,
valgrind
必须返回非零代码,并报告此事件。我们是这样运行的:

valgrind--error exitcode=1--tool=memcheck--leak check=full\
--泄漏类型的错误=确定--显示泄漏类型=确定\
--track origins=是。/some\u cgo\u应用程序
(...)
==25182==堆摘要:
==25182==在出口处使用:34296块中的2416970字节
==25182==总堆使用率:83979个allocs,49684个frees,分配5168335个字节
==25182== 
==25182==泄漏汇总:
==25182==肯定丢失:0个块中有0个字节
==25182==间接丢失:0个块中有0个字节
==25182==可能丢失:7个块中的3024字节
==25182==仍可访问:34289个块中的2413946字节
==25182==其中可通过启发式访问:
==25182==newarray:1个块中的520字节
==25182==抑制:0个块中有0个字节
==25182==未显示可访问块(找到指针的块)。
==25182==若要查看它们,请重新运行:--leak check=full--show leak kinds=all
==25182== 
==25182==对于检测到的和抑制的错误计数,请使用:-v重新运行
==25182==错误摘要:来自5个上下文的20个错误(已抑制:来自0的0)
目前,我们只对肯定丢失的
内存感兴趣
。如果没有明确丢失的块,
valgrind
的退出代码预计为零。但是,它返回
1
,尽管有选项
--errors for leak types=definite--show leak types=definite

echo$?
1.

是否还有其他选项有助于实现预期结果?

我怀疑退出状态1来自程序本身。我可以用以下方法再现这一点:

$ valgrind --error-exitcode=1 --tool=memcheck --leak-check=full \
  --errors-for-leak-kinds=definite --show-leak-kinds=definite \
  --track-origins=yes /bin/false
这看起来不像是可以在当前来源中更改的内容:

   case VgSrc_ExitProcess: /* the normal way out (Darwin) */
      /* Change the application return code to user's return code,
         if an error was found */
      if (VG_(clo_error_exitcode) > 0 
          && VG_(get_n_errs_found)() > 0) {
         VG_(client_exit)( VG_(clo_error_exitcode) );
      } else {
         /* otherwise, return the client's exit code, in the normal
            way. */
         VG_(client_exit)( VG_(threads)[tid].os_state.exitcode );
      }
这个
exitcode
成员是从
corefrind/m\u syswrap/syswrap linux.c
中的
sys\u exit\u组
包装器中设置的,没有任何方法对其进行调整

考虑到这一点,我认为您的最佳选择(无需修补valgrind)是选择与您的程序可能使用的任何退出状态不同的退出状态,并将其用作valgrind错误的指示器。

请查看--gen suppressions选项。有了它,您可以创建一个文件,告诉valgrind抑制特定于调用堆栈的可能丢失和仍然可访问的错误。使用此文件,使用--supressions=filename重新运行valgrind。现在valgrind($?)的返回值将为零。下面是一个例子:

valgrind --gen-suppressions=auto --log-file=suppressions.supp ./path/to/program
<open suppressions.supp, delete all lines that are not suppressions, save, and close>
valgrind --suppressions=suppressions.supp ./path/to/program
echo $?
valgrind--gen suppressions=auto--log file=suppressions.supp./path/to/program
valgrind--suppressions=suppressions.supp./path/to/program
回声$?
你应该看到零打印

这不会证明您的代码是否存在新的、可能丢失的和仍然可以访问的错误,但它会删除当前的错误。如果您想对代码进行未来验证,可以编写一个脚本来解析--gen suppressions=auto的输出,并生成一个新的suppressions文件。可以创建脚本,使其仅添加对可能丢失和仍然可以访问的错误的抑制,这样您仍然可以看到您关心的错误