DTraceにて関数の引数の確認をする方法

Q DTraceにて、probeの関数の引数を確認する方法ありますか?

A: 実は、Optionをつけると簡単に確認することができます。

-vオプションを使うと簡単に確認できます。

 # dtrace -lvn 'io:::start'
   ID   PROVIDER            MODULE                          FUNCTION NAME
16455         io           genunix                    default_physio start

        Probe Description Attributes
                Identifier Names: Private
                Data Semantics:   Private
                Dependency Class: Unknown

        Argument Attributes
                Identifier Names: Evolving
                Data Semantics:   Evolving
                Dependency Class: ISA

        Argument Types
                args[0]: bufinfo_t \*
                args[1]: devinfo_t \*
                args[2]: fileinfo_t \*


Stable Providerの場合、/usr/lib/dtrace以下にファイルに定義が書いてあるので、わかります。
例えば、上記のbufinfo_tやdevinfo_tなどは、/usr/lib/dtrace/io.dに定義されております。

args[2]であれば、以下のような情報をとります。

#/usr/lib/dtrace/io.dに定義してあります。

 typedef struct fileinfo {
        string fi_name;                 /\* name (basename of fi_pathname) \*/
        string fi_dirname;              /\* directory (dirname of fi_pathname) \*/
        string fi_pathname;             /\* full pathname \*/
        offset_t fi_offset;             /\* offset within file \*/
        string fi_fs;                   /\* filesystem \*/
        string fi_mount;                /\* mount point of file system \*/
        int fi_oflags;                  /\* open(2) flags for file descriptor \*/
} fileinfo_t;


カーネルのケースであれば、下記のようになります。

  # dtrace -lvn 'fbt:ufs:ufs_read:entry'
   ID   PROVIDER            MODULE                          FUNCTION NAME
40687        fbt               ufs                          ufs_read entry

        Probe Description Attributes
                Identifier Names: Private
                Data Semantics:   Private
                Dependency Class: Unknown

        Argument Attributes
                Identifier Names: Private
                Data Semantics:   Private
                Dependency Class: ISA

        Argument Types
                args[0]: struct vnode \*
                args[1]: struct uio \*
                args[2]: int
                args[3]: struct cred \*
                args[4]: struct caller_context \*

上記のような構造体をとることになります。

または、mdbにて、

 # mdb -k
Loading modules: [ unix genunix specfs dtrace xpv_psm scsi_vhci ufs ip hook neti sctp arp usba uhci s1394 nca fctl lofs zfs random audiosup md crypto smbsrv nfs fcip fcp logindmux ptm nsctl sdbc sv ii sppp nsmb rdc ipc ]
> ufs_read::nm -f ctype
C Type                                           
int (\*)(struct vnode \*, struct uio \*, int, struct cred \*, struct caller_context \*)

では、どうやって、これから解析を進めていくかというと、とりあえず、アドレスを出します。

# dtrace -n 'fbt:ufs:ufs_read:entry{printf("%a,%a,%a\\n",arg0,arg1,arg2);}'
dtrace: description 'fbt:ufs:ufs_read:entry' matched 1 probe
CPU     ID                    FUNCTION:NAME
  0  40687                   ufs_read:entry 0xffffff013da2dbc0,0xffffff0003cb5a80,0x0

それから、上記のアドレスをmdbでくわせて、struct vnodeを追ってみましょう。

# echo "0xffffff013da2dbc0::print -t vnode_t" | mdb -k
{
    kmutex_t v_lock = {
        void \*[1] _opaque = [ 0 ]
    }
    uint_t v_flag = 0x11000
    uint_t v_count = 0x1
    void \*v_data = 0xffffff013d95f838
    struct vfs \*v_vfsp = root
    struct stdata \*v_stream = 0
    enum vtype v_type = 1 (VREG)
    dev_t v_rdev = 0xffffffffffffffff
    struct vfs \*v_vfsmountedhere = 0
    struct vnodeops \*v_op = 0xffffff0131345180
    struct page \*v_pages = 0xffffff0002611e18
    pgcnt_t v_npages = 0
    pgcnt_t v_msnpages = 0
    struct page \*v_scanfront = 0
    struct page \*v_scanback = 0
    struct filock \*v_filocks = 0
    struct shrlocklist \*v_shrlocks = 0
    krwlock_t v_nbllock = {
        void \*[1] _opaque = [ 0 ]
    }
    kcondvar_t v_cv = {
        ushort_t _opaque = 0
    }
    void \*v_locality = 0
    struct fem_head \*v_femhead = 0
    char \*v_path = 0xffffff013d88ecc0 "/usr/bin/locale"
    uint_t v_rdcnt = 0x34
    uint_t v_wrcnt = 0
    u_longlong_t v_mmap_read = 0
    u_longlong_t v_mmap_write = 0
    void \*v_mpssdata = 0
    hrtime_t v_scantime = 0
    ushort_t v_mset = 0
    uint_t v_msflags = 0
    struct vnode \*v_msnext = 0
    struct vnode \*v_msprev = 0
    krwlock_t v_mslock = {
        void \*[1] _opaque = [ 0 ]
    }
    void \*v_fopdata = 0
    struct vsd_node \*v_vsd = 0
    struct vnode \*v_xattrdir = 0
}

といった感じで、かなり深くカーネルの構造を調べることができます。


Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

This blog is talked about OpenSolaris Community Activity and Bencmarking Test, which are my job.

Search

Archives
« April 2015
SunMonTueWedThuFriSat
   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  
       
Today