• dwarf是怎样处理的栈帧?


    dwarf是如何处理的栈帧呢?

    首先看下非dwarf的情况是如何处理栈帧的:

    1 3623804982590 0x3e90 [0xb0]: PERF_RECORD_SAMPLE(IP, 0x1): 18561/18561: 0xffffffff8109dc91 period: 1 addr: 0
    ... FP chain: nr:12
    .....  0: ffffffffffffff80
    .....  1: ffffffff8109dc91
    .....  2: ffffffff818244f2
    .....  3: fffffffffffffe00
    .....  4: 00007f54cc7c421f
    .....  5: 0000000000400598
    .....  6: 00000000004005b0
    .....  7: 00000000004005d6
    .....  8: 0000000000400663
    .....  9: 0000000000400689
    ..... 10: 00007f54cc717830
    ..... 11: 075e258d4c544155
     ... thread: sleepFStack:18561
     ...... dso: /usr/lib/debug/boot/vmlinux-4.4.0-21-generic
    

     我们可以看到,这里的0x400689,0x400664,0x4005b0都是栈中的下一跳ip的地址,但是对于dwarf的格式,中间却没有任何的用户栈的信息

    1754 1 3984822066633 0x3e80 [0x80]: PERF_RECORD_SAMPLE(IP, 0x1): 18648/18648: 0xffffffff8109dc91 period: 1 addr: 0
    1755 ... FP chain: nr:6
    1756 .....  0: ffffffffffffff80
    1757 .....  1: ffffffff8109dc91
    1758 .....  2: ffffffff818244f2
    1759 .....  3: fffffffffffffe00
    1760 .....  4: 00007f3b642d521f
    1761 .....  5: 074e258d4c544155
    1762  ... thread: sleep:18648
    1763  ...... dso: /usr/lib/debug/boot/vmlinux-4.4.0-21-generic
    

     可见中间毫无用户态的栈出现,dwarf到底是怎样解析的用户栈?难道dwarf只有抓用户实践的时候才能抓到栈吗?

     发生了奇妙的事情,当我的事件检测点是内核态的函数的时候,没有用户的数据,但是我以系统默认的branches指令输出的时候,就还有,通过lbr也可以,但是为啥就是通过dwarf的时候没有调用栈呢?

    20821 11054598445494 0x47c50 [0x20e8]: PERF_RECORD_SAMPLE(IP, 0x4002): 13865/13865: 0x400577 period: 338726 addr: 0
    20822 ... FP chain: nr:0
    20823 ... user regs: mask 0xff0fff ABI 64-bit
    20824 .... AX    0xece3f
    20825 .... BX    0x0
    20826 .... CX    0x0
    20827 .... DX    0xece3f
    20828 .... SI    0x27
    20829 .... DI    0x17
    20830 .... BP    0x4006e0
    20831 .... SP    0x7ffdc56a5130
    20832 .... IP    0x400577
    20833 .... FLAGS 0x29f
    20834 .... CS    0x33
    20835 .... SS    0x2b
    20836 .... R8    0x400750
    20837 .... R9    0x7fbb18dd1ab0
    20838 .... R10   0x846
    20839 .... R11   0x7fbb18a17740
    20840 .... R12   0x400470
    20841 .... R13   0x7ffdc56a5390
    20842 .... R14   0x0
    20843 .... R15   0x0
    20844 ... ustack: size 3792, offset 0xd8 <--------------------然后直接把user stack给打印出来了!!!!!!

    20845  ... thread: sleep:13865
    20846  ...... dso: /home/hon/codebox/gcc/sleep

     从上面看,用户应该是有,用cycles事件去抓取数据时,是有用户态寄存器处理的,并且,然后就是根据寄存器的值去分析栈帧了,首先会得到栈的起始地址,然后是直接把user_stack给打印出来了!!!可以看一个具体的例子,在这个例子中我们通过看perf收集的裸的数据,就知道dwarf方式的内容的是怎么来的啦!所以这个也是在一定程序上说明了为啥同样的程序,我使用perf record -e --call-graph dwarf抓的时候,抓出来的数据会大很多,那不就是用户态的栈么!!!!因为当有frame pointer的时候,栈直接在用户态解析好,但是如果没有frame pointer,那么我会dump出来整个用户态的栈!!所以能用fp就用fp!!!

    有了这样一层的考虑,所以内核基本上是不允许在tracepoint当使用 --call-graph dwarf选项时是不允许在tp事件上抓取的,但是硬件事件就不同了,因为他们是异步的,并不会直接阻塞到程序的执行,所以本质上不会干扰到程序的执行?

    不是这样的考虑,因为事件是发生在了内核态,当发生用户态的事情的时候,我们发现竟然。。。。。

     仍然是没有用户栈的信息呀!但是现在的问题是所有的问题都交给了用户态,但是为啥就没有解析出来呢?

  • 相关阅读:
    19年春第六周学习
    Java编程思想
    个人作业4-结对开发地铁
    Hadoop学习笔记—1.基本介绍与环境配置
    ZooKeeper学习第二期--ZooKeeper安装配置
    ZooKeeper学习第一期---Zookeeper简单介绍
    loadrunner--参数化—使用数据文件参数化
    loadrunner--analysis--图表筛选、合并、显示
    loadrunner--并发测试
    session和cookie
  • 原文地址:https://www.cnblogs.com/honpey/p/9315817.html
Copyright © 2020-2023  润新知