vmcore查找refcount过程



crash7latest> bt -s 246346
PID: 246346  TASK: ffff880280345400  CPU: 0   COMMAND: "perfquery"
 #0 [ffff88015d1c3b38] __schedule+535 at ffffffff816b4fa7
 #1 [ffff88015d1c3b90] schedule+62 at ffffffff816b54fe
 #2 [ffff88015d1c3bb0] schedule_timeout+437 at ffffffff816b83e5
 #3 [ffff88015d1c3c50] wait_for_completion+271 at ffffffff816b6a2f
 #4 [ffff88015d1c3cd0] unregister_mad_agent+429 at ffffffffa02a988d [ib_mad]
 #5 [ffff88015d1c3d40] ib_unregister_mad_agent+169 at ffffffffa02a9989 [ib_mad]
 #6 [ffff88015d1c3d70] ib_umad_close+210 at ffffffffa03c5692 [ib_umad]
 #7 [ffff88015d1c3dc0] __fput+189 at ffffffff8120e3ad
 #8 [ffff88015d1c3e10] ____fput+14 at ffffffff8120e5ee
 #9 [ffff88015d1c3e20] task_work_run+213 at ffffffff810a6785
#10 [ffff88015d1c3e80] do_exit+519 at ffffffff8108b5b7
#11 [ffff88015d1c3f00] do_group_exit+86 at ffffffff8108b916
#12 [ffff88015d1c3f40] sys_exit_group+23 at ffffffff8108b9d7
#13 [ffff88015d1c3f50] system_call_fastpath+18 at ffffffff816b9894
    RIP: 00007f77c93dafa8  RSP: 00007ffd9b682b28  RFLAGS: 00000246
    RAX: ffffffffffffffda  RBX: 00007f77c96b8830  RCX: 00007f77c93dafa8
    RDX: ffffffffffffffff  RSI: 000000000000003c  RDI: ffffffffffffffff
    RBP: 00000000ffffffff   R8: 00000000000000e7   R9: ffffffffffffffa8
    R10: 00007f77c96bf828  R11: 0000000000000246  R12: 00007f77c96b8830
    R13: 000000000000ffff  R14: 0000000000608c80  R15: 00007ffd9b683320
    ORIG_RAX: 00000000000000e7  CS: 0033  SS: 002b

crash7latest> whatis wait_for_completion
void wait_for_completion(struct completion *);

wait_for_complete的参数是completion, 由于这个结构包含在那个priv中,所以找到它的地址也就找到了priv的地址。
要找到它就得反汇编wait_for_complete的父函数,看看参数是怎么传递的.

crash7latest> dis -r unregister_mad_agent+429
0xffffffffa02a96e0 :      push   %rbp
0xffffffffa02a96e1 :    mov    %rsp,%rbp
0xffffffffa02a96e4 :    push   %r15
0xffffffffa02a96e6 :    push   %r14
0xffffffffa02a96e8 :    push   %r13
0xffffffffa02a96ea :   push   %r12
0xffffffffa02a96ec :   push   %rbx
0xffffffffa02a96ed :   sub    $0x38,%rsp
0xffffffffa02a96f1 :   nopl   0x0(%rax,%rax,1)
0xffffffffa02a96f6 :   lea    0x68(%rdi),%r13
0xffffffffa02a96fa :   lea    -0x50(%rbp),%r12
0xffffffffa02a96fe :   mov    %rdi,%rbx
0xffffffffa02a9701 :   mov    %r13,%rdi
0xffffffffa02a9704 :   mov    %r12,-0x50(%rbp)
0xffffffffa02a9708 :   mov    %r12,-0x48(%rbp)
0xffffffffa02a970c :   callq  0xffffffff816b90f0 <_raw_spin_lock_irqsave>
0xffffffffa02a9711 :   mov    0x70(%rbx),%rdi
0xffffffffa02a9715 :   lea    0x70(%rbx),%r8
0xffffffffa02a9719 :   lea    -0x18(%rdi),%rdx
0xffffffffa02a971d :   cmp    %rdi,%r8
0xffffffffa02a9720 :   mov    0x18(%rdx),%rcx
0xffffffffa02a9724 :   je     0xffffffffa02a976c
0xffffffffa02a9726 :   sub    $0x18,%rcx
0xffffffffa02a972a :   jmp    0xffffffffa02a9737
0xffffffffa02a972c :   nopl   0x0(%rax)
0xffffffffa02a9730 :   mov    %rcx,%rdx
0xffffffffa02a9733 :   lea    -0x18(%rdi),%rcx
0xffffffffa02a9737 :   mov    0x128(%rdx),%edi
0xffffffffa02a973d :   test   %edi,%edi
0xffffffffa02a973f :   jne    0xffffffffa02a975f
0xffffffffa02a9741 :   xor    %edi,%edi
0xffffffffa02a9743 :   cmpq   $0x0,0x110(%rdx)
0xffffffffa02a974b :  movl   $0x5,0x128(%rdx)
0xffffffffa02a9755 :  setne  %dil
0xffffffffa02a9759 :  sub    %edi,0x124(%rdx)
0xffffffffa02a975f :  lea    0x18(%rcx),%rdx
0xffffffffa02a9763 :  mov    0x18(%rcx),%rdi
0xffffffffa02a9767 :  cmp    %rdx,%r8
0xffffffffa02a976a :  jne    0xffffffffa02a9730
0xffffffffa02a976c :  mov    0x80(%rbx),%rcx
0xffffffffa02a9773 :  lea    0x80(%rbx),%rdx
0xffffffffa02a977a :  cmp    %rcx,%rdx
0xffffffffa02a977d :  je     0xffffffffa02a97a7
0xffffffffa02a977f :  mov    -0x50(%rbp),%rsi
0xffffffffa02a9783 :  mov    0x88(%rbx),%rdi
0xffffffffa02a978a :  mov    %r12,0x8(%rcx)
0xffffffffa02a978e :  mov    %rcx,-0x50(%rbp)
0xffffffffa02a9792 :  mov    %rsi,(%rdi)
0xffffffffa02a9795 :  mov    %rdi,0x8(%rsi)
0xffffffffa02a9799 :  mov    %rdx,0x80(%rbx)
0xffffffffa02a97a0 :  mov    %rdx,0x88(%rbx)
0xffffffffa02a97a7 :  mov    %r13,%rdi
0xffffffffa02a97aa :  mov    %rax,%rsi
0xffffffffa02a97ad :  callq  0xffffffff816b8fe0 <_raw_spin_unlock_irqrestore>
0xffffffffa02a97b2 :  mov    -0x50(%rbp),%rdi
0xffffffffa02a97b6 :  movl   $0x5,-0x38(%rbp)
0xffffffffa02a97bd :  movl   $0x0,-0x34(%rbp)
0xffffffffa02a97c4 :  lea    -0x18(%rdi),%rax
0xffffffffa02a97c8 :  cmp    %r12,%rdi
0xffffffffa02a97cb :  mov    0x18(%rax),%r13
0xffffffffa02a97cf :  je     0xffffffffa02a9822
0xffffffffa02a97d1 :  lea    0x10(%rbx),%rdx
0xffffffffa02a97d5 :  sub    $0x18,%r13
0xffffffffa02a97d9 :  lea    0x168(%rbx),%r14
0xffffffffa02a97e0 :  lea    -0x40(%rbp),%r15
0xffffffffa02a97e4 :  mov    %rdx,-0x58(%rbp)
0xffffffffa02a97e8 :  jmp    0xffffffffa02a97f6
0xffffffffa02a97ea :  nopw   0x0(%rax,%rax,1)
0xffffffffa02a97f0 :  mov    %r13,%rax
0xffffffffa02a97f3 :  mov    %rdx,%r13
0xffffffffa02a97f6 :  add    $0x30,%rax
0xffffffffa02a97fa :  mov    %rax,-0x40(%rbp)
0xffffffffa02a97fe :  callq  0xffffffff81340e40
0xffffffffa02a9803 :  mov    %r15,%rsi
0xffffffffa02a9806 :  mov    -0x58(%rbp),%rdi
0xffffffffa02a980a :  callq  *0x30(%rbx)
0xffffffffa02a980d :  lock decl (%r14)
0xffffffffa02a9811 :  mov    0x18(%r13),%rax
0xffffffffa02a9815 :  lea    0x18(%r13),%rdi
0xffffffffa02a9819 :  cmp    %r12,%rdi
0xffffffffa02a981c :  lea    -0x18(%rax),%rdx
0xffffffffa02a9820 :  jne    0xffffffffa02a97f0
0xffffffffa02a9822 :  mov    0x60(%rbx),%rax
0xffffffffa02a9826 :  lea    0xa0(%rbx),%rdi
0xffffffffa02a982d :  mov    (%rax),%r12
0xffffffffa02a9830 :  callq  0xffffffff810a3d50
0xffffffffa02a9835 :  lea    0x38(%r12),%r13
0xffffffffa02a983a :  mov    %r13,%rdi
0xffffffffa02a983d :  callq  0xffffffff816b90f0 <_raw_spin_lock_irqsave>
0xffffffffa02a9842 :  mov    %rbx,%rdi
0xffffffffa02a9845 :  mov    %rax,%r14
0xffffffffa02a9848 :  callq  0xffffffffa02a8630
0xffffffffa02a984d :  mov    %rbx,%rdi
0xffffffffa02a9850 :  callq  0xffffffff81340e40
0xffffffffa02a9855 :  mov    %r14,%rsi
0xffffffffa02a9858 :  mov    %r13,%rdi
0xffffffffa02a985b :  callq  0xffffffff816b8fe0 <_raw_spin_unlock_irqrestore>
0xffffffffa02a9860 :  mov    0xd0(%r12),%rdi
0xffffffffa02a9868 :  callq  0xffffffff810a0650
0xffffffffa02a986d :  mov    %rbx,%rdi
0xffffffffa02a9870 :  callq  0xffffffffa02af090
0xffffffffa02a9875 :  lock decl 0x168(%rbx)
0xffffffffa02a987c :  je     0xffffffffa02a98c0
0xffffffffa02a987e :  lea    0x170(%rbx),%r12
0xffffffffa02a9885 :  mov    %r12,%rdi
0xffffffffa02a9888 :  callq  0xffffffff816b6920
0xffffffffa02a988d :  mov    0x58(%rbx),%rdi

从这里看
...
0xffffffffa02a9875 :  lock decl 0x168(%rbx)
0xffffffffa02a987c :  je     0xffffffffa02a98c0
0xffffffffa02a987e :  lea    0x170(%rbx),%r12
0xffffffffa02a9885 :  mov    %r12,%rdi <----传参数
0xffffffffa02a9888 :  callq  0xffffffff816b6920
0xffffffffa02a988d :  mov    0x58(%rbx),%rdi
...

看rdi是从r12传入的,也就是说completion的地址保存在r12中。
接下来是找r12, r12是个callee saved register, 也就是说如果一个函数要用到r12,必须先把它保存到堆栈上。那么看看wait_for_completion到底会不会保存r12,反汇编。

crash7latest> dis -r wait_for_completion+271
0xffffffff816b6920 :       push   %rbp
0xffffffff816b6921 :     mov    %rsp,%rbp
0xffffffff816b6924 :     sub    $0x70,%rsp
0xffffffff816b6928 :     mov    %rbx,-0x28(%rbp)
0xffffffff816b692c :    mov    %r12,-0x20(%rbp) <---r12保存到堆栈中了
0xffffffff816b6930 :    mov    %r13,-0x18(%rbp)
0xffffffff816b6934 :    mov    %r14,-0x10(%rbp)
0xffffffff816b6938 :    mov    %r15,-0x8(%rbp)
0xffffffff816b693c :    nopl   0x0(%rax,%rax,1)
0xffffffff816b6941 :    mov    %rdi,%rbx
0xffffffff816b6944 :    lea    0x8(%rbx),%r12
...

r12被保存到-0x20(%rbp)中了,注意这是地址.
...
 #3 [ffff88015d1c3c50] wait_for_completion at ffffffff816b6a2f
    ffff88015d1c3c58: ffff880100020002 ffff8802646f3f58
    ffff88015d1c3c68: 0000000000000001 ffff880280345400
    ffff88015d1c3c78: ffffffff810b7970 ffff8802646f3f80
    ffff88015d1c3c88: ffff8802646f3f80 ffffffffa02af15e
    ffff88015d1c3c98: ffff88015d1c3cc8 ffff8802646f3e00
    ffff88015d1c3ca8: ffff8802646f3f70 ffff8802813db838
    ffff88015d1c3cb8: 0000000000000200 ffff8802646f3030
    ffff88015d1c3cc8: ffff88015d1c3d38 ffffffffa02a988d
...
-0x20(%rbp)=0xffff88015d1c3cc8-0x20=ffff88015d1c3ca8, 然后读这个地址里的值就是r12的值。

crash7latest> rd 0xffff88015d1c3ca8
ffff88015d1c3ca8:  ffff8802646f3f70                    p?od....

r12 是 ffff8802646f3f70, completion的地址是ffff8802646f3f70, 然后算算偏移是0x170.
最终ib_mad_agent_private地址是ffff8802646f3e00。

crash7latest> whatis unregister_mad_agent
void unregister_mad_agent(struct ib_mad_agent_private *);
crash7latest> struct ib_mad_agent_private -o
struct ib_mad_agent_private {
    [0] struct list_head agent_list;
   [16] struct ib_mad_agent agent;
   [88] struct ib_mad_reg_req *reg_req;
   [96] struct ib_mad_qp_info *qp_info;
  [104] spinlock_t lock;
  [112] struct list_head send_list;
  [128] struct list_head wait_list;
  [144] struct list_head done_list;
  [160] struct delayed_work timed_work;
  [288] unsigned long timeout;
  [296] struct list_head local_list;
  [312] struct work_struct local_work;
  [344] struct list_head rmpp_list;
  [360] atomic_t refcount;
  [368] struct completion comp;
}
SIZE: 400
crash7latest> eval 368
hexadecimal: 170
    decimal: 368
      octal: 560
     binary: 0000000000000000000000000000000000000000000000000000000101110000
crash7latest> eval 0xffff8802646f3f70 - 0x170
hexadecimal: ffff8802646f3e00
    decimal: 18446612142589165056  (-131931120386560)
      octal: 1777774200114433637000
     binary: 1111111111111111100010000000001001100100011011110011111000000000
crash7latest> struct ib_mad_agent_private ffff8802646f3e00
struct ib_mad_agent_private {
  agent_list = {
    next = 0xdead000000000100,
    prev = 0xdead000000000200
  },
  agent = {
    device = 0xffff880264400000,
    qp = 0xffff8802813d9800,
    mr = 0xffff8801e15bcde0,
    recv_handler = 0xffffffffa03c7160 ,
    send_handler = 0xffffffffa03c5820 ,
    snoop_handler = 0x0,
    context = 0xffff8802646f3000,
    hi_tid = 21438,
    flags = 0,
    port_num = 1 '\001',
    rmpp_version = 0 '\000'
  },
  reg_req = 0xffff8800467aa5a0,
  qp_info = 0xffff8802813db980,
  lock = {
    {
      rlock = {
        raw_lock = {
          {
            head_tail = 917518,
            tickets = {
              head = 14,
              tail = 14
            }
          }
        }
      }
    }
  },
  send_list = {
    next = 0xffff8801da369918,
    prev = 0xffff8801da369918
  },
  wait_list = {
    next = 0xffff8802646f3e80,
    prev = 0xffff8802646f3e80
  },
  done_list = {
    next = 0xffff8802646f3e90,
    prev = 0xffff8802646f3e90
  },
  timed_work = {
    work = {
      data = {
        counter = 256
      },
      entry = {
        next = 0xffff8802646f3ea8,
        prev = 0xffff8802646f3ea8
      },
      func = 0xffffffffa02ab1f0
    },
    timer = {
      entry = {
        next = 0x0,
        prev = 0xdead000000000200
      },
      expires = 4329013876,
      base = 0xffff880286e91682,
      function = 0xffffffff810a20a0 ,
      data = 18446612142589165216,
      slack = -1,
      start_pid = -1,
      start_site = 0x0,
      start_comm = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
    },
    wq = 0xffff88027a50fc00,
    cpu = 2
  },
  timeout = 0,
  local_list = {
    next = 0xffff8802646f3f28,
    prev = 0xffff8802646f3f28
  },
  local_work = {
    data = {
      counter = 68719476704
    },
    entry = {
      next = 0xffff8802646f3f40,
      prev = 0xffff8802646f3f40
    },
    func = 0xffffffffa02a9270
  },
  rmpp_list = {
    next = 0xffff8802646f3f58,
    prev = 0xffff8802646f3f58
  },
  refcount = {
    counter = 2
  },
  comp = {
    done = 0,
    wait = {
      lock = {
        {
          rlock = {
            raw_lock = {
              {
                head_tail = 131074,
                tickets = {
                  head = 2,
                  tail = 2
                }
              }
            }
          }
        }
      },
      task_list = {
        next = 0xffff88015d1c3c80,
        prev = 0xffff88015d1c3c80
      }
    }
  }
}

你可能感兴趣的:(vmcore查找refcount过程)