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

Changeset 2314381 in mainline


Ignore:
Timestamp:
2010-01-26T22:49:26Z (11 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
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.

Files:
19 added
1 deleted
35 edited
6 moved

Legend:

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

    rbb0d3d24 r2314381  
    2727 */
    2828
    29 /** @addtogroup generic 
     29/** @addtogroup generic
    3030 * @{
    3131 */
     
    8383UDEBUG_M_ARGS_READ,
    8484
     85/** Read thread's userspace register state (istate_t).
     86 *
     87 * - ARG2 - thread identification
     88 * - ARG3 - destination address in the caller's address space
     89 *
     90 * or, on error, retval will be
     91 * - ENOENT - thread does not exist
     92 * - EBUSY - register state not available
     93 */
     94UDEBUG_M_REGS_READ,
     95
    8596/** Read the list of the debugged tasks's threads.
    8697 *
     
    97108UDEBUG_M_THREAD_READ,
    98109
     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,
     122
    99123/** Read the list of the debugged task's address space areas.
    100124 *
     
    122146} udebug_method_t;
    123147
    124                                
     148
    125149typedef enum {
    126150        UDEBUG_EVENT_FINISHED = 1,      /**< Debuging session has finished */
     
    218242
    219243int udebug_task_cleanup(struct task *ta);
     244void udebug_thread_fault(void);
    220245
    221246#endif
  • kernel/generic/include/udebug/udebug_ops.h

    rbb0d3d24 r2314381  
    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);
     51
     52int udebug_regs_read(thread_t *t, void **buffer);
    5053
    5154int udebug_mem_read(unative_t uspace_addr, size_t n, void **buffer);
  • kernel/generic/src/interrupt/interrupt.c

    rbb0d3d24 r2314381  
    134134        printf("\n");
    135135
     136        /*
     137         * Userspace can subscribe for FAULT events to take action
     138         * whenever a thread faults. (E.g. take a dump, run a debugger).
     139         * The notification is always available, but unless Udebug is enabled,
     140         * that's all you get.
     141         */
    136142        if (event_is_subscribed(EVENT_FAULT)) {
     143                /* Notify the subscriber that a fault occurred. */
    137144                event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid),
    138145                    UPPER32(TASK->taskid), (unative_t) THREAD);
     146
     147#ifdef CONFIG_UDEBUG
     148                /* Wait for a debugging session. */
     149                udebug_thread_fault();
     150#endif
    139151        }
    140 
    141 #ifdef CONFIG_UDEBUG
    142         /* Wait until a debugger attends to us. */
    143         mutex_lock(&THREAD->udebug.lock);
    144         while (!THREAD->udebug.active)
    145                 condvar_wait(&THREAD->udebug.active_cv, &THREAD->udebug.lock);
    146         mutex_unlock(&THREAD->udebug.lock);
    147 
    148         udebug_stoppable_begin();
    149         udebug_stoppable_end();
    150 
    151         /* Make sure the debugging session is over before proceeding. */
    152         mutex_lock(&THREAD->udebug.lock);
    153         while (THREAD->udebug.active)
    154                 condvar_wait(&THREAD->udebug.active_cv, &THREAD->udebug.lock);
    155         mutex_unlock(&THREAD->udebug.lock);
    156 #endif
    157152
    158153        task_kill(task->taskid);
  • kernel/generic/src/udebug/udebug.c

    rbb0d3d24 r2314381  
    460460}
    461461
     462/** Wait for debugger to handle a fault in this thread.
     463 *
     464 * When a thread faults and someone is subscribed to the FAULT kernel event,
     465 * this function is called to wait for a debugging session to give userspace
     466 * a chance to examine the faulting thead/task. When the debugging session
     467 * is over, this function returns (so that thread/task cleanup can continue).
     468 */
     469void udebug_thread_fault(void)
     470{
     471        udebug_stoppable_begin();
     472
     473        /* Wait until a debugger attends to us. */
     474        mutex_lock(&THREAD->udebug.lock);
     475        while (!THREAD->udebug.active)
     476                condvar_wait(&THREAD->udebug.active_cv, &THREAD->udebug.lock);
     477        mutex_unlock(&THREAD->udebug.lock);
     478
     479        /* Make sure the debugging session is over before proceeding. */
     480        mutex_lock(&THREAD->udebug.lock);
     481        while (THREAD->udebug.active)
     482                condvar_wait(&THREAD->udebug.active_cv, &THREAD->udebug.lock);
     483        mutex_unlock(&THREAD->udebug.lock);
     484
     485        udebug_stoppable_end();
     486}
    462487
    463488/** @}
  • kernel/generic/src/udebug/udebug_ipc.c

    rbb0d3d24 r2314381  
    202202}
    203203
    204 /** Process an AREAS_READ call.
    205  *
    206  * Returns a list of address space areas in the current task, as an array
    207  * of as_area_info_t structures.
    208  *
    209  * @param call  The call structure.
    210  */
    211 static void udebug_receive_areas_read(call_t *call)
     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)
    212211{
    213212        unative_t uspace_addr;
     
    221220
    222221        /*
    223          * Read area list.
    224          */
    225         as_get_area_info(AS, (as_area_info_t **) &data, &data_size);
     222         * Read task name.
     223         */
     224        udebug_name_read((char **) &data, &data_size);
    226225
    227226        /* Copy MAX(buf_size, data_size) bytes */
     
    249248}
    250249
     250/** Process an AREAS_READ call.
     251 *
     252 * Returns a list of address space areas in the current task, as an array
     253 * of as_area_info_t structures.
     254 *
     255 * @param call  The call structure.
     256 */
     257static void udebug_receive_areas_read(call_t *call)
     258{
     259        unative_t uspace_addr;
     260        unative_t to_copy;
     261        size_t data_size;
     262        size_t buf_size;
     263        void *data;
     264
     265        uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */
     266        buf_size = IPC_GET_ARG3(call->data);    /* Dest. buffer size */
     267
     268        /*
     269         * Read area list.
     270         */
     271        as_get_area_info(AS, (as_area_info_t **) &data, &data_size);
     272
     273        /* Copy MAX(buf_size, data_size) bytes */
     274
     275        if (buf_size > data_size)
     276                to_copy = data_size;
     277        else
     278                to_copy = buf_size;
     279
     280        /*
     281         * Make use of call->buffer to transfer data to caller's userspace
     282         */
     283
     284        IPC_SET_RETVAL(call->data, 0);
     285        /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
     286           same code in process_answer() can be used
     287           (no way to distinguish method in answer) */
     288        IPC_SET_ARG1(call->data, uspace_addr);
     289        IPC_SET_ARG2(call->data, to_copy);
     290
     291        IPC_SET_ARG3(call->data, data_size);
     292        call->buffer = data;
     293
     294        ipc_answer(&TASK->kb.box, call);
     295}
     296
    251297
    252298/** Process an ARGS_READ call.
     
    287333        ipc_answer(&TASK->kb.box, call);
    288334}
     335
     336/** Receive a REGS_READ call.
     337 *
     338 * Reads the thread's register state (istate structure).
     339 */
     340static void udebug_receive_regs_read(call_t *call)
     341{
     342        thread_t *t;
     343        unative_t uspace_addr;
     344        unative_t to_copy;
     345        void *buffer;
     346        int rc;
     347
     348        t = (thread_t *) IPC_GET_ARG2(call->data);
     349
     350        rc = udebug_regs_read(t, &buffer);
     351        if (rc < 0) {
     352                IPC_SET_RETVAL(call->data, rc);
     353                ipc_answer(&TASK->kb.box, call);
     354                return;
     355        }
     356
     357        /*
     358         * Make use of call->buffer to transfer data to caller's userspace
     359         */
     360
     361        uspace_addr = IPC_GET_ARG3(call->data);
     362        to_copy = sizeof(istate_t);
     363
     364        IPC_SET_RETVAL(call->data, 0);
     365        /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
     366           same code in process_answer() can be used
     367           (no way to distinguish method in answer) */
     368        IPC_SET_ARG1(call->data, uspace_addr);
     369        IPC_SET_ARG2(call->data, to_copy);
     370
     371        call->buffer = buffer;
     372
     373        ipc_answer(&TASK->kb.box, call);
     374}
     375
    289376
    290377/** Process an MEM_READ call.
     
    368455                udebug_receive_thread_read(call);
    369456                break;
     457        case UDEBUG_M_NAME_READ:
     458                udebug_receive_name_read(call);
     459                break;
    370460        case UDEBUG_M_AREAS_READ:
    371461                udebug_receive_areas_read(call);
     
    374464                udebug_receive_args_read(call);
    375465                break;
     466        case UDEBUG_M_REGS_READ:
     467                udebug_receive_regs_read(call);
     468                break;
    376469        case UDEBUG_M_MEM_READ:
    377470                udebug_receive_mem_read(call);
  • kernel/generic/src/udebug/udebug_ops.c

    rbb0d3d24 r2314381  
    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 *
     
    449473 * this function will fail with an EINVAL error code.
    450474 *
    451  * @param buffer        The buffer for storing thread hashes.
     475 * @param t             Thread where call arguments are to be read.
     476 * @param buffer        Place to store pointer to new buffer.
     477 * @return              EOK on success, ENOENT if @a t is invalid, EINVAL
     478 *                      if thread state is not valid for this operation.
    452479 */
    453480int udebug_args_read(thread_t *t, void **buffer)
     
    481508}
    482509
     510/** Read the register state of the thread.
     511 *
     512 * The contents of the thread's istate structure are copied to a newly
     513 * allocated buffer and a pointer to it is written to @a buffer. The size of
     514 * the buffer will be sizeof(istate_t).
     515 *
     516 * Currently register state cannot be read if the thread is inside a system
     517 * call (as opposed to an exception). This is an implementation limit.
     518 *
     519 * @param t             Thread whose state is to be read.
     520 * @param buffer        Place to store pointer to new buffer.
     521 * @return              EOK on success, ENOENT if @a t is invalid, EINVAL
     522 *                      if thread is not in valid state, EBUSY if istate
     523 *                      is not available.
     524 */
     525int udebug_regs_read(thread_t *t, void **buffer)
     526{
     527        istate_t *state, *state_buf;
     528        int rc;
     529
     530        /* Prepare a buffer to hold the data. */
     531        state_buf = malloc(sizeof(istate_t), 0);
     532
     533        /* On success, this will lock t->udebug.lock */
     534        rc = _thread_op_begin(t, false);
     535        if (rc != EOK) {
     536                return rc;
     537        }
     538
     539        state = t->udebug.uspace_state;
     540        if (state == NULL) {
     541                _thread_op_end(t);
     542                return EBUSY;
     543        }
     544
     545        /* Copy to the allocated buffer */
     546        memcpy(state_buf, state, sizeof(istate_t));
     547
     548        _thread_op_end(t);
     549
     550        *buffer = (void *) state_buf;
     551        return 0;
     552}
     553
    483554/** Read the memory of the debugged task.
    484555 *
  • uspace/app/taskdump/Makefile

    rbb0d3d24 r2314381  
    2929USPACE_PREFIX = ../..
    3030LIBS = $(LIBC_PREFIX)/libc.a
     31EXTRA_CFLAGS = -Iinclude
    3132
    3233OUTPUT = taskdump
    3334
    3435SOURCES = \
    35         taskdump.c
     36        taskdump.c \
     37        symtab.c
    3638
    3739include ../Makefile.common
  • 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 */
  • uspace/lib/libc/arch/amd64/Makefile.inc

    rbb0d3d24 r2314381  
    3737        arch/$(UARCH)/src/fibril.S \
    3838        arch/$(UARCH)/src/tls.c \
    39         arch/$(UARCH)/src/stacktrace.S
     39        arch/$(UARCH)/src/stacktrace.c \
     40        arch/$(UARCH)/src/stacktrace_asm.S
    4041
    4142GCC_CFLAGS += -fno-omit-frame-pointer
  • uspace/lib/libc/arch/amd64/include/types.h

    rbb0d3d24 r2314381  
    3636#define LIBC_amd64_TYPES_H_
    3737
     38#define __64_BITS__
     39
    3840typedef unsigned long long sysarg_t;
    3941
  • uspace/lib/libc/arch/amd64/src/stacktrace_asm.S

    rbb0d3d24 r2314381  
    2929.text
    3030
    31 .global frame_pointer_get
    32 .global frame_pointer_prev
    33 .global frame_pointer_validate
    34 .global return_address_get
    35 .global program_counter_get
     31.global stacktrace_prepare
     32.global stacktrace_fp_get
     33.global stacktrace_pc_get
    3634
    37 frame_pointer_get:
     35stacktrace_prepare:
     36        ret
     37
     38stacktrace_fp_get:
    3839        movq %rbp, %rax
    3940        ret
    4041
    41 frame_pointer_prev:
    42         movq (%rdi), %rax
    43         ret
    44 
    45 frame_pointer_validate:
    46         movq %rdi, %rax
    47         ret
    48 
    49 return_address_get:
    50         movq 8(%rdi), %rax
    51         ret
    52 
    53 program_counter_get:
     42stacktrace_pc_get:
    5443        movq (%rsp), %rax
    5544        ret
  • uspace/lib/libc/arch/arm32/Makefile.inc

    rbb0d3d24 r2314381  
    3838        arch/$(UARCH)/src/tls.c \
    3939        arch/$(UARCH)/src/eabi.S \
    40         arch/$(UARCH)/src/stacktrace.S
     40        arch/$(UARCH)/src/stacktrace.c \
     41        arch/$(UARCH)/src/stacktrace_asm.S
    4142
    4243GCC_CFLAGS += -ffixed-r9 -mtp=soft -mapcs-frame -fno-omit-frame-pointer
  • uspace/lib/libc/arch/arm32/include/types.h

    rbb0d3d24 r2314381  
    3737#define LIBC_arm32_TYPES_H_
    3838
     39#define __32_BITS__
     40
    3941typedef unsigned int sysarg_t;
    4042
  • uspace/lib/libc/arch/arm32/src/stacktrace_asm.S

    rbb0d3d24 r2314381  
    2929.text
    3030
    31 .global frame_pointer_get
    32 .global frame_pointer_prev
    33 .global frame_pointer_validate
    34 .global return_address_get
    35 .global program_counter_get
     31.global stacktrace_prepare
     32.global stacktrace_fp_get
     33.global stacktrace_pc_get
    3634
    37 frame_pointer_get:
     35stacktrace_prepare:
     36        mov pc, lr
     37
     38stacktrace_fp_get:
    3839        mov r0, fp
    3940        mov pc, lr
    4041
    41 frame_pointer_prev:
    42         ldr r0, [r0, #-12]
    43         mov pc, lr
    44 
    45 frame_pointer_validate:
    46         mov pc, lr
    47 
    48 return_address_get:
    49         ldr r0, [r0, #-4]
    50         mov pc, lr
    51 
    52 program_counter_get:
     42stacktrace_pc_get:
    5343        mov r0, lr
    5444        mov pc, lr
    55 
  • uspace/lib/libc/arch/ia32/Makefile.inc

    rbb0d3d24 r2314381  
    3838        arch/$(UARCH)/src/tls.c \
    3939        arch/$(UARCH)/src/setjmp.S \
    40         arch/$(UARCH)/src/stacktrace.S
     40        arch/$(UARCH)/src/stacktrace.c \
     41        arch/$(UARCH)/src/stacktrace_asm.S
    4142
    4243GCC_CFLAGS += -march=pentium
  • uspace/lib/libc/arch/ia32/include/types.h

    rbb0d3d24 r2314381  
    3636#define LIBC_ia32_TYPES_H_
    3737
     38#define __32_BITS__
     39
    3840typedef unsigned int sysarg_t;
    3941
  • uspace/lib/libc/arch/ia32/src/stacktrace_asm.S

    rbb0d3d24 r2314381  
    2929.text
    3030
    31 .global frame_pointer_get
    32 .global frame_pointer_prev
    33 .global frame_pointer_validate
    34 .global return_address_get
    35 .global program_counter_get
     31.global stacktrace_prepare
     32.global stacktrace_fp_get
     33.global stacktrace_pc_get
    3634
    37 frame_pointer_get:
     35stacktrace_prepare:
     36        ret
     37
     38stacktrace_fp_get:
    3839        movl %ebp, %eax
    3940        ret
    4041
    41 frame_pointer_prev:
    42         movl 4(%esp), %eax
    43         movl (%eax), %eax
    44         ret
    45 
    46 frame_pointer_validate:
    47         movl 4(%esp), %eax
    48         ret
    49 
    50 return_address_get:
    51         movl 4(%esp), %eax
    52         movl 4(%eax), %eax
    53         ret
    54 
    55 program_counter_get:
     42stacktrace_pc_get:
    5643        movl (%esp), %eax
    5744        ret
  • uspace/lib/libc/arch/ia64/Makefile.inc

    rbb0d3d24 r2314381  
    3737        arch/$(UARCH)/src/tls.c \
    3838        arch/$(UARCH)/src/ddi.c \
    39         arch/$(UARCH)/src/stacktrace.S
     39        arch/$(UARCH)/src/stacktrace.c \
     40        arch/$(UARCH)/src/stacktrace_asm.S
    4041
    4142GCC_CFLAGS += -fno-unwind-tables
  • uspace/lib/libc/arch/ia64/include/types.h

    rbb0d3d24 r2314381  
    3636#define LIBC_ia64_TYPES_H_
    3737
     38#define __64_BITS__
     39
    3840typedef unsigned long long sysarg_t;
    3941
  • uspace/lib/libc/arch/ia64/src/stacktrace_asm.S

    rbb0d3d24 r2314381  
    2929.text
    3030
    31 .global frame_pointer_get
    32 .global frame_pointer_prev
    33 .global frame_pointer_validate
    34 .global return_address_get
    35 .global program_counter_get
     31.global stacktrace_prepare
     32.global stacktrace_fp_get
     33.global stacktrace_pc_get
    3634
    37 frame_pointer_get:
    38 frame_pointer_prev:
    39 frame_pointer_validate:
    40 return_address_get:
    41 program_counter_get:
     35stacktrace_prepare:
     36        br.ret.sptk.many b0
     37
     38stacktrace_fp_get:
     39stacktrace_pc_get:
    4240        mov r8 = r0
    4341        br.ret.sptk.many b0
  • uspace/lib/libc/arch/mips32/Makefile.inc

    rbb0d3d24 r2314381  
    3636        arch/$(UARCH)/src/fibril.S \
    3737        arch/$(UARCH)/src/tls.c \
    38         arch/$(UARCH)/src/stacktrace.S
     38        arch/$(UARCH)/src/stacktrace.c \
     39        arch/$(UARCH)/src/stacktrace_asm.S
    3940
    4041GCC_CFLAGS += -mips3
  • uspace/lib/libc/arch/mips32/include/types.h

    rbb0d3d24 r2314381  
    3737#define LIBC_mips32_TYPES_H_
    3838
     39#define __32_BITS__
     40
    3941typedef unsigned int sysarg_t;
    4042
  • uspace/lib/libc/arch/mips32/src/stacktrace_asm.S

    rbb0d3d24 r2314381  
    3232.set noreorder
    3333
    34 .global frame_pointer_get
    35 .global frame_pointer_prev
    36 .global frame_pointer_validate
    37 .global return_address_get
    38 .global program_counter_get
     34.global stacktrace_prepare
     35.global stacktrace_fp_get
     36.global stacktrace_pc_get
    3937
    40 frame_pointer_get:
    41 frame_pointer_prev:
    42 frame_pointer_validate:
    43 return_address_get:
    44 program_counter_get:
     38stacktrace_prepare:
     39stacktrace_fp_get:
     40stacktrace_pc_get:
    4541        j $ra
    4642        xor $v0, $v0
  • uspace/lib/libc/arch/mips32eb/Makefile.inc

    rbb0d3d24 r2314381  
    3636        arch/$(UARCH)/src/fibril.S \
    3737        arch/$(UARCH)/src/tls.c \
    38         arch/$(UARCH)/src/stacktrace.S
     38        arch/$(UARCH)/src/stacktrace.c \
     39        arch/$(UARCH)/src/stacktrace_asm.S
    3940
    4041GCC_CFLAGS += -mips3
  • uspace/lib/libc/arch/ppc32/Makefile.inc

    rbb0d3d24 r2314381  
    3636        arch/$(UARCH)/src/fibril.S \
    3737        arch/$(UARCH)/src/tls.c \
    38         arch/$(UARCH)/src/stacktrace.S
     38        arch/$(UARCH)/src/stacktrace.c \
     39        arch/$(UARCH)/src/stacktrace_asm.S
    3940
    4041GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32
  • uspace/lib/libc/arch/ppc32/include/types.h

    rbb0d3d24 r2314381  
    3636#define LIBC_ppc32_TYPES_H_
    3737
     38#define __32_BITS__
     39
    3840typedef unsigned int sysarg_t;
    3941
  • uspace/lib/libc/arch/ppc32/src/stacktrace_asm.S

    rbb0d3d24 r2314381  
    3131#include <libarch/regname.h>
    3232
    33 .global frame_pointer_get
    34 .global frame_pointer_prev
    35 .global frame_pointer_validate
    36 .global return_address_get
    37 .global program_counter_get
     33.global stacktrace_prepare
     34.global stacktrace_fp_get
     35.global stacktrace_pc_get
    3836
    39 frame_pointer_get:
     37stacktrace_prepare:
     38        blr
     39
     40stacktrace_fp_get:
    4041        mr r3, sp
    4142        blr
    4243
    43 frame_pointer_prev:
    44         lwz r3, 0(r3)
    45         blr
    46 
    47 frame_pointer_validate:
    48         blr
    49 
    50 return_address_get:
    51         lwz r3, 4(r3)
    52         blr
    53 
    54 program_counter_get:
     44stacktrace_pc_get:
    5545        mflr r3
    5646        blr
  • uspace/lib/libc/arch/sparc64/Makefile.inc

    rbb0d3d24 r2314381  
    3535ARCH_SOURCES += arch/$(UARCH)/src/fibril.S \
    3636        arch/$(UARCH)/src/tls.c \
    37         arch/$(UARCH)/src/stacktrace.S
     37        arch/$(UARCH)/src/stacktrace.c \
     38        arch/$(UARCH)/src/stacktrace_asm.S
    3839
    3940GCC_CFLAGS += -mcpu=ultrasparc -m64
  • uspace/lib/libc/arch/sparc64/include/types.h

    rbb0d3d24 r2314381  
    3636#define LIBC_sparc64_TYPES_H_
    3737
     38#define __64_BITS__
     39
    3840typedef unsigned long sysarg_t;
    3941
  • uspace/lib/libc/generic/stacktrace.c

    rbb0d3d24 r2314381  
    11/*
    22 * Copyright (c) 2009 Jakub Jermar
     3 * Copyright (c) 2010 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    3637#include <stdio.h>
    3738#include <sys/types.h>
     39#include <errno.h>
    3840
    39 void stack_trace_fp_pc(uintptr_t fp, uintptr_t pc)
     41static int stacktrace_read_uintptr(void *arg, uintptr_t addr, uintptr_t *data);
     42
     43void stacktrace_print_fp_pc(uintptr_t fp, uintptr_t pc)
    4044{
    41         while (frame_pointer_validate(fp)) {
     45        stacktrace_t st;
     46        uintptr_t nfp;
     47
     48        st.op_arg = NULL;
     49        st.read_uintptr = stacktrace_read_uintptr;
     50
     51        while (stacktrace_fp_valid(&st, fp)) {
    4252                printf("%p: %p()\n", fp, pc);
    43                 pc = return_address_get(fp);
    44                 fp = frame_pointer_prev(fp);
     53                (void) stacktrace_ra_get(&st, fp, &pc);
     54                (void) stacktrace_fp_prev(&st, fp, &nfp);
     55                fp = nfp;
    4556        }
    4657}
    4758
    48 void stack_trace(void)
     59void stacktrace_print(void)
    4960{
    50         stack_trace_fp_pc(frame_pointer_get(), program_counter_get());
     61        stacktrace_prepare();
     62        stacktrace_print_fp_pc(stacktrace_fp_get(), stacktrace_pc_get());
    5163        /*
    5264         * Prevent the tail call optimization of the previous call by
    5365         * making it a non-tail call.
    5466         */
    55         (void) frame_pointer_get();
     67        (void) stacktrace_fp_get();
     68}
     69
     70static int stacktrace_read_uintptr(void *arg, uintptr_t addr, uintptr_t *data)
     71{
     72        (void) arg;
     73        *data = *((uintptr_t *) addr);
     74        return EOK;
    5675}
    5776
  • uspace/lib/libc/generic/udebug.c

    rbb0d3d24 r2314381  
    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)
     
    8499}
    85100
    86 
    87101int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n)
    88102{
     
    94108{
    95109        return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_ARGS_READ,
     110            tid, (sysarg_t)buffer);
     111}
     112
     113int udebug_regs_read(int phoneid, thash_t tid, void *buffer)
     114{
     115        return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_REGS_READ,
    96116            tid, (sysarg_t)buffer);
    97117}
  • uspace/lib/libc/include/stacktrace.h

    rbb0d3d24 r2314381  
    11/*
    22 * Copyright (c) 2009 Jakub Jermar
     3 * Copyright (c) 2010 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    3940#include <bool.h>
    4041
    41 extern void stack_trace(void);
    42 extern void stack_trace_fp_pc(uintptr_t, uintptr_t);
     42typedef struct {
     43        void *op_arg;
     44        int (*read_uintptr)(void *, uintptr_t, uintptr_t *);
     45} stacktrace_t;
     46
     47extern void stacktrace_print(void);
     48extern void stacktrace_print_fp_pc(uintptr_t, uintptr_t);
    4349
    4450/*
    4551 * The following interface is to be implemented by each architecture.
    4652 */
    47 extern bool frame_pointer_validate(uintptr_t);
    48 extern uintptr_t frame_pointer_get(void);
    49 extern uintptr_t frame_pointer_prev(uintptr_t);
    50 extern uintptr_t return_address_get(uintptr_t);
    51 extern uintptr_t program_counter_get();
     53extern bool stacktrace_fp_valid(stacktrace_t *, uintptr_t);
     54extern int stacktrace_fp_prev(stacktrace_t *, uintptr_t, uintptr_t *);
     55extern int stacktrace_ra_get(stacktrace_t *, uintptr_t, uintptr_t *);
     56
     57extern void stacktrace_prepare(void);
     58extern uintptr_t stacktrace_fp_get(void);
     59extern uintptr_t stacktrace_pc_get();
    5260
    5361#endif
  • uspace/lib/libc/include/stdlib.h

    rbb0d3d24 r2314381  
    4242#define abort() \
    4343        do { \
    44                 stack_trace(); \
     44                stacktrace_print(); \
    4545                _exit(1); \
    4646        } while (0)
  • uspace/lib/libc/include/udebug.h

    rbb0d3d24 r2314381  
    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);
    5153int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n);
    5254int udebug_args_read(int phoneid, thash_t tid, sysarg_t *buffer);
     55int udebug_regs_read(int phoneid, thash_t tid, void *buffer);
    5356int udebug_go(int phoneid, thash_t tid, udebug_event_t *ev_type,
    5457        sysarg_t *val0, sysarg_t *val1);
  • uspace/srv/loader/arch/amd64/Makefile.inc

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

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

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

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

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

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

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