【问题标题】:dtrace execute action only when the function returns to a specific moduledtrace 仅在函数返回特定模块时执行操作
【发布时间】:2013-07-08 17:54:09
【问题描述】:

我正在使用 dtrace 跟踪一些 libc 函数。我想做一个谓词,仅在函数返回到参数中给定的特定模块的地址时才执行操作。

返回探针上的copyin(uregs[R_ESP],1) 应该给出我认为的返回地址,我不完全确定,所以如果有人能确认会很好。

但是我需要一种方法来将该地址解析为模块,这可能吗?如何实现?

【问题讨论】:

    标签: dtrace


    【解决方案1】:

    有一个ucaller 变量可以为您提供 将程序计数器保存为 uint64_tumod() 将 将其翻译成相应的模块名称,例如

    # dtrace -n 'pid$target:::entry {@[umod(ucaller)]=count()}' -p `pgrep -n xscreensaver`
    dtrace: description 'pid$target:::entry ' matched 14278 probes
    ^C
    
      xscreensaver                                                     16
      libXt.so.4                                                       73
      libX11.so.4                                                      92
      libxcb.so.1                                                     141
      libc.so.1                                                       144
    ^C# 
    

    但是,umod() 是一个动作(相对于子程序);它 不能分配给左值,因此不能用于 一个表达式(因为翻译被推迟到地址 由 dtrace(1) 用户级程序接收)。

    幸运的是,没有什么能阻止您找到地址 libc 在您的进程中占用的范围并将其与ucaller 进行比较。 这是 Solaris 上的一个示例(其中特定于硬件的 libc 是 在启动时安装):

    # mount | fgrep libc
    /lib/libc.so.1 on /usr/lib/libc/libc_hwcap1.so.1 read/write/setuid/devices/rstchown/dev=30d0002 on Sat Jul 13 20:27:32 2013
    # pmap `pgrep -n gedit` | fgrep libc_hwcap1.so.1
    FEE10000    1356K r-x--  /usr/lib/libc/libc_hwcap1.so.1
    FEF73000      44K rwx--  /usr/lib/libc/libc_hwcap1.so.1
    FEF7E000       4K rwx--  /usr/lib/libc/libc_hwcap1.so.1
    #
    

    我假设文本部分是只有 读取和执行权限,但请注意,在某些 文本部分可写的情况。

    # cat Vision.d 
    /*
     * self->current is a boolean indicating whether or not execution is currently
     * within the target range.
     *
     * self->next is a boolean indicating whether or not execution is about to
     * return to the target range.
     */
    BEGIN
    {
        self->current = 1;
    }
    
    pid$target:::entry
    {   
        self->current = (uregs[R_PC] >= $1 && uregs[R_PC] < $2);
    }
    
    syscall:::return
    /pid==$target/
    {
        self->next = self->current;
        self->current = 0;
    }
    
    pid$target:::return
    {
        self->next = (ucaller >= $1 && ucaller < $2);
    }
    
    pid$target:::return,syscall:::return
    /pid==$target && self->next && !self->current/
    {
        printf("Returning to target from %s:%s:%s:%s...\n",
            probeprov, probemod, probefunc, probename);
        ustack();
        printf("\n");
    }
    
    pid$target:::return,syscall:::return
    /pid==$target/
    {
        self->current = self->next;
    } 
    # dtrace -qs Vision.d 0xFEE10000 0xFEF73000 -p `pgrep -n gedit`
    

    这会产生类似的结果

    Returning to target from pid2095:libcairo.so.2.10800.10:cairo_bo_event_compare:return...
    
                  libcairo.so.2.10800.10`cairo_bo_event_compare+0x158
                  libc.so.1`qsort+0x51c
                  libcairo.so.2.10800.10`_cairo_bo_event_queue_init+0x122
                  libcairo.so.2.10800.10`_cairo_bentley_ottmann_tessellate_bo_edges+0x2d
                  libcairo.so.2.10800.10`_cairo_bentley_ottmann_tessellate_polygon+0
                  .
                  .
                  .
    
    Returning to target from syscall::pollsys:return...
    
                  libc.so.1`__pollsys+0x15
                  libc.so.1`poll+0x81
                  libxcb.so.1`_xcb_conn_wait+0xb5
                  libxcb.so.1`_xcb_out_send+0x3b
                  libxcb.so.1`xcb_writev+0x65
                  libX11.so.4`_XSend+0x17c
                  libX11.so.4`_XFlush+0x30
                  libX11.so.4`XFlush+0x37
    

    【讨论】:

      猜你喜欢
      • 2013-12-23
      • 1970-01-01
      • 1970-01-01
      • 2014-09-11
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多