我怎样才能在程序中找到符号

问题描述 投票:0回答:8

使用

perf report
时,我没有看到程序的任何符号,而是得到如下输出:

$ perf record /path/to/racket ints.rkt 10000
$ perf report --stdio

# Overhead   Command      Shared Object  Symbol
# ........  ........  .................  ......
#
    70.06%  ints.rkt  [unknown]          [.] 0x5f99b8        
    26.28%  ints.rkt  [kernel.kallsyms]  [k] 0xffffffff8103d0ca
     3.66%  ints.rkt  perf-32046.map     [.] 0x7f1d9be46650  

这是相当无信息的。

相关程序是用调试符号构建的,

sysprof
工具显示了适当的符号,Zoom也是如此,我认为它在幕后使用了
perf

请注意,这是在 x86-64 上,因此二进制文件是使用

-fomit-frame-pointer
编译的,但在其他工具下运行时也是如此。

linux performance perf
8个回答
39
投票

这篇文章已经有一年多了,但是当我遇到同样的问题时,它出现在我的谷歌搜索结果的顶部,所以我想我应该在这里回答它。经过更多搜索后,我发现此相关 StackOverflow 问题中给出的答案非常有帮助。在我的 Ubuntu Raring 系统上,我最终执行了以下操作:

  1. 使用

    -g
    编译我的C++源代码(相当明显,你需要调试符号)

  2. 运行

    perf

    record -g --call-graph dwarf -F 97 /path/to/my/program
    

    这样

    perf
    就能够处理 DWARF 2 调试格式,这是
    gcc
    在 Linux 上使用的标准格式。
    -F 97
    参数将采样率降低至 97 Hz。默认采样率对于我的系统来说显然太大,并导致出现如下消息:

    Warning:
    Processed 172390 events and lost 126 chunks!
    
    Check IO/CPU overload!
    

    并且之后的

    perf report
    调用将因分段错误而失败。随着采样率的降低,一切都很好。

  3. 一旦在上一步中生成了

    perf.data
    文件并且没有任何错误,您就可以运行
    perf report
    等。我个人喜欢 FlameGraph 工具来生成 SVG 可视化。

  4. 其他人举报跑步

    echo 0 > /proc/sys/kernel/kptr_restrict
    

    如果需要内核符号,root 也可以提供帮助。


6
投票

在我的例子中,解决方案是删除 elf 文件,这些文件包含以前版本中的缓存符号,并且把事情弄乱了。

它们位于 ~/.debug/ 文件夹中


2
投票

我也遇到了这个问题,我看不到任何用户空间符号,但我看到了一些内核符号。我认为这是一个符号加载问题。在尝试了我能找到的所有可能的解决方案后,我仍然无法让它工作。

然后我依稀记得

ulimit -u 无限制

是需要的。我试过了,它神奇地起作用了。

我从这个wiki中发现,当你使用太多文件描述符时需要这个命令。

https://perf.wiki.kernel.org/index.php/Tutorial#Troubleshooting_and_Tips

我的最终命令是

性能记录-F 999 -g ./my_program

不需要--call-graph


1
投票

您始终可以使用“$ nm”命令。

这是一些示例输出:

Ethans-MacBook-Pro:~ phyrrus9$ nm a.out
0000000100000000 T __mh_execute_header
0000000100000f30 T _main
                 U _printf
0000000100000f00 T _sigint
                 U _signal
                 U dyld_stub_binder

0
投票

确保使用 -g 选项和 gcc(cc) 来编译程序,以便以操作系统的本机格式生成调试信息。 尝试执行以下操作并检查符号表中是否存在调试符号。

$objdump -t your-elf 
$readelf -a your-elf
$nm -a your-elf

0
投票

您可以通过

cat /proc/kallsyms
查看kptr_restrict的值。如果结果中符号的地址都是0x000000,可以通过命令
echo 0 > sys/kernel/kptr_restrict
修复。在此之后,您可能会得到想要的结果
perf report


-1
投票

您的开发主机怎么样?它也运行 x86_64 操作系统吗? 如果没有,请确保 perf 是交叉编译的,因为 perf 取决于 objdump 和工具链中的其他工具。


-1
投票

通过 prctl(PR_SET_NAME)

 覆盖我的程序名称后,我遇到了与 
perf

相同的问题

据我所知,您的情况非常相似:

70.06% ints.rkt [未知]

您执行的命令 (racket) 与 perf 看到的命令不同。

© www.soinside.com 2019 - 2024. All rights reserved.