static int frame_callback (Dwfl_Frame *state, void *frame_arg) { Dwarf_Addr pc; bool isactivation; if (! dwfl_frame_pc (state, &pc, &isactivation)) { error (0, 0, "%s", dwfl_errmsg (-1)); return DWARF_CB_ABORT; } Dwarf_Addr pc_adjusted = pc - (isactivation ? 0 : 1); /* Get PC->SYMNAME. */ Dwfl_Thread *thread = dwfl_frame_thread (state); Dwfl *dwfl = dwfl_thread_dwfl (thread); Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc_adjusted); const char *symname = NULL; if (mod) symname = dwfl_module_addrname (mod, pc_adjusted); printf ("%#" PRIx64 "\t%s\n", (uint64_t) pc, symname); if (symname && (strcmp (symname, "main") == 0 || strcmp (symname, ".main") == 0)) { kill (dwfl_pid (dwfl), SIGKILL); exit (0); } return DWARF_CB_OK; }
static int frame_callback(Dwfl_Frame *frame, void *data) { struct frame_callback_arg *frame_arg = data; char **error_msg = &frame_arg->error_msg; Dwarf_Addr pc; bool minus_one; if (!dwfl_frame_pc(frame, &pc, &minus_one)) { set_error_dwfl("dwfl_frame_pc"); return DWARF_CB_ABORT; } Dwfl *dwfl = dwfl_thread_dwfl(dwfl_frame_thread(frame)); struct sr_core_frame *result = resolve_frame(dwfl, pc, minus_one); /* Do not unwind below __libc_start_main. */ if (0 == sr_strcmp0(result->function_name, "__libc_start_main")) { sr_core_frame_free(result); return CB_STOP_UNWIND; } frame_arg->thread->frames = sr_core_frame_append(frame_arg->thread->frames, result); return DWARF_CB_OK; }
/* Prints information about one frame of a thread. Called by dwfl_getthread_frames in output_right. Returns 1 when done (max number of frames reached). Returns -1 on error. Returns 0 on success (if there are more frames in the thread, call us again). */ static int frame_callback (Dwfl_Frame *state, void *arg) { Dwarf_Addr pc; bool isactivation; int *frames = (int *) arg; if (!dwfl_frame_pc(state, &pc, &isactivation)) return -1; if (!isactivation) pc--; Dwfl *dwfl = dwfl_thread_dwfl(dwfl_frame_thread(state)); Dwfl_Module *mod = dwfl_addrmodule(dwfl, pc); const char *modname = NULL; const char *symname = NULL; GElf_Off off = 0; if (mod != NULL) { GElf_Sym sym; modname = dwfl_module_info(mod, NULL, NULL, NULL, NULL, NULL, NULL, NULL); symname = dwfl_module_addrinfo(mod, pc, &off, &sym, NULL, NULL, NULL); } /* This mimics the output produced by libunwind below. */ fprintf(options.output, " > %s(%s+0x%" PRIx64 ") [%" PRIx64 "]\n", modname, symname, off, pc); /* See if we can extract the source line too and print it on the next line if we can find it. */ if (mod != NULL) { Dwfl_Line *l = dwfl_module_getsrc(mod, pc); if (l != NULL) { int line, col; line = col = -1; const char *src = dwfl_lineinfo(l, NULL, &line, &col, NULL, NULL); if (src != NULL) { fprintf(options.output, "\t%s", src); if (line > 0) { fprintf(options.output, ":%d", line); if (col > 0) fprintf(options.output, ":%d", col); } fprintf(options.output, "\n"); } } } /* Max number of frames to print reached? */ if ((*frames)-- == 0) return 1; return 0; }