Example #1
0
char	*replace_line(char *line, char *elem, char *new_elem, int n)
{
  char	*new_line;
  char	*beg;
  int	i;

  i = n - 1;
  if ((new_line = calloc(sizeof(char) * (my_strlen(line) + my_strlen(new_elem))
			 , (my_strlen(line) + my_strlen(new_elem)))) == NULL)
    return (NULL);
  while (line[++i])
    if (!(strncmp(&line[i], elem, my_strlen(elem))))
      {
	if (line[i + my_strlen(elem)] == '\0')
	  return (new_line = short_line(new_line, line, new_elem, i));
	else
	  {
	    if ((beg = begin_of_line(line, i)) == NULL)
	      return (NULL);
	    sprintf(new_line, "%s%s%s", beg, new_elem,
		    &line[my_strlen(beg) + my_strlen(elem)]);
	    free_bl(line, beg);
	    return (new_line);
	  }
      }
  free(new_line);
  return (NULL);
}
Example #2
0
void
output_line(struct process *proc, const char *fmt, ...)
{
    if (options.summary)
        return;

    if (current_proc != NULL) {
        if (current_proc->callstack[current_depth].return_addr)
            fprintf(options.output, " <unfinished ...>\n");
        else
            fprintf(options.output, " <no return ...>\n");
    }
    current_proc = NULL;
    if (fmt == NULL)
        return;

    begin_of_line(proc, 0, 0);

    va_list args;
    va_start(args, fmt);
    vfprintf(options.output, fmt, args);
    fprintf(options.output, "\n");
    va_end(args);

    current_column = 0;
}
Example #3
0
char	*short_line(char *new_line, char *line, char *new_elem, int i)
{
  char	*beg;

  beg = begin_of_line(line, i);
  sprintf(new_line, "%s%s",
	  beg,
	  new_elem);
  free(beg);
  free(line);
  return (new_line);
}
Example #4
0
void
output_right(enum tof type, struct process *proc, struct library_symbol *libsym,
             struct timedelta *spent)
{
    assert(! options.summary);

    struct prototype *func = lookup_symbol_prototype(proc, libsym);
    if (func == NULL)
        return;

    if (current_proc != NULL
            && (current_proc != proc
                || current_depth != proc->callstack_depth)) {
        fprintf(options.output, " <unfinished ...>\n");
        current_proc = NULL;
    }
    if (current_proc != proc) {
        begin_of_line(proc, type == LT_TOF_FUNCTIONR, 1);
#ifdef USE_DEMANGLE
        current_column +=
            fprintf(options.output, "<... %s resumed> ",
                    options.demangle ? my_demangle(libsym->name)
                    : libsym->name);
#else
        current_column +=
            fprintf(options.output, "<... %s resumed> ", libsym->name);
#endif
    }

    struct callstack_element *stel
            = &proc->callstack[proc->callstack_depth - 1];

    struct fetch_context *context = stel->fetch_context;

    /* Fetch & enter into dictionary the retval first, so that
     * other values can use it in expressions.  */
    struct value retval;
    bool own_retval = false;
    if (context != NULL) {
        value_init(&retval, proc, NULL, func->return_info, 0);
        own_retval = true;
        if (fetch_retval(context, type, proc, func->return_info,
                         &retval) < 0)
            value_set_type(&retval, NULL, 0);
        else if (stel->arguments != NULL
                 && val_dict_push_named(stel->arguments, &retval,
                                        "retval", 0) == 0)
            own_retval = false;
    }

    if (stel->arguments != NULL)
        output_params(stel->arguments, stel->out.params_left,
                      val_dict_count(stel->arguments),
                      &stel->out.need_delim);

    current_column += fprintf(options.output, ") ");
    tabto(options.align - 1);
    fprintf(options.output, "= ");

    if (context != NULL && retval.type != NULL) {
        struct format_argument_data data = { &retval, stel->arguments };
        format_argument_cb(options.output, &data);
    }

    if (own_retval)
        value_destroy(&retval);

    if (opt_T) {
        assert(spent != NULL);
        fprintf(options.output, " <%lu.%06d>",
                (unsigned long) spent->tm.tv_sec,
                (int) spent->tm.tv_usec);
    }

    fprintf(options.output, "\n");

#if defined(HAVE_LIBUNWIND)
    if (options.bt_depth > 0
            && proc->unwind_priv != NULL
            && proc->unwind_as != NULL) {
        unw_cursor_t cursor;
        arch_addr_t ip, function_offset;
        struct library *lib = NULL;
        int unwind_depth = options.bt_depth;
        char fn_name[100];
        const char *lib_name;
        size_t distance;

        /* Verify that we can safely cast arch_addr_t* to
         * unw_word_t*.  */
        (void)sizeof(char[1 - 2*(sizeof(unw_word_t)
                                 != sizeof(arch_addr_t))]);
        unw_init_remote(&cursor, proc->unwind_as, proc->unwind_priv);
        while (unwind_depth) {

            int rc = unw_get_reg(&cursor, UNW_REG_IP,
                                 (unw_word_t *) &ip);
            if (rc < 0) {
                fprintf(options.output, " > Error: %s\n",
                        unw_strerror(rc));
                goto cont;
            }

            /* We are looking for the library with the base address
             * closest to the current ip.  */
            lib_name = "unmapped_area";
            distance = (size_t) -1;
            lib = proc->libraries;
            while (lib != NULL) {
                /* N.B.: Assumes sizeof(size_t) ==
                 * sizeof(arch_addr_t).
                 * Keyword: double cast.  */
                if ((ip >= lib->base) &&
                        ((size_t)(ip - lib->base)
                         < distance)) {
                    distance = ip - lib->base;
                    lib_name = lib->pathname;
                }
                lib = lib->next;
            }

            rc = unw_get_proc_name(&cursor, fn_name,
                                   sizeof(fn_name),
                                   (unw_word_t *) &function_offset);
            if (rc == 0 || rc == -UNW_ENOMEM)
                fprintf(options.output, " > %s(%s+%p) [%p]\n",
                        lib_name, fn_name, function_offset, ip);
            else
                fprintf(options.output, " > %s(??\?) [%p]\n",
                        lib_name, ip);

cont:
            if (unw_step(&cursor) <= 0)
                break;
            unwind_depth--;
        }
        fprintf(options.output, "\n");
    }
#endif /* defined(HAVE_LIBUNWIND) */

#if defined(HAVE_LIBDW)
    if (options.bt_depth > 0 && proc->leader->dwfl != NULL) {
        int frames = options.bt_depth;
        if (dwfl_getthread_frames(proc->leader->dwfl, proc->pid,
                                  frame_callback, &frames) < 0) {
            // Only print an error if we couldn't show anything.
            // Otherwise just show there might be more...
            if (frames == options.bt_depth)
                fprintf(stderr,
                        "dwfl_getthread_frames tid %d: %s\n",
                        proc->pid, dwfl_errmsg(-1));
            else
                fprintf(options.output, " > [...]\n");
        }
        fprintf(options.output, "\n");
    }
#endif /* defined(HAVE_LIBDW) */

    current_proc = NULL;
    current_column = 0;
}
Example #5
0
void
output_left(enum tof type, struct process *proc,
            struct library_symbol *libsym)
{
    assert(! options.summary);

    if (current_proc) {
        fprintf(options.output, " <unfinished ...>\n");
        current_column = 0;
    }
    current_proc = proc;
    current_depth = proc->callstack_depth;
    begin_of_line(proc, type == LT_TOF_FUNCTION, 1);
    if (!options.hide_caller && libsym->lib != NULL
            && libsym->plt_type != LS_TOPLT_NONE)
        /* We don't terribly mind failing this.  */
        account_output(&current_column,
                       fprintf(options.output, "%s->",
                               libsym->lib->soname));

    const char *name = libsym->name;
#ifdef USE_DEMANGLE
    if (options.demangle)
        name = my_demangle(libsym->name);
#endif
    if (account_output(&current_column,
                       fprintf(options.output, "%s", name)) < 0)
        return;

    if (libsym->lib != NULL
            && libsym->lib->type != LT_LIBTYPE_MAIN
            && libsym->plt_type == LS_TOPLT_NONE
            && account_output(&current_column,
                              fprintf(options.output, "@%s",
                                      libsym->lib->soname)) < 0)
        /* We do mind failing this though.  */
        return;

    account_output(&current_column, fprintf(options.output, "("));

    struct prototype *func = lookup_symbol_prototype(proc, libsym);
    if (func == NULL) {
fail:
        account_output(&current_column, fprintf(options.output, "???"));
        return;
    }

    struct fetch_context *context = fetch_arg_init(type, proc,
                                    func->return_info);
    if (context == NULL)
        goto fail;

    struct value_dict *arguments = malloc(sizeof(*arguments));
    if (arguments == NULL) {
        fetch_arg_done(context);
        goto fail;
    }
    val_dict_init(arguments);

    ssize_t params_left = -1;
    int need_delim = 0;
    if (fetch_params(type, proc, context, arguments, func, &params_left) < 0
            || output_params(arguments, 0, params_left, &need_delim) < 0) {
        val_dict_destroy(arguments);
        fetch_arg_done(context);
        arguments = NULL;
        context = NULL;
    }

    struct callstack_element *stel
            = &proc->callstack[proc->callstack_depth - 1];
    stel->fetch_context = context;
    stel->arguments = arguments;
    stel->out.params_left = params_left;
    stel->out.need_delim = need_delim;
}