2017-10-17 6 views
0

(私はこれが動作するようになってかなりの時間を費やしてきたので、私は、私はそれを文書化しようと思いました - まず、質問として正式にそれを置くために):/トレース機能をプロービングsystemtapの簡単な例は、Systemtapシンプルなユーザー空間の例(関数トレース、Ubuntu)?

ありますユーザー空間アプリケーションで、好ましくはC++で?私のシステムは、Ubuntuの14.04である:

$ uname -a 
Linux mypc 4.2.0-42-generiC#49~14.04.1-Ubuntu SMP Wed Jun 29 20:22:11 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux 
$ g++ --version 
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4 ... 
$ stap --version 
Systemtap translator/driver (version 2.3/0.158, Debian version 2.3-1ubuntu1.4 (trusty)) 

答えて

2

OK、これは些細なことが判明していなかった - まず第一に、私は何とかのUbuntu 14.04上の(新しい)のカーネル4.2.0になってしまいました。明らかに、Ubuntu 14.04に付属のsystemtapは、そのカーネルにとっては古すぎます(下記参照)。それは私がソースからsystemtapを構築しなければならなかったことを意味します - これが私の手順だった:

cd /path/to/src 
git clone git://sourceware.org/git/elfutils.git elfutils_git 
git clone git://sourceware.org/git/systemtap.git systemtap_git 
cd systemtap_git 
./configure --with-elfutils=/path/to/src/elfutils_git --prefix=/path/to/src/systemtap_git/local --enable-docs=no 
make 
make install 
# after this, there are `stap` executables in: 
# /path/to/src/systemtap_git/stap 
# /path/to/src/systemtap_git/local/bin/stap 

これはものです:

  • あなたが別途elfutilsを構築し、その後、systemtapべきではない - あなたの代わりに渡す必要がありますelfutilsのソースディレクトリは、--with-elfutilssystemtapconfigureになります。それはconfigureになり、さらにelfutilsになります。
  • make installsystemtapでなければなりません(たとえそれが非システム/プライベート(ローカル)ディレクトリにあっても)! - それ以外の場合は、多少の誤差が発生構築した後

stapレポートバージョン(残念ながら、それらをログに記録しませんでした):

$ ./stap --version 
Systemtap translator/driver (version 3.2/0.170, commit release-3.1-331-g0efba6fc74c8 + changes) ... 

は、[OK]をので、私は、分析のための基本的なフィボナッチC++の例を、見つけたIわずかに変更された、と/tmp/fibo.cppと呼ばれる:

// based on: http://www.cplusplus.com/articles/LT75fSEw/ 
#include <iostream> 

using namespace std; 

class Fibonacci{ 
public: 
    int a, b, c; 
    void generate(int); 
    void doFibonacciStep(int); 
}; 

void Fibonacci::doFibonacciStep(int istep){ 
    c = a + b; 
    cout << " istep: " << istep << " c: " << c << endl; 
    a = b; 
    b = c; 
} 

void Fibonacci::generate(int n){ 
    a = 0; b = 1; 
    cout << " Start: a "<< a << " b " << b << endl; 
    for(int i=1; i<= n-2; i++){ 
    doFibonacciStep(i); 
    } 
} 

int main() 
{ 
    cout << "Hello world! Fibonacci series" << endl; 
    cout << "Enter number of items you need in the series: "; 
    int n; 
    cin >> n; 
    Fibonacci fibonacci; 
    fibonacci.generate(n); 
    return 0; 
} 

まず私はこのようにそれをコンパイルしてみました:

cd /tmp 
g++ -g fibo.cpp -o fibo.exe 

ここで最初に行うことは、実行可能ファイルでどの機能がプロービングに使用できるかを調べることです。そのために、我々はstap -L使用することができます(注を、ここで私はまだ古い、Ubuntuの14.04システムをstap使用しています):

$ stap -L 'process("/tmp/fibo.exe").function("*").call' 
process("/tmp/fibo.exe").function("_GLOBAL__sub_I__ZN9Fibonacci15doFibonacciStepEi").call 
process("/tmp/fibo.exe").function("__static_initialization_and_destruction_0").call $__initialize_p:int $__priority:int 
process("/tmp/fibo.exe").function("[email protected]/tmp/fibo.cpp:13").call $this:class Fibonacci* const $istep:int 
process("/tmp/fibo.exe").function("[email protected]/tmp/fibo.cpp:20").call $this:class Fibonacci* const $n:int 
process("/tmp/fibo.exe").function("[email protected]/tmp/fibo.cpp:28").call 

ニース - 私が探査したいと思いますので、/ doFibonacciStep、その入力引数をトレースし、 istep。だから私はコマンドラインから試してみる:

$ sudo stap -e 'probe process("/tmp/fibo.exe").function("Fibonacci::doFibonacciStep").call { printf("stap do step: %d\n", $istep) }' -c /tmp/fibo.exe 
WARNING: "__tracepoint_sched_process_fork" [/tmp/stap51A5tV/stap_ab5b824c79b38b5207910696c49c4e22_1760.ko] undefined! 
WARNING: "__tracepoint_sys_exit" [/tmp/stap51A5tV/stap_ab5b824c79b38b5207910696c49c4e22_1760.ko] undefined! 
WARNING: "__tracepoint_sys_enter" [/tmp/stap51A5tV/stap_ab5b824c79b38b5207910696c49c4e22_1760.ko] undefined! 
WARNING: "__tracepoint_sched_process_exec" [/tmp/stap51A5tV/stap_ab5b824c79b38b5207910696c49c4e22_1760.ko] undefined! 
WARNING: "__tracepoint_sched_process_exit" [/tmp/stap51A5tV/stap_ab5b824c79b38b5207910696c49c4e22_1760.ko] undefined! 
ERROR: Couldn't insert module '/tmp/stap51A5tV/stap_ab5b824c79b38b5207910696c49c4e22_1760.ko': Unknown symbol in module 
WARNING: /usr/bin/staprun exited with status: 1 
Pass 5: run failed. [man error::pass5] 
Tip: /usr/share/doc/systemtap/README.Debian should help you get started. 
$ sudo stap -e 'probe process("/tmp/fibo.exe").function("Fibonacci::doFibonacciStep").call { printf("stap do step: %d\n", $istep) }' -c /tmp/fibo.exe 
ERROR: Couldn't insert module '/tmp/stapmo60OW/stap_ab5b824c79b38b5207910696c49c4e22_1760.ko': Unknown symbol in module 
WARNING: /usr/bin/staprun exited with status: 1 
Pass 5: run failed. [man error::pass5] 

これらのようなエラーはうまくいかない。投稿"__tracepoint_sched_process_fork undefined" when run systemstap scriptは、基本的にstapのバージョンが、私が持っているカーネルにとっては古すぎると説明しています。それでは、今どのように新しいstap -L作品を見てみましょう:

$ /path/to/src/systemtap_git/stap -L 'process("/tmp/fibo.exe").function("*").call' 
process("/tmp/fibo.exe").function("[email protected]/tmp/fibo.cpp:37").call 
process("/tmp/fibo.exe").function("__do_global_dtors_aux").call 
process("/tmp/fibo.exe").function("__libc_csu_fini").call 
process("/tmp/fibo.exe").function("__libc_csu_init").call 
process("/tmp/fibo.exe").function("[email protected]/tmp/fibo.cpp:37").call $__initialize_p:int $__priority:int 
process("/tmp/fibo.exe").function("_fini").call 
process("/tmp/fibo.exe").function("_init").call 
process("/tmp/fibo.exe").function("_start").call 
process("/tmp/fibo.exe").function("deregister_tm_clones").call 
process("/tmp/fibo.exe").function("[email protected]/tmp/fibo.cpp:13").call $this:class Fibonacci* const $istep:int 
process("/tmp/fibo.exe").function("frame_dummy").call 
process("/tmp/fibo.exe").function("[email protected]/tmp/fibo.cpp:20").call $this:class Fibonacci* const $n:int 
process("/tmp/fibo.exe").function("[email protected]/tmp/fibo.cpp:28").call 
process("/tmp/fibo.exe").function("register_tm_clones").call 

ニースが、これはすでに、もう少し詳細な古いバージョンよりもです。とにかく、doFibonacciStep関数と入力引数($istep)を調査したいと思います。

$ sudo /path/to/src/systemtap_git/stap -e 'probe process("/tmp/fibo.exe").function("Fibonacci::doFibonacciStep").call { printf("stap do step: %d\n", $istep) }' -c /tmp/fibo.exe 
semantic error: while processing probe process("/tmp/fibo.exe").function("Fibonacci::[email protected]/tmp/fibo.cpp:13").call from: process("/tmp/fibo.exe").function("Fibonacci::doFibonacciStep").call 

semantic error: No cfa_ops supplied, but needed by DW_OP_call_frame_cfa: identifier '$istep' at <input>:1:107 
     source: probe process("/tmp/fibo.exe").function("Fibonacci::doFibonacciStep").call { printf("stap do step: %d\n", $istep) } 

Pass 2: analysis failed. [man error::pass2] 

痛い - 厄介なエラー、および本当に私には何も教えてくれない - このエラーの非常にいくつかのバグレポートは(と主に2010年から)があります。だから私は、コマンドラインでこれを書いてください。先日私が思いついたときに、私は-gdwarf-2でいくつかのプログラムをコンパイルしました(これは私が今忘れてしまった理由によるものです)。だから、私はそれを試してみると思っていました。そして今、実際に働いています。

​​

ニース! stapプリントは、の後、実際にはに印刷されます(つまり、実際のプログラム出力とインターリーブされません)。代わりに、コマンドラインで直接プローブポイントと動作を指定するので

することは、我々は代わりに、スクリプトを書くことができます - ので、ここでcheck-do-step.stpである - ここにいくつかの余分なものを持つ:

#!/usr/bin/env stap 

global stringone = "Testing String One" 
global stringtwo = "Testing String Two" 

probe begin { 
    printf("begin: %s\n", stringone) 
    #exit() # must have; else probe end runs only upon Ctrl-C if we only have `begin` and `end` probes! 
} 

probe process(
    "/tmp/fibo.exe" 
).function(
    "Fibonacci::doFibonacciStep" 
).call { 
    printf("stap do step: %d\n", $istep) 
} 

probe end { 
    newstr = "We Are " . stringtwo . " And We're Done" # string concat 
    printf("%s\n", newstr) 
} 

...と、このスクリプトで、私たちの呼び出しと結果は次のようになります。もう一度

$ sudo /path/to/src/systemtap_git/stap check-do-step.stp -c /tmp/fibo.exe 
Hello world! Fibonacci series 
Enter number of items you need in the series: begin: Testing String One 
6 
Start: a 0 b 1 
    istep: 1 c: 1 
    istep: 2 c: 2 
    istep: 3 c: 3 
    istep: 4 c: 5 
stap do step: 1 
stap do step: 2 
stap do step: 3 
stap do step: 4 
We Are Testing String Two And We're Done 

お知らせ - begin: Testing ...文字列は、私たちはそう期待して非常に開始時にヒットが、唯一のプログラムの後、すでに出力を生成し始めていません。

+0

DWARF関連のエラーは残念ですが、これは私にとっては十分です。現代のGCCは関数のパラメータを最適化する上で非常に優れていて、debuginfoに複雑な手がかりだけをどこに置いておくのかということだけが残っています。 Systemtapはすべてのトリックにはあまり慣れていません。 -gdwarf2はこれらの複雑な手がかりを省略します(ただし、交換すると、影響を受けるパラメータはスタップすることさえありません)。 – fche

関連する問題