libunwind 中的宏

有些宏真的很绕:

static inline int

common_init (struct cursor *c, unsigned use_prev_instr)

{

int ret;

c->dwarf.loc[RAX] = REG_INIT_LOC(c, rax, RAX);

->

# define REG_INIT_LOC(c, rlc, ruc) \
    DWARF_REG_LOC (&c->dwarf, UNW_X86_64_ ## ruc)

->

# define DWARF_REG_LOC(c,r)     (DWARF_LOC((unw_word_t)                      \
                                 x86_64_r_uc_addr(dwarf_get_uc(c), (r)), 0))

->

先从最里面转:

dwarf_get_uc(c) 

->

static inline ucontext_t *
dwarf_get_uc(const struct dwarf_cursor *cursor)
{
  assert(cursor->as == unw_local_addr_space);
  return AS_ARG_GET_UC_PTR(cursor->as_arg);
}

# define DWARF_REG_LOC(c,r)     (DWARF_LOC((unw_word_t)                      \
                                 x86_64_r_uc_addr(cursor->as_arg, (r)), 0))

->

x86_64_r_uc_addr

#define x86_64_r_uc_addr                UNW_OBJ(r_uc_addr)

UNW_OBJ(r_uc_addr) 根据平台生成对应函数名

HIDDEN void *

x86_64_r_uc_addr (ucontext_t *uc, int reg)

{

/* NOTE: common_init() in init.h inlines these for fast path access. */

void *addr;

switch (reg)

{

case UNW_X86_64_R8: addr = &uc->uc_mcontext.gregs[REG_R8]; break;

case UNW_X86_64_R9: addr = &uc->uc_mcontext.gregs[REG_R9]; break;

case UNW_X86_64_R10: addr = &uc->uc_mcontext.gregs[REG_R10]; break;

case UNW_X86_64_R11: addr = &uc->uc_mcontext.gregs[REG_R11]; break;

根据reg返回地址

最终

c->dwarf.loc[RAX] = REG_INIT_LOC(c, rax, RAX);

# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) })

等于

c->dwarf.loc[RAX] = ((dwarf_loc_t) { .val = ( &uc->uc_mcontext.gregs[REG_R8]), .type = (t) })

上一篇:SpringBoot搭建非web应用的两种方式


下一篇:java中的wait和notify方法