为什么 __nss_database_lookup 在我的数值 C++ 程序中花费了大部分时间

Tom*_*lis 7 c++ profiling

行分析输出google-pprof声称我的数值 C++ 程序的大部分运行时间都花费在一个名为的函数中__nss_database_lookup(见下文)。显然,该函数用于处理passwdUNIX 系统上的文件等内容。我的 C++ 程序应该只进行数值计算、分配内存以及传递一些自定义 C++ 数据类型。

这是怎么回事?该功能的出现是否是海市蜃楼,仅仅是google-pprof工作原理的产物?或者它实际上被调用并浪费了我的程序三分之二的运行时间?如果它被调用,那么调用它的可能是什么?我的 C++ 类中是否有错误地调用了它?我该如何追踪呢?

我正在使用 Ubuntu 20.04,g++-7并且g++-9.

Total: 1046 samples
     665  63.6%  63.6%      665  63.6% __nss_database_lookup ??:0
     107  10.2%  73.8%      193  18.5% <function1> file.h:1035
      92   8.8%  82.6%       92   8.8% <function2> file.h:...
      87   8.3%  90.9%       87   8.3% <function3> file.h:995
      17   1.6%  92.5%      734  70.2% <function4> file.h:1128
...
Run Code Online (Sandbox Code Playgroud)

(出于保密原因,函数和文件名被隐藏)

zsr*_*myn 16

我的一个朋友今天也遇到了类似的问题。虽然你提出这个问题已经有一段时间了,但我仍然想回答一下,以便其他到达这里的人可以得到一些提示。

这是因为调用了一些局部符号(相当于C/C++中的静态局部函数),而这些符号在符号表中没有条目,它们的文本(代码)放在__nss_database_lookup. 所以你的 perf 工具将它们视为__nss_database_lookup.

例如,你的程序可能会调用memcpy, 并memcpy调用,它是 glibc 中的本地符号,并且没有在动态符号表中导出,并且它的代码恰好与其他本地符号__memmove_unaligned_avx_erms放在一起。__nss_database_lookup而你的 perf 工具找不到任何关于 的信息__memmove_unaligned_avx_erms,所以它只是认为__nss_database_lookup被调用。

一个潜在的解决方案是安装 libc-dbg 软件包(软件包名称可能因不同发行版而异),如果您的 perf 工具足够智能,可以自动加载调试信息,它可能会正确注释符号。(我的朋友检查过它对perf工具有一些影响)