[Linux] DTrace update to 0.2

DTraceの最新版をULNに公開しました。これはversion 0.2で、別のプレビューという位置づけです。

Unbreakable Linux Network
http://linux.oracle.com/

お試し方法
ULNにサーバを登録し、以下のチャネルをサーバリストに追加して下さい。
ol6_x86_64_Dtrace_BETA
チャネルをサーバに登録したら、以下のRPMをインストールできます。
dtrace-modules-2.6.39-101.0.1.el6uek
dtrace-utils
kernel-uek-headers-2.6.39-101.0.1.el6uek.x86_64
kernel-uek-devel-2.6.39-101.0.1.el6uek.x86_64
kernel-uek-2.6.39-101.0.1.el6uek.x86_64
kernel-uek-firmware-2.6.39-101.0.1.el6uek.noarch
RPMをインストールしたら、サーバを次のカーネルで再起動します。
2.6.39-101.0.1.el6uek
DTraceモジュールは以下のディレクトリにインストールされています。
/lib/modules/2.6.39-101.0.1.el6uek.x86_64/kernel/drivers/dtrace

# cd /lib/modules/2.6.39-101.0.1.el6uek.x86_64/kernel/drivers/dtrace
# ls

dtrace.ko  dt_test.ko  profile.ko  sdt.ko  systrace.ko
DTraceモジュールを実行中のカーネルにロードします。
# modprobe dtrace 
# modprobe profile
# modprobe sdt
# modprobe systrace
# modprobe dt_test
DTraceコンパイラは /usr/sbin/dtrace にあります。数種類のREADMEファイルが /usr/share/doc/dtrace-0.2.4 にありますので、そちらで何ができて何ができないのか確認して下さい。

新機能
  • SDTプロバイダを実装し、カーネル内の静的プローブを提供しています。いくつかのプロセスプロバイダをこのリソースを使って実装しています。
不具合の修正
  • スタブベースのシステムコール(fork()、clone()、exit()、sigreturn()など)のsyscallトレースが機能するようになっています。
  • Dスクリプトでの不正なメモリアクセスによってoopsやpanicが発生しなくなりました。
  • Dスクリプトでのメモリの枯渇が原因で偽のoopsが発生しなくなりました。
  • いくつかのクラッシュを修正しました。
  • 算術的内部集計を修正し、quantize()を修正しました。
  • インストール済みヘッダを改善しました。
DTrace Test Suiteの観点では、ユーザ空間ならびにカーネルの両方をかなりカバーしています。チームのみんなに感謝します。

以下は出力および.dスクリプトのソースコードの例です。
activity.d    - this shows ongoing activity in terms of what program was executing, 
          what its parent is, and how long it ran. This makes use of the proc SDT provider.
pstrace.d     - this is similar but instead of providing timing, it lists ancestory
          of a process, based on whatever history is collected during the DTrace runtime 
          of this script.  This makes use of the proc SDT provider.
rdbufsize.d   - this shows quantised results for buffer sizes used in read syscalls, 
          i.e. it gives a statistical breakdown of sizes passed in the read() syscall, 
          which can be useful to see what buffer sizes are commonly used.

=====================
activity.d
=====================

#pragma D option quiet

proc:::create
{
    this->pid = *((int *)arg0 + 171);

    time[this->pid] = timestamp;
    p_pid[this->pid] = pid;
    p_name[this->pid] = execname;
    p_exec[this->pid] = "";
}

proc:::exec
/p_pid[pid]/
{
    p_exec[pid] = stringof(arg0);
}

proc:::exit
/p_pid[pid]&&  p_exec[pid] != ""/
{
    printf("%d: %s (%d) executed %s (%d) for %d msecs\n",
           timestamp, p_name[pid], p_pid[pid], p_exec[pid], pid,
           (timestamp - time[pid]) / 1000);
}

proc:::exit
/p_pid[pid]&&  p_exec[pid] == ""/
{
    printf("%d: %s (%d) forked itself (as %d) for %d msecs\n",
           timestamp, p_name[pid], p_pid[pid], pid,
           (timestamp - time[pid]) / 1000);

}


=============
pstrace.d
=============


#pragma D option quiet

proc:::create
{
    this->pid = *((int *)arg0 + 171);

    p_pid[this->pid] = pid;
    p_name[this->pid] = execname;
    p_exec[this->pid] = "";
    path[this->pid] = strjoin(execname, " -> ");
}

proc:::create
/p_pid[pid]/
{
    this->pid = *((int *)arg0 + 171);

    path[this->pid] = strjoin(path[pid], " -> ");
}

proc:::exec
/p_pid[pid]/
{
    this->path = basename(stringof(arg0));

    path[pid] = strjoin(p_name[pid], strjoin(" ->  ", this->path));
    p_exec[pid] = this->path;
}

proc:::exit
/p_pid[pid]&&  p_exec[pid] != ""/
{
    printf("%d: %s[%d] ->  %s[%d]\n",
           timestamp, p_name[pid], p_pid[pid], p_exec[pid], pid);

    p_name[pid] = 0;
    p_pid[pid] = 0;
    p_exec[pid] = 0;
    path[pid] = 0;
}

proc:::exit
/p_pid[pid]&&  p_exec[pid] == ""/
{
    printf("%d: %s[%d] ->  [%d]\n",
           timestamp, p_name[pid], p_pid[pid], pid);

    p_name[pid] = 0;
    p_pid[pid] = 0;
    p_exec[pid] = 0;
    path[pid] = 0;
}

proc:::create
/path[pid] != ""/
{
    this->pid = *((int *)arg0 + 171);

    p_name[this->pid] = path[pid];
}


==================
rdbufsize.d
==================

syscall::read:entry
{
    @["read"] = quantize(arg2);
}
まだCTFはサポートしていませんので、スクリプトはRAWメモリアクセスして、task_struct構造体のPIDフィールドにアクセスします。

this->pid = *((int *)arg0 + 171);

ここで、arg0はtask_struct構造体へのポインタです(新しいタスク/スレッド/プロセスが生成されると、arg0はproc:::createプローブに渡されます)。

このスクリプトをカット&ペーストしてテキストファイルにし、実行すると、以下のような出力結果を得ます。
activity.d (here I just run some commands in a separate shell which then shows in the output)
dtrace -s activity.d 
  2134889238792594: automount (1736) forked itself (as 11484) for 292 msecs
2134912932312379: bash (11488) forked itself (as 11489) for 1632 msecs
2134912934171504: bash (11488) forked itself (as 11491) for 1319 msecs
2134912937531743: bash (11488) forked itself (as 11493) for 2150 msecs
2134912939231853: bash (11488) forked itself (as 11496) for 1366 msecs
2134912945152337: bash (11488) forked itself (as 11499) for 1135 msecs
2134912948946944: bash (11488) forked itself (as 11503) for 1285 msecs
2134912923230099: sshd (11485) forked itself (as 11486) for 8790195 msecs
2134912932092719: bash (11489) executed /usr/bin/id (11490) for 1005 msecs
2134912945773882: bash (11488) forked itself (as 11501) for 328 msecs
2134912937325453: bash (11493) executed /usr/bin/tput (11495) for 721 msecs
2134912941951947: bash (11488) executed /bin/grep (11498) for 1418 msecs
2134912933963262: bash (11491) executed /bin/hostname (11492) for 804 msecs
2134912936358611: bash (11493) executed /usr/bin/tty (11494) for 626 msecs
2134912939035204: bash (11496) executed /usr/bin/dircolors (11497) for 789 msecs
2134912944986994: bash (11499) executed /bin/uname (11500) for 621 msecs
2134912946568141: bash (11488) executed /bin/grep (11502) for 1003 msecs
2134912948757031: bash (11503) executed /usr/bin/id (11504) for 796 msecs
2134913874947141: ksmtuned (1867) forked itself (as 11505) for 2189 msecs
2134913883976223: ksmtuned (11507) executed /bin/awk (11509) for 8056 msecs
2134913883854384: ksmtuned (11507) executed /bin/ps (11508) for 8122 msecs
2134913884227577: ksmtuned (1867) forked itself (as 11507) for 9025 msecs
2134913874664300: ksmtuned (11505) executed /bin/awk (11506) for 1307 msecs
2134919238874188: automount (1736) forked itself (as 11511) for 263 msecs
2134920459512267: bash (11488) executed /bin/ls (11512) for 1682 msecs
2134930786318884: bash (11488) executed /bin/ps (11513) for 7241 msecs
2134933581336279: bash (11488) executed /bin/find (11514) for 161853 msecs


pstrace.d (as daemons or shells/users execute binaries, they show up automatically)
# dtrace -s pstrace.d 
2134960378397662: bash[11488] ->  ps[11517]
2134962360623937: bash[11488] ->  ls[11518]
2134964238953132: automount[1736] ->  [11519]
2134965712514625: bash[11488] ->  df[11520]
2134971432047109: bash[11488] ->  top[11521]
2134973888279789: ksmtuned[1867] ->  [11522]
2134973897131858: ksmtuned ->  [11524] ->  awk[11526]
2134973896999204: ksmtuned ->  [11524] ->  ps[11525]
2134973897400622: ksmtuned[1867] ->  [11524]
2134973888019910: ksmtuned ->  [11522] ->  awk[11523]
2134981995742661: sshd ->  sshd ->  bash[11531] ->  [11532]
2134981997448161: sshd ->  sshd ->  bash[11531] ->  [11534]
2134982000599413: sshd ->  sshd ->  bash[11531] ->  [11536]
2134982002035206: sshd ->  sshd ->  bash[11531] ->  [11539]
2134982007815639: sshd ->  sshd ->  bash[11531] ->  [11542]
2134982011627125: sshd ->  sshd ->  bash[11531] ->  [11546]
2134981989026168: sshd ->  sshd[11529] ->  [11530]
2134982008472173: sshd ->  sshd ->  bash[11531] ->  [11544]
2134981995518210: sshd ->  sshd ->  bash ->  [11532] ->  id[11533]
2134982000393612: sshd ->  sshd ->  bash ->  [11536] ->  tput[11538]
2134982004531164: sshd ->  sshd ->  bash[11531] ->  grep[11541]
2134981997256114: sshd ->  sshd ->  bash ->  [11534] ->  hostname[11535]
2134981999476476: sshd ->  sshd ->  bash ->  [11536] ->  tty[11537]
2134982001865119: sshd ->  sshd ->  bash ->  [11539] ->  dircolors[11540]
2134982007610268: sshd ->  sshd ->  bash ->  [11542] ->  uname[11543]
2134982009271769: sshd ->  sshd ->  bash[11531] ->  grep[11545]
2134982011408808: sshd ->  sshd ->  bash ->  [11546] ->  id[11547]


rdbufsize.d (in another shell I just did some random read operations and this
shows a summary)
# dtrace -s rdbufsize.d 
dtrace: script 'rdbufsize.d' matched 1 probe
^C

  read                                              
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |                                         8        
               1 |                                         59       
               2 |                                         209      
               4 |                                         72       
               8 |                                         488      
              16 |                                         67       
              32 |                                         1074     
              64 |                                         113      
             128 |                                         88       
             256 |                                         384      
             512 |@@@                                      6582     
            1024 |@@@@@@@@@@@@@@@@@@                       44787    
            2048 |@                                        2419     
            4096 |@@@@@@@                                  16239    
            8192 |@@@@                                     10395    
           16384 |@@@@@@                                   14784    
           32768 |                                         427      
           65536 |                                         669      
          131072 |                                         143      
          262144 |                                         43       
          524288 |                                         46       
         1048576 |                                         92       
         2097152 |                                         196      
         4194304 |                                         0 

原文はこちら。
https://blogs.oracle.com/wim/entry/dtrace_update_to_0_2

0 件のコメント:

コメントを投稿