コード例 #1
0
ファイル: core_unwind_elfutils.c プロジェクト: lkundrak/satyr
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;
}
コード例 #2
0
ファイル: backtrace-dwarf.c プロジェクト: Distrotech/elfutils
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;
}
コード例 #3
0
/* 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;
}
コード例 #4
0
ファイル: crash_probe.c プロジェクト: balagopalraj/clearlinux
/* This callback is invoked for every frame in a thread. From a Dwfl_Frame, we
 * are able to extract the program counter (PC), and from that, the procedure
 * name via a Dwfl_Module.
 */
static int frame_cb(Dwfl_Frame *frame, void *userdata)
{
        Dwarf_Addr pc;
        Dwarf_Addr pc_adjusted;
        Dwfl_Module *module;
        const char *procname;
        const char *modname;
        bool activation;
        GString **bt = (GString **)userdata;

        if (!dwfl_frame_pc(frame, &pc, &activation)) {
                tm_dwfl_err("Failed to find program counter for current frame");
                return DWARF_CB_ABORT;
        }

        // The return address may be beyond the calling address, putting the
        // current PC in a different context. Subtracting 1 from PC in this
        // case generally puts it back in the same context, thus fixing the
        // virtual unwind for this frame. See the DWARF standard for details.
        if (!activation) {
                pc_adjusted = pc - 1;
        } else {
                pc_adjusted = pc;
        }

        module = dwfl_addrmodule(d_core, pc_adjusted);

        if (!module) {
                // TODO: decide if it's worth creating a record in this
                // situation, since there are likely no symbols available for a
                // backtrace...
                telem_log(LOG_ERR,
                          "Failed to find module from dwfl_addrmodule"
                          " (process '%s', PID %u)\n",
                          proc_name, (unsigned int)core_for_pid);
                return DWARF_CB_ABORT;
        }

        modname = dwfl_module_info(module, NULL, NULL, NULL, NULL, NULL, NULL,
                                   NULL);
        procname = dwfl_module_addrname(module, pc_adjusted);

        if (procname && modname) {
                g_string_append_printf(*bt, "#%u %s() - [%s]\n",
                                       frame_counter++, procname, modname);
        } else if (modname) {
                g_string_append_printf(*bt, "#%u ??? - [%s]\n",
                                       frame_counter++, modname);
        } else {
                // TODO: decide on "no symbol" representation
                g_string_append_printf(*bt, "#%u (no symbols)\n",
                                       frame_counter++);
        }

        return DWARF_CB_OK;
}
コード例 #5
0
ファイル: stacktrace.c プロジェクト: josephgbr/systemd
static int frame_callback(Dwfl_Frame *frame, void *userdata) {
        struct stack_context *c = userdata;
        Dwarf_Addr pc, pc_adjusted, bias = 0;
        _cleanup_free_ Dwarf_Die *scopes = NULL;
        const char *fname = NULL, *symbol = NULL;
        Dwfl_Module *module;
        bool is_activation;

        assert(frame);
        assert(c);

        if (c->n_frame >= FRAMES_MAX)
                return DWARF_CB_ABORT;

        if (!dwfl_frame_pc(frame, &pc, &is_activation))
                return DWARF_CB_ABORT;

        pc_adjusted = pc - (is_activation ? 0 : 1);

        module = dwfl_addrmodule(c->dwfl, pc_adjusted);
        if (module) {
                Dwarf_Die *s, *cudie;
                int n;

                cudie = dwfl_module_addrdie(module, pc_adjusted, &bias);
                if (cudie) {
                        n = dwarf_getscopes(cudie, pc_adjusted - bias, &scopes);
                        for (s = scopes; s < scopes + n; s++) {
                                if (IN_SET(dwarf_tag(s), DW_TAG_subprogram, DW_TAG_inlined_subroutine, DW_TAG_entry_point)) {
                                        Dwarf_Attribute *a, space;

                                        a = dwarf_attr_integrate(s, DW_AT_MIPS_linkage_name, &space);
                                        if (!a)
                                                a = dwarf_attr_integrate(s, DW_AT_linkage_name, &space);
                                        if (a)
                                                symbol = dwarf_formstring(a);
                                        if (!symbol)
                                                symbol = dwarf_diename(s);

                                        if (symbol)
                                                break;
                                }
                        }
                }

                if (!symbol)
                        symbol = dwfl_module_addrname(module, pc_adjusted);

                fname = dwfl_module_info(module, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
        }

        fprintf(c->f, "#%-2u 0x%016" PRIx64 " %s (%s)\n", c->n_frame, (uint64_t) pc, strna(symbol), strna(fname));
        c->n_frame ++;

        return DWARF_CB_OK;
}
コード例 #6
0
/* This callback is invoked for every frame in a thread. From a Dwfl_Frame, we
 * are able to extract the program counter (PC), and from that, the procedure
 * name via a Dwfl_Module.
 */
static int frame_cb(Dwfl_Frame *frame, void *userdata)
{
        Dwarf_Addr pc;
        Dwarf_Addr pc_adjusted;
        Dwfl_Module *module;
        const char *procname;
        const char *modname;
        bool activation;
        GString **bt = (GString **)userdata;

        if (!dwfl_frame_pc(frame, &pc, &activation)) {
                errorstr = g_strdup_printf("Failed to find program counter for"
                                           " current frame: %s\n",
                                           dwfl_errmsg(-1));
                return DWARF_CB_ABORT;
        }

        // The return address may be beyond the calling address, putting the
        // current PC in a different context. Subtracting 1 from PC in this
        // case generally puts it back in the same context, thus fixing the
        // virtual unwind for this frame. See the DWARF standard for details.
        if (!activation) {
                pc_adjusted = pc - 1;
        } else {
                pc_adjusted = pc;
        }

        module = dwfl_addrmodule(d_core, pc_adjusted);

        if (!module) {
                errorstr = g_strdup("Failed to find module for current"
                                    " frame\n");
                return DWARF_CB_ABORT;
        }

        modname = dwfl_module_info(module, NULL, NULL, NULL, NULL, NULL, NULL,
                                   NULL);
        procname = dwfl_module_addrname(module, pc_adjusted);

        if (procname && modname) {
                g_string_append_printf(*bt, "#%u %s() - [%s]\n",
                                       frame_counter++, procname, modname);
        } else if (modname) {
                g_string_append_printf(*bt, "#%u ??? - [%s]\n",
                                       frame_counter++, modname);
        } else {
                // TODO: decide on "no symbol" representation
                g_string_append_printf(*bt, "#%u (no symbols)\n",
                                       frame_counter++);
        }

        return DWARF_CB_OK;
}
コード例 #7
0
ファイル: Libdw.c プロジェクト: momiken/ghc
// Remember that we are traversing from the inner-most to the outer-most frame
static int getBacktraceFrameCb(Dwfl_Frame *frame, void *arg) {
    LibdwSession *session = arg;
    Dwarf_Addr pc;
    bool is_activation;
    if (! dwfl_frame_pc(frame, &pc, &is_activation)) {
        // failed to find PC
        backtracePush(session->cur_bt, 0x0);
    } else {
        if (is_activation)
            pc -= 1; // TODO: is this right?
        backtracePush(session->cur_bt, (StgPtr) (uintptr_t) pc);
    }

    return DWARF_CB_OK;
}