Ignore:
File:
1 edited

Legend:

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

    r3698e44 rbc310a05  
    4141#include <task.h>
    4242#include <kernel/mm/as.h>
    43 #include <libarch/istate.h>
    4443#include <macros.h>
    4544#include <assert.h>
    4645#include <bool.h>
    4746
    48 #include <symtab.h>
    49 #include <stacktrace.h>
    50 
    5147#define LINE_BYTES 16
    5248
     
    5753static task_id_t task_id;
    5854static bool dump_memory;
    59 static char *app_name;
    60 static symtab_t *app_symtab;
    6155
    6256static int connect_task(task_id_t task_id);
    6357static int parse_args(int argc, char *argv[]);
    64 static void print_syntax(void);
     58static void print_syntax();
    6559static int threads_dump(void);
    66 static int thread_dump(uintptr_t thash);
    6760static int areas_dump(void);
    6861static int area_dump(as_area_info_t *area);
    6962static void hex_dump(uintptr_t addr, void *buffer, size_t size);
    70 static int td_read_uintptr(void *arg, uintptr_t addr, uintptr_t *value);
    71 
    72 static void autoload_syms(void);
    73 static char *get_app_task_name(void);
    74 static char *fmt_sym_address(uintptr_t addr);
    7563
    7664int main(int argc, char *argv[])
     
    9785        }
    9886
    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');
     87        printf("Dumping task %lld.\n\n", task_id);
    10588
    10689        rc = threads_dump();
     
    199182}
    200183
    201 static void print_syntax(void)
     184static void print_syntax()
    202185{
    203186        printf("Syntax: taskdump [-m] -t <task_id>\n");
     
    246229        for (i = 0; i < n_threads; i++) {
    247230                printf(" [%d] hash: 0x%lx\n", 1+i, thash_buf[i]);
    248 
    249                 thread_dump(thash_buf[i]);
    250231        }
    251232        putchar('\n');
     
    310291}
    311292
    312 static 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;
    351 }
    352 
    353293static int area_dump(as_area_info_t *area)
    354294{
     
    410350}
    411351
    412 static 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. */
    430 static 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 
    470 static 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  */
    504 static 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 
    531352/** @}
    532353 */
Note: See TracChangeset for help on using the changeset viewer.