使用带有排序的 gperftools 时分析计时器已过期

Posted

技术标签:

【中文标题】使用带有排序的 gperftools 时分析计时器已过期【英文标题】:Profiling timer expired when using gperftools with sort 【发布时间】:2017-02-03 12:37:09 【问题描述】:

我花了一整天的时间试图让gperftools 工作:/

我厌倦了不同的 libunwind 版本,但是当我成功安装它时,每当我使用 std::system 时,都会收到以下错误“Profiling timer expired”。

main.cpp:

#include <cstdlib>
int main(int argc, char** argv) 
    std::system("cut -f1 anyExistingFile | sort > newSortedFile");
    return 0;

我厌倦了执行如下分析:

$ g++ main.cpp -o myApp -std=c++11
$ env CPUPROFILE=out.prof    LD_PRELOAD="/usr/local/lib/libprofiler.so" ./myApp
Profiling timer expired
PROFILE: interrupts/evictions/bytes = 0/0/64

然后我做了:

$ env LD_PRELOAD="/usr/local/lib/libprofiler.so" 
$ sort file
$ env LD_PRELOAD=
$ sort file

当我将 LD_PRELOAD 设置为“/usr/local/lib/libprofiler.so”时,排序不起作用!

然后我尝试使用库的静态版本:

$ g++ main.cpp -o myApp -std=c++11 /usr/local/lib/libtcmalloc_and_profiler.a
$ env CPUPROFILE=out.prof ./myApp

什么也没发生,out.prof 也没有创​​建!

所以我想知道为什么我在使用 std::system(sort) 时得到“分析计时器已过期”?它是使用 gperftools 库的静态版本的正确方法吗?

P.S:64 位,gperftools=2.5,libunwind=1.1,linux Ubuntu 16.04.1

【问题讨论】:

【参考方案1】:

问题似乎在于,当您设置 LD_PRELOAD 时,实际上是为当前 shell 工作中的所有内容设置了它,包括您的程序产生的子进程。 CPUPROFILE 环境变量也是如此。因此 cpu profiler 也被激活以进行排序。看起来排序程序中的某些东西正在将 SIGPROF 信号处理程序重置为默认值,而没有实际重置相应的间隔计时器。因此,当 sort 完成足够的工作时,它会收到信号并且默认处理程序退出程序。简单的解决方法是在您的排序程序周围取消设置 CPUPROFILE。例如:

#include <cstdlib>
int main(int argc, char** argv) 
    std::system("cut -f1 /usr/share/dict/american-english-insane | CPUPROFILE='' sort  > /tmp/insane");
    return 0;

至于为什么静态链接不起作用,那是因为您的程序中没有任何东西可以提取分析器符号,因此实际上变成了无操作 w.r.t。分析。

【讨论】:

以上是关于使用带有排序的 gperftools 时分析计时器已过期的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 应用程序运行时分析所有变量的内存使用情况

使用FreeRTOS进行性能和运行时分析

干货推荐:使用 Apache Kafka 和微服务实时分析 Twitter 趋势第一部分

IIS ajax CORS 访问发送自定义Header时分析

新闻网大数据实时分析可视化系统项目——10数据采集/存储/分发完整流程测试

新闻网大数据实时分析可视化系统项目——12Hive与HBase集成进行数据分析