62 #include <sys/types.h> 70 #define UNW_LOCAL_ONLY 71 #include <libunwind.h> 241 void *pc, **bp, **sp;
242 unw_get_reg(&cursor->
uc, UNW_REG_IP, (unw_word_t *)&pc);
243 unw_get_reg(&cursor->
uc, UNW_REG_SP, (unw_word_t *)&sp);
244 unw_get_reg(&cursor->
uc, UNW_TDEP_BP, (unw_word_t *)&bp);
253 EMSG(
"unw_init: cursor could NOT build an interval for initial pc = %p",
292 cursor->
fence = (monitor_unwind_process_bottom_frame(pc) ? FENCE_MAIN :
293 monitor_unwind_thread_bottom_frame(pc)? FENCE_THREAD : FENCE_NONE);
295 if (cursor->
fence != FENCE_NONE) {
303 TMSG(UNW,
"unw_step: STEP_STOP, current pc in monitor fence pc=%p\n", pc);
308 void** bp = cursor->
bp;
309 void* sp = cursor->
sp;
313 TMSG(UNW,
"unw_step: invalid unw interval for cursor, trolling ...");
314 TMSG(TROLL,
"Troll due to Invalid interval for pc %p", pc);
334 EMSG(
"unw_step: ILLEGAL UNWIND INTERVAL");
344 TMSG(TROLL,
"unw_step: STEP_ERROR, pc=%p, bp=%p, sp=%p", pc, bp, sp);
348 fprintf(stderr,
"Hit troll point: attach w gdb to %d\n" 349 "Maybe call dbg_set_flag(DBG_TROLL_WAIT,0) after attached\n",
362 #define _MM(a) [UNW_ADDR_ ## a] = 0, 370 AMSG(
"VALIDATION: Confirmed: %ld, Probable: %ld (indirect: %ld, tail: %ld, etc: %ld), Wrong: %ld",
387 if (
ENABLED(VALID_RECORD_ALL) || (vstat == UNW_ADDR_WRONG) ){
388 TMSG(UNW_VALID,
"%p->%p (%s)", from, to,
vstat2s(vstat));
395 void *pc,
void **sp,
void **bp)
398 memcpy(&uc, &cursor->
uc,
sizeof(uc));
402 unw_init_local(&cursor->
uc, &uc);
414 void *pc, **bp, **sp;
415 unw_get_reg(&cursor->
uc, UNW_REG_IP, (unw_word_t *)&pc);
416 unw_get_reg(&cursor->
uc, UNW_REG_SP, (unw_word_t *)&sp);
417 unw_get_reg(&cursor->
uc, UNW_TDEP_BP, (unw_word_t *)&bp);
419 if (sp <= cursor->sp) {
436 EMSG(
"hpcrun_unw_step: cursor could NOT build an interval for last libunwind pc = %p",
453 if (!monitor_in_start_func_wide(cursor->
pc_unnorm)) {
470 TMSG(UNW_STRATEGY,
"Using SP step");
475 void** bp = cursor->
bp;
476 void* sp = cursor->
sp;
485 TMSG(UNW,
"step_sp: cursor { bp=%p, sp=%p, pc=%p }", bp, sp, pc);
496 void*
ra_loc = (
void*) next_sp;
497 void* next_pc = *next_sp++;
515 if (((
unsigned long) next_bp < (
unsigned long) sp) &&
516 ((
unsigned long) bp > (
unsigned long) sp)){
518 TMSG(UNW,
" step_sp: unwind bp sanity check fails." 519 " Resetting next_bp to current bp = %p", next_bp);
527 TMSG(UNW,
" step_sp: potential next cursor next_sp=%p ==> next_pc = %p",
533 if (((
void *)next_sp) >= monitor_stack_bottom()){
534 TMSG(UNW,
" step_sp: STEP_STOP_WEAK, no next interval and next_sp >= stack bottom," 535 " so stop unwind ...");
538 TMSG(UNW,
" sp STEP_ERROR: no next interval, step fails");
543 if (next_sp <= cursor->sp){
544 TMSG(INTV_ERR,
"@ pc = %p. sp unwind does not advance stack." 545 " New sp = %p, old sp = %p", cursor->
pc_unnorm, next_sp,
550 TMSG(UNW,
" step_sp: STEP_OK, has_intvl=%d, bp=%p, sp=%p, pc=%p",
563 TMSG(UNW_STRATEGY,
"Using BP step");
565 void **bp = cursor->
bp;
566 void *sp = cursor->
sp;
571 TMSG(UNW,
"step_bp: cursor { bp=%p, sp=%p, pc=%p }", bp, sp, pc);
574 if (!(sp <= (
void*) bp)) {
575 TMSG(UNW,
" step_bp: STEP_ERROR, unwind attempted, but incoming bp(%p) was not" 576 " >= sp(%p)", bp, sp);
580 if (!((
void *)bp < monitor_stack_bottom())) {
581 TMSG(UNW,
" step_bp: STEP_ERROR, unwind attempted, but incoming bp(%p) was not" 582 " between sp (%p) and monitor stack bottom (%p)",
583 bp, sp, monitor_stack_bottom());
588 void **next_bp = *(
void **)((
void *)bp + xr->
reg.
bp_bp_pos);
589 void **next_sp = (
void **)((
void *)bp + xr->
reg.
bp_ra_pos);
590 void*
ra_loc = (
void*) next_sp;
591 void *next_pc = *next_sp++;
599 if ((
void *)next_sp <= sp) {
600 TMSG(UNW_STRATEGY,
"BP unwind fails: bp (%p) < sp (%p)", bp, sp);
607 if (((
void *)next_sp) >= monitor_stack_bottom()) {
608 TMSG(UNW,
" step_bp: STEP_STOP_WEAK, next_sp >= monitor_stack_bottom," 609 " next_sp = %p", next_sp);
612 TMSG(UNW,
" step_bp: STEP_ERROR, cannot build interval for next_pc(%p)", next_pc);
615 TMSG(UNW,
" step_bp: STEP_OK, has_intvl=%d, bp=%p, sp=%p, pc=%p",
616 unwr_info.
btuwi !=
NULL, next_bp, next_sp, next_pc);
617 assert(ra_loc == (
void *)(next_sp - 1));
631 TMSG(UNW_STRATEGY,
"--STD_FRAME: STARTing with SP");
634 TMSG(UNW_STRATEGY,
"--STD_FRAME: SP failed, RETRY w BP");
640 TMSG(UNW_STRATEGY,
"--STD_FRAME: STARTing with BP");
643 TMSG(UNW_STRATEGY,
"--STD_FRAME: BP failed, RETRY w SP");
697 TMSG(TROLL,
"Trolling disabled");
701 unsigned int tmp_ra_offset;
707 void **next_sp = ((
void **)((
unsigned long) cursor->sp + tmp_ra_offset));
708 void *next_pc = *next_sp;
709 void *
ra_loc = (
void*) next_sp;
712 void **next_bp = (
void **) cursor->bp;
715 if ( next_sp <= cursor->sp){
716 TMSG(TROLL,
"Something weird happened! trolling from %p" 717 " resulted in sp not advancing", cursor->pc_unnorm);
723 TMSG(TROLL,
"Trolling advances cursor to pc = %p, sp = %p",
725 TMSG(TROLL,
"TROLL SUCCESS pc = %p", cursor->pc_unnorm);
727 assert(ra_loc == (
void *)(next_sp - 1));
732 TMSG(TROLL,
"No interval found for trolled pc, dropping sample," 733 " cursor pc = %p", cursor->pc_unnorm);
737 TMSG(TROLL,
"Troll failed: dropping sample, cursor pc = %p",
739 TMSG(TROLL,
"TROLL FAILURE pc = %p", cursor->pc_unnorm);
ip_normalized_t hpcrun_normalize_ip(void *unnormalized_ip, load_module_t *lm)
static step_state t1_dbg_unw_step(hpcrun_unw_cursor_t *cursor)
unw_frame_regnum_t unw_reg_code_t
void hpcrun_unw_init(void)
static int hpcrun_unw_get_norm_reg(hpcrun_unw_cursor_t *cursor, unw_reg_code_t reg_id, ip_normalized_t *reg_value)
void dump_ui_troll(unwind_interval *u)
void * hpcrun_unw_get_ra_loc(hpcrun_unw_cursor_t *cursor)
static int DEBUG_WAIT_BEFORE_TROLLING
static step_state(* dbg_unw_step)(hpcrun_unw_cursor_t *cursor)
void hpcrun_validation_summary(void)
static void update_cursor_with_troll(hpcrun_unw_cursor_t *cursor, int offset)
static step_state GCC_ATTR_UNUSED t2_dbg_unw_step(hpcrun_unw_cursor_t *cursor)
static step_state unw_step_bp(hpcrun_unw_cursor_t *cursor)
int hpcrun_below_pmsg_threshold(void)
#define LV_MCONTEXT_PC(mctxt)
static step_state unw_step_std(hpcrun_unw_cursor_t *cursor)
static bool hpcrun_retry_libunw_find_step(hpcrun_unw_cursor_t *cursor, void *pc, void **sp, void **bp)
#define UWI_RECIPE(btuwi)
enum libunw_state libunw_status
static void save_registers(hpcrun_unw_cursor_t *cursor, void **pc, void **bp, void *sp, void **ra_loc)
bool uw_recipe_map_lookup(void *addr, unwinder_t uw, unwindr_info_t *unwr_info)
void hpcrun_unw_init_cursor(hpcrun_unw_cursor_t *cursor, void *context)
step_state hpcrun_unw_step(hpcrun_unw_cursor_t *cursor)
static step_state unw_step_sp(hpcrun_unw_cursor_t *cursor)
void hpcrun_up_pmsg_count(void)
int hpcrun_unw_get_ip_unnorm_reg(hpcrun_unw_cursor_t *c, void **reg_value)
void hpcrun_unw_throw(void)
static step_state hpcrun_unw_step_real(hpcrun_unw_cursor_t *cursor)
btuwi_status_t x86_build_intervals(void *ins, unsigned int len, int noisy)
troll_status stack_troll(void **start_sp, uint *ra_pos, validate_addr_fn_t validate_addr, void *generic_arg)
static char * vstat2s(validation_status v)
void dump_ui(unwind_interval *u, int dump_to_stderr)
static void compute_normalized_ips(hpcrun_unw_cursor_t *cursor)
#define LV_MCONTEXT_SP(mctxt)
btuwi_status_t libunw_build_intervals(char *beg_insn, unsigned int len)
unw_frame_regnum_t unw_reg_code_t
ip_normalized_t the_function
#define LV_MCONTEXT_BP(mctxt)
step_state libunw_take_step(hpcrun_unw_cursor_t *cursor)
int hpcrun_unw_get_ip_norm_reg(hpcrun_unw_cursor_t *c, ip_normalized_t *reg_value)
bitree_uwi_t unwind_interval
enum unwinder_e unwinder_t
void x86_family_decoder_init()
void hpcrun_bt_dump(frame_t *unwind, const char *tag)
siglongjmp_fcn * hpcrun_get_real_siglongjmp(void)
static char * fence_enum_name(fence_enum_t f)
bool libunw_finalize_cursor(hpcrun_unw_cursor_t *cursor)
validation_status deep_validate_return_addr(void *addr, void *generic)
size_t hpcrun_validation_counts[]
static void vrecord(void *from, void *to, validation_status vstat)
void libunw_unw_init_cursor(hpcrun_unw_cursor_t *cursor, void *context)
static int hpcrun_unw_get_unnorm_reg(hpcrun_unw_cursor_t *cursor, unw_reg_code_t reg_id, void **reg_value)
static int DEBUG_NO_LONGJMP
void uw_recipe_map_init(void)
btuwi_status_t build_intervals(char *ins, unsigned int len, unwinder_t uw)