根据gperftools文档,可以使用以下任何方法启动探查器:
CPUPROFILE环境变量设置为将保存配置文件信息的文件名CPUPROFILESIGNAL和发送适当的信号以启动或停止采样.ProfilerStart(filename)和ProfileStop()从您的代码直接所有这三种方法都需要libprofiler.so链接.
当我尝试这个时,第三种方法有效,但是当我只是设置时CPUPROFILE,没有生成分析信息.
不起作用:
$ cat foo.c
#include <stdio.h>
int main(void) {
printf("Hello, world!\n");
}
$ gcc foo.c -std=c99 -lprofiler -g && CPUPROFILE=foo.prof ./a.out
Hello, world!
$ ls foo.prof
ls: cannot access foo.prof: No such file or directory
Run Code Online (Sandbox Code Playgroud)
工作:
$ cat bar.c
#include <stdio.h>
#include <gperftools/profiler.h>
int main(void) {
ProfilerStart("bogus_filename");
printf("Hello, world!\n");
ProfilerStop();
}
$ gcc -std=c99 bar.c -lprofiler -g && CPUPROFILE=foo.prof ./a.out
Hello, world!
PROFILE: interrupts/evictions/bytes = 0/0/64
$ ls foo.prof
foo.prof
$ ls bogus_filename
ls: cannot access bogus_filename: No such file or directory
$ ./a.out
Hello, world!
PROFILE: interrupts/evictions/bytes = 0/0/64
$ ls bogus_filename
bogus_filename
Run Code Online (Sandbox Code Playgroud)
请注意,CPUPROFILE正在读取它,因为它的值会覆盖传递给ProfileStart()if if 的文件名.
解决这个问题所需的所有信息都分散在Stack Overflow中,但将它放在一个地方会很有用,所以现在就是这样.我已经在解决这个问题时提到了我发现有用的答案,以防有人在寻找更多信息.
在gperftools中,用于CpuProfiler检查CPUPROFILE和调用的构造函数ProfilerStart(getenv("CPUPROFILE"))(如果已设置)(加上或减去其他一些条件).CpuProfiler声明A profiler.cc以确保调用该函数.[1]当然,这只会在libprofiler.so链接时发生.
以下代码显示了该问题:
$ cat baz.c
#include <stdlib.h>
#include <stdio.h>
#include <gperftools/profiler.h>
int main(void) {
volatile int i = 0;
if (i) ProfilerStop();
printf("Hello, world!\n");
return 0;
}
$ gcc -std=c99 baz.c -lprofiler -g && CPUPROFILE=foo.prof ./a.out
Hello, world!
PROFILE: interrupts/evictions/bytes = 0/0/64
Run Code Online (Sandbox Code Playgroud)
ProfileStop()实际上永远不会被调用,但由于它i是易失性的,编译器无法对其进行优化,因此链接器需要将libprofiler用于定义.默认情况下,-lprofiler只引入程序中实际出现的符号,在原始情况下它们都不是,所以它根本没有链接库,也CpuProfiler()从未被调用过.
修复是在链接之前将--no-as-needed标志传递给. [2]这导致它链接库,无论它是否在程序中使用它(ld手册页似乎表明这应该是默认行为,但它不适用于我).该则标志传递给将它关闭,一旦我们已经加载了我们所需要的.(顺便说一句,似乎是静态库的等价选项[3])ldlibprofiler.so--as-needed--whole-archive
用于使分析工作原始文件的编译命令:
$ gcc -std=c99 foo.c -Wl,--no-as-needed,-lprofiler,--as-needed -g && CPUPROFILE=foo.prof ./a.out
Hello, world!
PROFILE: interrupts/evictions/bytes = 0/0/64
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2024 次 |
| 最近记录: |