Changeset 2314381 in mainline for uspace/app/taskdump/taskdump.c


Ignore:
Timestamp:
2010-01-26T22:49:26Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bca408b
Parents:
bb0d3d24 (diff), 3698e44 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge jsvoboda/helenos/taskdump: Taskdump now prints stack traces, even with symbolic names.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/taskdump/taskdump.c

    rbb0d3d24 r2314381  
    4141#include <task.h>
    4242#include <kernel/mm/as.h>
     43#include <libarch/istate.h>
    4344#include <macros.h>
    4445#include <assert.h>
    4546#include <bool.h>
    4647
     48#include <symtab.h>
     49#include <stacktrace.h>
     50
    4751#define LINE_BYTES 16
    4852
     
    5357static task_id_t task_id;
    5458static bool dump_memory;
     59static char *app_name;
     60static symtab_t *app_symtab;
    5561
    5662static int connect_task(task_id_t task_id);
    5763static int parse_args(int argc, char *argv[]);
    58 static void print_syntax();
     64static void print_syntax(void);
    5965static int threads_dump(void);
     66static int thread_dump(uintptr_t thash);
    6067static int areas_dump(void);
    6168static int area_dump(as_area_info_t *area);
    6269static void hex_dump(uintptr_t addr, void *buffer, size_t size);
     70static int td_read_uintptr(void *arg, uintptr_t addr, uintptr_t *value);
     71
     72static void autoload_syms(void);
     73static char *get_app_task_name(void);
     74static char *fmt_sym_address(uintptr_t addr);
    6375
    6476int main(int argc, char *argv[])
     
    8597        }
    8698
    87         printf("Dumping task %lld.\n\n", task_id);
     99        app_name = get_app_task_name();
     100        app_symtab = NULL;
     101
     102        printf("Dumping task '%s' (task ID %lld).\n", app_name, task_id);
     103        autoload_syms();
     104        putchar('\n');
    88105
    89106        rc = threads_dump();
     
    182199}
    183200
    184 static void print_syntax()
     201static void print_syntax(void)
    185202{
    186203        printf("Syntax: taskdump [-m] -t <task_id>\n");
     
    229246        for (i = 0; i < n_threads; i++) {
    230247                printf(" [%d] hash: 0x%lx\n", 1+i, thash_buf[i]);
     248
     249                thread_dump(thash_buf[i]);
    231250        }
    232251        putchar('\n');
     
    289308
    290309        return 0;
     310}
     311
     312static int thread_dump(uintptr_t thash)
     313{
     314        istate_t istate;
     315        uintptr_t pc, fp, nfp;
     316        stacktrace_t st;
     317        char *sym_pc;
     318        int rc;
     319
     320        rc = udebug_regs_read(phoneid, thash, &istate);
     321        if (rc < 0) {
     322                printf("Failed reading registers (%d).\n", rc);
     323                return EIO;
     324        }
     325
     326        pc = istate_get_pc(&istate);
     327        fp = istate_get_fp(&istate);
     328
     329        printf("Thread 0x%lx crashed at PC 0x%lx. FP 0x%lx\n", thash, pc, fp);
     330
     331        st.op_arg = NULL;
     332        st.read_uintptr = td_read_uintptr;
     333
     334        while (stacktrace_fp_valid(&st, fp)) {
     335                sym_pc = fmt_sym_address(pc);
     336                printf("  %p: %s()\n", fp, sym_pc);
     337                free(sym_pc);
     338
     339                rc = stacktrace_ra_get(&st, fp, &pc);
     340                if (rc != EOK)
     341                        return rc;
     342
     343                rc = stacktrace_fp_prev(&st, fp, &nfp);
     344                if (rc != EOK)
     345                        return rc;
     346
     347                fp = nfp;
     348        }
     349
     350        return EOK;
    291351}
    292352
     
    350410}
    351411
     412static int td_read_uintptr(void *arg, uintptr_t addr, uintptr_t *value)
     413{
     414        uintptr_t data;
     415        int rc;
     416
     417        (void) arg;
     418
     419        rc = udebug_mem_read(phoneid, &data, addr, sizeof(data));
     420        if (rc < 0) {
     421                printf("Warning: udebug_mem_read() failed.\n");
     422                return rc;
     423        }
     424
     425        *value = data;
     426        return EOK;
     427}
     428
     429/** Attempt to find the right executable file and load the symbol table. */
     430static void autoload_syms(void)
     431{
     432        char *file_name;
     433        int rc;
     434
     435        assert(app_name != NULL);
     436        assert(app_symtab == NULL);
     437
     438        rc = asprintf(&file_name, "/app/%s", app_name);
     439        if (rc < 0) {
     440                printf("Memory allocation failure.\n");
     441                exit(1);
     442        }
     443
     444        rc = symtab_load(file_name, &app_symtab);
     445        if (rc == EOK) {
     446                printf("Loaded symbol table from %s\n", file_name);
     447                free(file_name);
     448                return;
     449        }
     450
     451        free(file_name);
     452
     453        rc = asprintf(&file_name, "/srv/%s", app_name);
     454        if (rc < 0) {
     455                printf("Memory allocation failure.\n");
     456                exit(1);
     457        }
     458
     459        rc = symtab_load("/srv/xyz", &app_symtab);
     460        if (rc == EOK) {
     461                printf("Loaded symbol table from %s\n", file_name);
     462                free(file_name);
     463                return;
     464        }
     465
     466        free(file_name);
     467        printf("Failed autoloading symbol table.\n");
     468}
     469
     470static char *get_app_task_name(void)
     471{
     472        char dummy_buf;
     473        size_t copied, needed, name_size;
     474        char *name;
     475        int rc;
     476
     477        rc = udebug_name_read(phoneid, &dummy_buf, 0, &copied, &needed);
     478        if (rc < 0)
     479                return NULL;
     480
     481        name_size = needed;
     482        name = malloc(name_size + 1);
     483        rc = udebug_name_read(phoneid, name, name_size, &copied, &needed);
     484        if (rc < 0) {
     485                free(name);
     486                return NULL;
     487        }
     488
     489        assert(copied == name_size);
     490        assert(copied == needed);
     491        name[copied] = '\0';
     492
     493        return name;
     494}
     495
     496/** Format address in symbolic form.
     497 *
     498 * Formats address as <symbol_name>+<offset> (<address>), if possible,
     499 * otherwise as <address>.
     500 *
     501 * @param addr  Address to format.
     502 * @return      Newly allocated string, address in symbolic form.
     503 */
     504static char *fmt_sym_address(uintptr_t addr)
     505{
     506        char *name;
     507        size_t offs;
     508        int rc;
     509        char *str;
     510
     511        if (app_symtab != NULL) {
     512                rc = symtab_addr_to_name(app_symtab, addr, &name, &offs);
     513        } else {
     514                rc = ENOTSUP;
     515        }
     516
     517        if (rc == EOK) {
     518                rc = asprintf(&str, "(%p) %s+%p", addr, name, offs);
     519        } else {
     520                rc = asprintf(&str, "%p", addr);
     521        }
     522
     523        if (rc < 0) {
     524                printf("Memory allocation error.\n");
     525                exit(1);
     526        }
     527
     528        return str;
     529}
     530
    352531/** @}
    353532 */
Note: See TracChangeset for help on using the changeset viewer.