Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 3698e44 in mainline


Ignore:
Timestamp:
2010-01-26T22:46:29Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
196a1439, 2314381
Parents:
e515b21a
Message:

Add ability to determine task name and load symbol table from the binary executable. Resolve symbol names in stack traces when dumping.

Files:
3 added
22 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/udebug/udebug.h

    re515b21a r3698e44  
    107107 */
    108108UDEBUG_M_THREAD_READ,
     109
     110/** Read the name of the debugged task.
     111 *
     112 * - ARG2 - destination address in the caller's address space
     113 * - ARG3 - size of receiving buffer in bytes
     114 *
     115 * The kernel fills the buffer with a non-terminated string.
     116 *
     117 * - ARG2 - number of bytes that were actually copied
     118 * - ARG3 - number of bytes of the complete data
     119 *
     120 */
     121UDEBUG_M_NAME_READ,
    109122
    110123/** Read the list of the debugged task's address space areas.
  • kernel/generic/include/udebug/udebug_ops.h

    re515b21a r3698e44  
    4747int udebug_thread_read(void **buffer, size_t buf_size, size_t *stored,
    4848    size_t *needed);
     49int udebug_name_read(char **data, size_t *data_size);
    4950int udebug_args_read(thread_t *t, void **buffer);
    5051
  • kernel/generic/src/udebug/udebug_ipc.c

    re515b21a r3698e44  
    198198        IPC_SET_ARG3(call->data, needed);
    199199        call->buffer = buffer;
     200
     201        ipc_answer(&TASK->kb.box, call);
     202}
     203
     204/** Process a NAME_READ call.
     205 *
     206 * Returns a string containing the name of the task.
     207 *
     208 * @param call  The call structure.
     209 */
     210static void udebug_receive_name_read(call_t *call)
     211{
     212        unative_t uspace_addr;
     213        unative_t to_copy;
     214        size_t data_size;
     215        size_t buf_size;
     216        void *data;
     217
     218        uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */
     219        buf_size = IPC_GET_ARG3(call->data);    /* Dest. buffer size */
     220
     221        /*
     222         * Read task name.
     223         */
     224        udebug_name_read((char **) &data, &data_size);
     225
     226        /* Copy MAX(buf_size, data_size) bytes */
     227
     228        if (buf_size > data_size)
     229                to_copy = data_size;
     230        else
     231                to_copy = buf_size;
     232
     233        /*
     234         * Make use of call->buffer to transfer data to caller's userspace
     235         */
     236
     237        IPC_SET_RETVAL(call->data, 0);
     238        /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
     239           same code in process_answer() can be used
     240           (no way to distinguish method in answer) */
     241        IPC_SET_ARG1(call->data, uspace_addr);
     242        IPC_SET_ARG2(call->data, to_copy);
     243
     244        IPC_SET_ARG3(call->data, data_size);
     245        call->buffer = data;
    200246
    201247        ipc_answer(&TASK->kb.box, call);
     
    409455                udebug_receive_thread_read(call);
    410456                break;
     457        case UDEBUG_M_NAME_READ:
     458                udebug_receive_name_read(call);
     459                break;
    411460        case UDEBUG_M_AREAS_READ:
    412461                udebug_receive_areas_read(call);
  • kernel/generic/src/udebug/udebug_ops.c

    re515b21a r3698e44  
    4646#include <errno.h>
    4747#include <print.h>
     48#include <string.h>
    4849#include <syscall/copy.h>
    4950#include <ipc/ipc.h>
     
    439440}
    440441
     442/** Read task name.
     443 *
     444 * Returns task name as non-terminated string in a newly allocated buffer.
     445 * Also returns the size of the data.
     446 *
     447 * @param data          Place to store pointer to newly allocated block.
     448 * @param data_size     Place to store size of the data.
     449 *
     450 * @returns             EOK.
     451 */
     452int udebug_name_read(char **data, size_t *data_size)
     453{
     454        size_t name_size;
     455
     456        name_size = str_size(TASK->name) + 1;
     457        *data = malloc(name_size, 0);
     458        *data_size = name_size;
     459
     460        memcpy(*data, TASK->name, name_size);
     461
     462        return 0;
     463}
     464
    441465/** Read the arguments of a system call.
    442466 *
  • uspace/app/taskdump/Makefile

    re515b21a r3698e44  
    3434
    3535SOURCES = \
    36         taskdump.c
     36        taskdump.c \
     37        symtab.c
    3738
    3839include ../Makefile.common
  • uspace/app/taskdump/taskdump.c

    re515b21a r3698e44  
    4646#include <bool.h>
    4747
     48#include <symtab.h>
    4849#include <stacktrace.h>
    4950
     
    5657static task_id_t task_id;
    5758static bool dump_memory;
     59static char *app_name;
     60static symtab_t *app_symtab;
    5861
    5962static int connect_task(task_id_t task_id);
     
    6770static int td_read_uintptr(void *arg, uintptr_t addr, uintptr_t *value);
    6871
     72static void autoload_syms(void);
     73static char *get_app_task_name(void);
     74static char *fmt_sym_address(uintptr_t addr);
     75
    6976int main(int argc, char *argv[])
    7077{
     
    9097        }
    9198
    92         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');
    93105
    94106        rc = threads_dump();
     
    303315        uintptr_t pc, fp, nfp;
    304316        stacktrace_t st;
     317        char *sym_pc;
    305318        int rc;
    306319
     
    320333
    321334        while (stacktrace_fp_valid(&st, fp)) {
    322                 printf("%p: %p()\n", fp, pc);
     335                sym_pc = fmt_sym_address(pc);
     336                printf("  %p: %s()\n", fp, sym_pc);
     337                free(sym_pc);
    323338
    324339                rc = stacktrace_ra_get(&st, fp, &pc);
     
    412427}
    413428
     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
    414531/** @}
    415532 */
  • uspace/lib/libc/arch/amd64/include/types.h

    re515b21a r3698e44  
    3636#define LIBC_amd64_TYPES_H_
    3737
     38#define __64_BITS__
     39
    3840typedef unsigned long long sysarg_t;
    3941
  • uspace/lib/libc/arch/arm32/include/types.h

    re515b21a r3698e44  
    3737#define LIBC_arm32_TYPES_H_
    3838
     39#define __32_BITS__
     40
    3941typedef unsigned int sysarg_t;
    4042
  • uspace/lib/libc/arch/ia32/include/types.h

    re515b21a r3698e44  
    3636#define LIBC_ia32_TYPES_H_
    3737
     38#define __32_BITS__
     39
    3840typedef unsigned int sysarg_t;
    3941
  • uspace/lib/libc/arch/ia64/include/types.h

    re515b21a r3698e44  
    3636#define LIBC_ia64_TYPES_H_
    3737
     38#define __64_BITS__
     39
    3840typedef unsigned long long sysarg_t;
    3941
  • uspace/lib/libc/arch/mips32/include/types.h

    re515b21a r3698e44  
    3737#define LIBC_mips32_TYPES_H_
    3838
     39#define __32_BITS__
     40
    3941typedef unsigned int sysarg_t;
    4042
  • uspace/lib/libc/arch/ppc32/include/types.h

    re515b21a r3698e44  
    3636#define LIBC_ppc32_TYPES_H_
    3737
     38#define __32_BITS__
     39
    3840typedef unsigned int sysarg_t;
    3941
  • uspace/lib/libc/arch/sparc64/include/types.h

    re515b21a r3698e44  
    3636#define LIBC_sparc64_TYPES_H_
    3737
     38#define __64_BITS__
     39
    3840typedef unsigned long sysarg_t;
    3941
  • uspace/lib/libc/generic/udebug.c

    re515b21a r3698e44  
    6969}
    7070
     71int udebug_name_read(int phoneid, void *buffer, size_t n,
     72        size_t *copied, size_t *needed)
     73{
     74        ipcarg_t a_copied, a_needed;
     75        int rc;
     76
     77        rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_NAME_READ,
     78                (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
     79
     80        *copied = (size_t)a_copied;
     81        *needed = (size_t)a_needed;
     82
     83        return rc;
     84}
     85
    7186int udebug_areas_read(int phoneid, void *buffer, size_t n,
    7287        size_t *copied, size_t *needed)
     
    8398        return rc;
    8499}
    85 
    86100
    87101int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n)
  • uspace/lib/libc/include/udebug.h

    re515b21a r3698e44  
    4747int udebug_thread_read(int phoneid, void *buffer, size_t n,
    4848        size_t *copied, size_t *needed);
     49int udebug_name_read(int phoneid, void *buffer, size_t n,
     50        size_t *copied, size_t *needed);
    4951int udebug_areas_read(int phoneid, void *buffer, size_t n,
    5052        size_t *copied, size_t *needed);
  • uspace/srv/loader/arch/amd64/Makefile.inc

    re515b21a r3698e44  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__64_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/amd64.s
  • uspace/srv/loader/arch/arm32/Makefile.inc

    re515b21a r3698e44  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__32_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/arm32.s
  • uspace/srv/loader/arch/ia32/Makefile.inc

    re515b21a r3698e44  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__32_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/ia32.s
  • uspace/srv/loader/arch/ia64/Makefile.inc

    re515b21a r3698e44  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__64_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/ia64.s
    3130AFLAGS += -xexplicit
  • uspace/srv/loader/arch/mips32/Makefile.inc

    re515b21a r3698e44  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__32_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/mips32.s
  • uspace/srv/loader/arch/ppc32/Makefile.inc

    re515b21a r3698e44  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__32_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/ppc32.s
  • uspace/srv/loader/arch/sparc64/Makefile.inc

    re515b21a r3698e44  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__64_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/sparc64.s
Note: See TracChangeset for help on using the changeset viewer.