web-dev-qa-db-ja.com

プログラムでシンボルを見つけるためにperfを取得する方法

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でコンパイルされますが、他のツールで実行する場合も同様です。

25

この投稿はもう1年以上前のものですが、同じ問題が発生したときにGoogle検索結果の上部に表示されたので、ここで答えようと思いました。少し調べてみたところ、 この関連するStackOverflowの質問で与えられた回答 が非常に参考になりました。私のUbuntu Raringシステムでは、次のことを行いました。

  1. C++ソースを-gでコンパイルします(かなり明白ですが、デバッグシンボルが必要です)
  2. perfを実行

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

    このように、perfDWARF 2 デバッグ形式を処理できます。これは、Linuxでgccが使用する標準形式です。 -F 97パラメータは、サンプリングレートを97 Hzに下げます。デフォルトのサンプリングレートは私のシステムには明らかに大きすぎ、次のようなメッセージが表示されました。

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

    後でperf reportを呼び出すと、セグメンテーション違反で失敗します。サンプリングレートを下げると、すべてがうまくいきました。

  3. 前のステップでperf.dataファイルがエラーなしで生成されたら、perf reportなどを実行できます。個人的には、SVG視覚化を生成する FlameGraph ツールが好きです。
  4. その他の人々 は、

    echo 0 > /proc/sys/kernel/kptr_restrict
    

    カーネルシンボルが必要な場合は、rootも同様に役立ちます。

20
mindriot

私の場合、解決策は、以前のビルドからのキャッシュされたシンボルを含み、混乱を招くelfファイルを削除することでした。

〜/ .debug /フォルダーにあります

4
sotiris

オペレーティングシステムのネイティブ形式でデバッグ情報が生成されるように、必ずgcc(cc)とともに-gオプションを使用してプログラムをコンパイルしてください。以下を実行して、シンボルテーブルにデバッグシンボルが存在するかどうかを確認してください。

$objdump -t your-elf 
$readelf -a your-elf
$nm -a your-elf
1
New to Rails

いつでも '$ 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
phyrrus9

kptr_restrictの値はcat /proc/kallsymsで確認できます。結果のシンボルのアドレスがすべて0x000000の場合、コマンドecho 0 > sys/kernel/kptr_restrictで修正できます。この後、perf reportの望ましい結果が得られる場合があります

0
yzark

あなたの開発ホストマシンはどうですか? x86_64 OSも実行していますか?そうでない場合は、perfがクロスコンパイルされていることを確認してください。perfは、objdumpおよびツールチェーン内の他のツールに依存しているためです。

0
jumper

私もこの問題を抱えていて、ユーザー空間のシンボルはまったく見えませんでしたが、カーネルシンボルがいくつかありました。これはシンボルの読み込みの問題だと思いました。私が見つけることができるすべての可能な解決策を試した後、私はまだそれを機能させることができませんでした。

それから私はかすかにそれを覚えています

ulimit -u無制限

必要です。私が試したところ、それは魔法のように機能しました。

このWikiから、ファイル記述子を使用しすぎると、このコマンドが必要になることがわかりました。

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

私の最後のコマンドは

perfレコード-F 999 -g ./my_program

必要ありませんでした--call-graph

0
Bill Yan

prctl(PR_SET_NAME)を使用してプログラムの名前をオーバーライドした後、perfで同じ問題が発生しました

私が見ることができるようにあなたのケースはかなり似ています:

70.06%ints.rkt [不明]

実行したコマンド(racket)がperfのコマンドと異なります見た。

0
Nik_