プロフィール

kosaki

Author:kosaki
連絡先はコチラ

ブログ検索
最近の記事
最近のコメント
最近のトラックバック
リンク
カテゴリー
月別アーカイブ
RSSフィード
FC2ブログランキング

スポンサーサイト このエントリーをはてなブックマークに追加

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


スポンサー広告 | 【--------(--) --:--:--】 | Trackback(-) | Comments(-)

perf scripting support 入門 このエントリーをはてなブックマークに追加

Frederic Weisbecker がperf scripting入門を書いていたので転載
なお、Fedora13ではちゃんと動いたけど、Fedora12では動かなかった。依存ライブラリがかなり新しい者を要求してるっぽい。

I have the feeling you've made an ad-hoc post processing script that seems
to rewrite all the format parsing, debugfs, stream handling, etc... we
have that in perf tools already.

May be you weren't aware of what we have in perf in terms of scripting support.

First, launch perf list and spot the events you're interested in, let's
say you're interested in irqs:

$ perf list
[...]
irq:irq_handler_entry [Tracepoint event]
irq:irq_handler_exit [Tracepoint event]
irq:softirq_entry [Tracepoint event]
irq:softirq_exit [Tracepoint event]
[...]

Now do a trace record:

# perf record -e irq:irq_handler_entry -e irq:irq_handler_exit -e irq:softirq_entry -e irq:softirq_exit cmd

or more simple:

# perf record -e irq:* cmd

You can use -a instead of cmd for wide tracing.

Now generate a perf parsing script on top of these traces:

# perf trace -g perl
generated Perl script: perf-trace.pl


Fill up the trace handlers inside perf-trace.pl and just run it:

# perf trace -s perf-trace.pl

Once ready, you can place your script in the script directory.



意訳:

適当にとりたいトレースイベントを-e オプションで選んで、データ収集しろや。
データは perf.data ファイルに保存される。

# perf record -e 'irq:*'

-g オプションで選んだ -e を元に出力スクリプトのテンプレートが生成される

# perf trace -g perl

中身はこんなの

# perf trace event handlers, generated by perf trace -g perl
# Licensed under the terms of the GNU GPL License version 2

# The common_* event handler fields are the most useful fields common to
# all events. They don't necessarily correspond to the 'common_*' fields
# in the format files. Those fields not available as handler params can
# be retrieved using Perl functions of the form common_*($context).
# See Context.pm for the list of available functions.

use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
use lib "./Perf-Trace-Util/lib";
use Perf::Trace::Core;
use Perf::Trace::Context;
use Perf::Trace::Util;

sub trace_begin
{
# optional
}

sub trace_end
{
# optional
}

sub irq::softirq_exit
{
my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
$common_pid, $common_comm,
$vec) = @_;

print_header($event_name, $common_cpu, $common_secs, $common_nsecs,
$common_pid, $common_comm);

printf("vec=%s\n",
symbol_str("irq::softirq_exit", "vec", $vec));
}


sub irq::softirq_entry
{
my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
$common_pid, $common_comm,
$vec) = @_;

print_header($event_name, $common_cpu, $common_secs, $common_nsecs,
$common_pid, $common_comm);

printf("vec=%s\n",
symbol_str("irq::softirq_entry", "vec", $vec));
}

sub irq::irq_handler_exit
{
my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
$common_pid, $common_comm,
$irq, $ret) = @_;

print_header($event_name, $common_cpu, $common_secs, $common_nsecs,
$common_pid, $common_comm);

printf("irq=%d, ret=%d\n",
$irq, $ret);
}

sub irq::irq_handler_entry
{
my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
$common_pid, $common_comm,
$irq, $name) = @_;

print_header($event_name, $common_cpu, $common_secs, $common_nsecs,
$common_pid, $common_comm);

printf("irq=%d, name=%s\n",
$irq, $name);
}

sub trace_unhandled
{
my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
$common_pid, $common_comm) = @_;

print_header($event_name, $common_cpu, $common_secs, $common_nsecs,
$common_pid, $common_comm);
}

sub print_header
{
my ($event_name, $cpu, $secs, $nsecs, $pid, $comm) = @_;

printf("%-20s %5u %05u.%09u %8u %-20s ",
$event_name, $cpu, $secs, $nsecs, $pid, $comm);
}



これを適当にいじって、printの形式かえたり、引数によって出力させないとか、
好きにしろ。

それを trace -s すると、データを引数スクリプトで加工した出力が得られる

# perf trace -s perf-trace.pl


上記、irq:*のサンプル


[root@kosaopt tmp]# perf trace -s perf-trace.pl
irq::softirq_entry 3 1232482.338391992 3046 ls vec=TIMER
irq::softirq_exit 3 1232482.338394889 3046 ls vec=TIMER
irq::softirq_entry 3 1232482.339389340 3046 ls vec=TIMER
irq::softirq_exit 3 1232482.339395908 3046 ls vec=TIMER
irq::softirq_entry 3 1232482.339397522 3046 ls vec=RCU
irq::softirq_exit 3 1232482.339400024 3046 ls vec=RCU




ところで、現在スクリプトがperlとpythonしか選べないという問題がある。だれかruby対応をRubyKaigiまでに
終わらせてしまってサプライズイベントを発表しようとかいう猛者はおらんか。

関連記事


linux | 【2010-07-31(Sat) 20:15:48】 | Trackback:(0) | Comments:(1)
コメント
Rubyの場合のテンプレはこんな感じですか分かりません><
# インデントを実現するための の置き換えが大変でした……

def trace_begin
  # optional
end

def trace_end
  # optional
end

module IRQ
  module_functions
  def softirq_exit(event_name, context, common_cpu, common_secs,
                   common_nsecs, common_pid, common_comm, vec)

    print_header(event_name, common_cpu, common_secs, common_nsecs,
                 common_pid, common_comm)

    printf("vec=%sn",
           Perf::Trace.symbol_str("irq::softirq_exit", "vec", vec))
  end

  def softirq_entry(event_name, context, common_cpu, common_secs,
                    common_nsecs, common_pid, common_comm, vec)

    print_header(event_name, common_cpu, common_secs, common_nsecs,
                 common_pid, common_comm)

    printf("vec=%sn",
           Perf::Trace.symbol_str("irq::softirq_entry", "vec", vec))
  end
  
  def irq_handler_exit(event_name, context, common_cpu, common_secs,
                       common_nsecs, common_pid, common_comm, irq, ret)

    print_header(event_name, common_cpu, common_secs, common_nsecs,
                 common_pid, common_comm)

    printf("irq=%d, ret=%dn", irq, et)
  end
  
  def irq_handler_entry(event_name, context, common_cpu, common_secs,
                        common_nsecs, common_pid, common_comm, irq, name)

    print_header(event_name, common_cpu, common_secs, common_nsecs,
                 common_pid, common_comm)

    printf("irq=%d, name=%sn", irq, name)
  end
end

def trace_unhandled(event_name, context, common_cpu, common_secs,
                    common_nsecs, common_pid, common_comm)

  print_header(event_name, common_cpu, common_secs, common_nsecs,
               common_pid, common_comm)
end

def print_header(event_name, cpu, secs, nsecs, pid, comm)

  printf("%-20s %5u %05u.%09u %8u %-20s ",
         event_name, cpu, secs, nsecs, pid, comm)

end
2010-08-01 日 01:21:49 | URL | 斎藤ただし #9cg9ikIo [ 編集]
  1. 無料アクセス解析
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。