Changeset 2314381 in mainline
- Timestamp:
- 2010-01-26T22:49:26Z (15 years ago)
- 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. - Files:
-
- 19 added
- 1 deleted
- 35 edited
- 6 moved
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/udebug/udebug.h
rbb0d3d24 r2314381 27 27 */ 28 28 29 /** @addtogroup generic 29 /** @addtogroup generic 30 30 * @{ 31 31 */ … … 83 83 UDEBUG_M_ARGS_READ, 84 84 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 */ 94 UDEBUG_M_REGS_READ, 95 85 96 /** Read the list of the debugged tasks's threads. 86 97 * … … 97 108 UDEBUG_M_THREAD_READ, 98 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 */ 121 UDEBUG_M_NAME_READ, 122 99 123 /** Read the list of the debugged task's address space areas. 100 124 * … … 122 146 } udebug_method_t; 123 147 124 148 125 149 typedef enum { 126 150 UDEBUG_EVENT_FINISHED = 1, /**< Debuging session has finished */ … … 218 242 219 243 int udebug_task_cleanup(struct task *ta); 244 void udebug_thread_fault(void); 220 245 221 246 #endif -
kernel/generic/include/udebug/udebug_ops.h
rbb0d3d24 r2314381 47 47 int udebug_thread_read(void **buffer, size_t buf_size, size_t *stored, 48 48 size_t *needed); 49 int udebug_name_read(char **data, size_t *data_size); 49 50 int udebug_args_read(thread_t *t, void **buffer); 51 52 int udebug_regs_read(thread_t *t, void **buffer); 50 53 51 54 int udebug_mem_read(unative_t uspace_addr, size_t n, void **buffer); -
kernel/generic/src/interrupt/interrupt.c
rbb0d3d24 r2314381 134 134 printf("\n"); 135 135 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 */ 136 142 if (event_is_subscribed(EVENT_FAULT)) { 143 /* Notify the subscriber that a fault occurred. */ 137 144 event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid), 138 145 UPPER32(TASK->taskid), (unative_t) THREAD); 146 147 #ifdef CONFIG_UDEBUG 148 /* Wait for a debugging session. */ 149 udebug_thread_fault(); 150 #endif 139 151 } 140 141 #ifdef CONFIG_UDEBUG142 /* 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 #endif157 152 158 153 task_kill(task->taskid); -
kernel/generic/src/udebug/udebug.c
rbb0d3d24 r2314381 460 460 } 461 461 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 */ 469 void 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 } 462 487 463 488 /** @} -
kernel/generic/src/udebug/udebug_ipc.c
rbb0d3d24 r2314381 202 202 } 203 203 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 */ 210 static void udebug_receive_name_read(call_t *call) 212 211 { 213 212 unative_t uspace_addr; … … 221 220 222 221 /* 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); 226 225 227 226 /* Copy MAX(buf_size, data_size) bytes */ … … 249 248 } 250 249 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 */ 257 static 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 251 297 252 298 /** Process an ARGS_READ call. … … 287 333 ipc_answer(&TASK->kb.box, call); 288 334 } 335 336 /** Receive a REGS_READ call. 337 * 338 * Reads the thread's register state (istate structure). 339 */ 340 static 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 289 376 290 377 /** Process an MEM_READ call. … … 368 455 udebug_receive_thread_read(call); 369 456 break; 457 case UDEBUG_M_NAME_READ: 458 udebug_receive_name_read(call); 459 break; 370 460 case UDEBUG_M_AREAS_READ: 371 461 udebug_receive_areas_read(call); … … 374 464 udebug_receive_args_read(call); 375 465 break; 466 case UDEBUG_M_REGS_READ: 467 udebug_receive_regs_read(call); 468 break; 376 469 case UDEBUG_M_MEM_READ: 377 470 udebug_receive_mem_read(call); -
kernel/generic/src/udebug/udebug_ops.c
rbb0d3d24 r2314381 46 46 #include <errno.h> 47 47 #include <print.h> 48 #include <string.h> 48 49 #include <syscall/copy.h> 49 50 #include <ipc/ipc.h> … … 439 440 } 440 441 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 */ 452 int 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 441 465 /** Read the arguments of a system call. 442 466 * … … 449 473 * this function will fail with an EINVAL error code. 450 474 * 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. 452 479 */ 453 480 int udebug_args_read(thread_t *t, void **buffer) … … 481 508 } 482 509 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 */ 525 int 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 483 554 /** Read the memory of the debugged task. 484 555 * -
uspace/app/taskdump/Makefile
rbb0d3d24 r2314381 29 29 USPACE_PREFIX = ../.. 30 30 LIBS = $(LIBC_PREFIX)/libc.a 31 EXTRA_CFLAGS = -Iinclude 31 32 32 33 OUTPUT = taskdump 33 34 34 35 SOURCES = \ 35 taskdump.c 36 taskdump.c \ 37 symtab.c 36 38 37 39 include ../Makefile.common -
uspace/app/taskdump/taskdump.c
rbb0d3d24 r2314381 41 41 #include <task.h> 42 42 #include <kernel/mm/as.h> 43 #include <libarch/istate.h> 43 44 #include <macros.h> 44 45 #include <assert.h> 45 46 #include <bool.h> 46 47 48 #include <symtab.h> 49 #include <stacktrace.h> 50 47 51 #define LINE_BYTES 16 48 52 … … 53 57 static task_id_t task_id; 54 58 static bool dump_memory; 59 static char *app_name; 60 static symtab_t *app_symtab; 55 61 56 62 static int connect_task(task_id_t task_id); 57 63 static int parse_args(int argc, char *argv[]); 58 static void print_syntax( );64 static void print_syntax(void); 59 65 static int threads_dump(void); 66 static int thread_dump(uintptr_t thash); 60 67 static int areas_dump(void); 61 68 static int area_dump(as_area_info_t *area); 62 69 static 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); 63 75 64 76 int main(int argc, char *argv[]) … … 85 97 } 86 98 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'); 88 105 89 106 rc = threads_dump(); … … 182 199 } 183 200 184 static void print_syntax( )201 static void print_syntax(void) 185 202 { 186 203 printf("Syntax: taskdump [-m] -t <task_id>\n"); … … 229 246 for (i = 0; i < n_threads; i++) { 230 247 printf(" [%d] hash: 0x%lx\n", 1+i, thash_buf[i]); 248 249 thread_dump(thash_buf[i]); 231 250 } 232 251 putchar('\n'); … … 289 308 290 309 return 0; 310 } 311 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; 291 351 } 292 352 … … 350 410 } 351 411 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 352 531 /** @} 353 532 */ -
uspace/lib/libc/arch/amd64/Makefile.inc
rbb0d3d24 r2314381 37 37 arch/$(UARCH)/src/fibril.S \ 38 38 arch/$(UARCH)/src/tls.c \ 39 arch/$(UARCH)/src/stacktrace.S 39 arch/$(UARCH)/src/stacktrace.c \ 40 arch/$(UARCH)/src/stacktrace_asm.S 40 41 41 42 GCC_CFLAGS += -fno-omit-frame-pointer -
uspace/lib/libc/arch/amd64/include/types.h
rbb0d3d24 r2314381 36 36 #define LIBC_amd64_TYPES_H_ 37 37 38 #define __64_BITS__ 39 38 40 typedef unsigned long long sysarg_t; 39 41 -
uspace/lib/libc/arch/amd64/src/stacktrace_asm.S
rbb0d3d24 r2314381 29 29 .text 30 30 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 36 34 37 frame_pointer_get: 35 stacktrace_prepare: 36 ret 37 38 stacktrace_fp_get: 38 39 movq %rbp, %rax 39 40 ret 40 41 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: 42 stacktrace_pc_get: 54 43 movq (%rsp), %rax 55 44 ret -
uspace/lib/libc/arch/arm32/Makefile.inc
rbb0d3d24 r2314381 38 38 arch/$(UARCH)/src/tls.c \ 39 39 arch/$(UARCH)/src/eabi.S \ 40 arch/$(UARCH)/src/stacktrace.S 40 arch/$(UARCH)/src/stacktrace.c \ 41 arch/$(UARCH)/src/stacktrace_asm.S 41 42 42 43 GCC_CFLAGS += -ffixed-r9 -mtp=soft -mapcs-frame -fno-omit-frame-pointer -
uspace/lib/libc/arch/arm32/include/types.h
rbb0d3d24 r2314381 37 37 #define LIBC_arm32_TYPES_H_ 38 38 39 #define __32_BITS__ 40 39 41 typedef unsigned int sysarg_t; 40 42 -
uspace/lib/libc/arch/arm32/src/stacktrace_asm.S
rbb0d3d24 r2314381 29 29 .text 30 30 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 36 34 37 frame_pointer_get: 35 stacktrace_prepare: 36 mov pc, lr 37 38 stacktrace_fp_get: 38 39 mov r0, fp 39 40 mov pc, lr 40 41 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: 42 stacktrace_pc_get: 53 43 mov r0, lr 54 44 mov pc, lr 55 -
uspace/lib/libc/arch/ia32/Makefile.inc
rbb0d3d24 r2314381 38 38 arch/$(UARCH)/src/tls.c \ 39 39 arch/$(UARCH)/src/setjmp.S \ 40 arch/$(UARCH)/src/stacktrace.S 40 arch/$(UARCH)/src/stacktrace.c \ 41 arch/$(UARCH)/src/stacktrace_asm.S 41 42 42 43 GCC_CFLAGS += -march=pentium -
uspace/lib/libc/arch/ia32/include/types.h
rbb0d3d24 r2314381 36 36 #define LIBC_ia32_TYPES_H_ 37 37 38 #define __32_BITS__ 39 38 40 typedef unsigned int sysarg_t; 39 41 -
uspace/lib/libc/arch/ia32/src/stacktrace_asm.S
rbb0d3d24 r2314381 29 29 .text 30 30 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 36 34 37 frame_pointer_get: 35 stacktrace_prepare: 36 ret 37 38 stacktrace_fp_get: 38 39 movl %ebp, %eax 39 40 ret 40 41 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: 42 stacktrace_pc_get: 56 43 movl (%esp), %eax 57 44 ret -
uspace/lib/libc/arch/ia64/Makefile.inc
rbb0d3d24 r2314381 37 37 arch/$(UARCH)/src/tls.c \ 38 38 arch/$(UARCH)/src/ddi.c \ 39 arch/$(UARCH)/src/stacktrace.S 39 arch/$(UARCH)/src/stacktrace.c \ 40 arch/$(UARCH)/src/stacktrace_asm.S 40 41 41 42 GCC_CFLAGS += -fno-unwind-tables -
uspace/lib/libc/arch/ia64/include/types.h
rbb0d3d24 r2314381 36 36 #define LIBC_ia64_TYPES_H_ 37 37 38 #define __64_BITS__ 39 38 40 typedef unsigned long long sysarg_t; 39 41 -
uspace/lib/libc/arch/ia64/src/stacktrace_asm.S
rbb0d3d24 r2314381 29 29 .text 30 30 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 36 34 37 frame_pointer_get:38 frame_pointer_prev: 39 frame_pointer_validate: 40 return_address_get:41 program_counter_get:35 stacktrace_prepare: 36 br.ret.sptk.many b0 37 38 stacktrace_fp_get: 39 stacktrace_pc_get: 42 40 mov r8 = r0 43 41 br.ret.sptk.many b0 -
uspace/lib/libc/arch/mips32/Makefile.inc
rbb0d3d24 r2314381 36 36 arch/$(UARCH)/src/fibril.S \ 37 37 arch/$(UARCH)/src/tls.c \ 38 arch/$(UARCH)/src/stacktrace.S 38 arch/$(UARCH)/src/stacktrace.c \ 39 arch/$(UARCH)/src/stacktrace_asm.S 39 40 40 41 GCC_CFLAGS += -mips3 -
uspace/lib/libc/arch/mips32/include/types.h
rbb0d3d24 r2314381 37 37 #define LIBC_mips32_TYPES_H_ 38 38 39 #define __32_BITS__ 40 39 41 typedef unsigned int sysarg_t; 40 42 -
uspace/lib/libc/arch/mips32/src/stacktrace_asm.S
rbb0d3d24 r2314381 32 32 .set noreorder 33 33 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 39 37 40 frame_pointer_get: 41 frame_pointer_prev: 42 frame_pointer_validate: 43 return_address_get: 44 program_counter_get: 38 stacktrace_prepare: 39 stacktrace_fp_get: 40 stacktrace_pc_get: 45 41 j $ra 46 42 xor $v0, $v0 -
uspace/lib/libc/arch/mips32eb/Makefile.inc
rbb0d3d24 r2314381 36 36 arch/$(UARCH)/src/fibril.S \ 37 37 arch/$(UARCH)/src/tls.c \ 38 arch/$(UARCH)/src/stacktrace.S 38 arch/$(UARCH)/src/stacktrace.c \ 39 arch/$(UARCH)/src/stacktrace_asm.S 39 40 40 41 GCC_CFLAGS += -mips3 -
uspace/lib/libc/arch/ppc32/Makefile.inc
rbb0d3d24 r2314381 36 36 arch/$(UARCH)/src/fibril.S \ 37 37 arch/$(UARCH)/src/tls.c \ 38 arch/$(UARCH)/src/stacktrace.S 38 arch/$(UARCH)/src/stacktrace.c \ 39 arch/$(UARCH)/src/stacktrace_asm.S 39 40 40 41 GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32 -
uspace/lib/libc/arch/ppc32/include/types.h
rbb0d3d24 r2314381 36 36 #define LIBC_ppc32_TYPES_H_ 37 37 38 #define __32_BITS__ 39 38 40 typedef unsigned int sysarg_t; 39 41 -
uspace/lib/libc/arch/ppc32/src/stacktrace_asm.S
rbb0d3d24 r2314381 31 31 #include <libarch/regname.h> 32 32 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 38 36 39 frame_pointer_get: 37 stacktrace_prepare: 38 blr 39 40 stacktrace_fp_get: 40 41 mr r3, sp 41 42 blr 42 43 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: 44 stacktrace_pc_get: 55 45 mflr r3 56 46 blr -
uspace/lib/libc/arch/sparc64/Makefile.inc
rbb0d3d24 r2314381 35 35 ARCH_SOURCES += arch/$(UARCH)/src/fibril.S \ 36 36 arch/$(UARCH)/src/tls.c \ 37 arch/$(UARCH)/src/stacktrace.S 37 arch/$(UARCH)/src/stacktrace.c \ 38 arch/$(UARCH)/src/stacktrace_asm.S 38 39 39 40 GCC_CFLAGS += -mcpu=ultrasparc -m64 -
uspace/lib/libc/arch/sparc64/include/types.h
rbb0d3d24 r2314381 36 36 #define LIBC_sparc64_TYPES_H_ 37 37 38 #define __64_BITS__ 39 38 40 typedef unsigned long sysarg_t; 39 41 -
uspace/lib/libc/generic/stacktrace.c
rbb0d3d24 r2314381 1 1 /* 2 2 * Copyright (c) 2009 Jakub Jermar 3 * Copyright (c) 2010 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 36 37 #include <stdio.h> 37 38 #include <sys/types.h> 39 #include <errno.h> 38 40 39 void stack_trace_fp_pc(uintptr_t fp, uintptr_t pc) 41 static int stacktrace_read_uintptr(void *arg, uintptr_t addr, uintptr_t *data); 42 43 void stacktrace_print_fp_pc(uintptr_t fp, uintptr_t pc) 40 44 { 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)) { 42 52 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; 45 56 } 46 57 } 47 58 48 void stack _trace(void)59 void stacktrace_print(void) 49 60 { 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()); 51 63 /* 52 64 * Prevent the tail call optimization of the previous call by 53 65 * making it a non-tail call. 54 66 */ 55 (void) frame_pointer_get(); 67 (void) stacktrace_fp_get(); 68 } 69 70 static int stacktrace_read_uintptr(void *arg, uintptr_t addr, uintptr_t *data) 71 { 72 (void) arg; 73 *data = *((uintptr_t *) addr); 74 return EOK; 56 75 } 57 76 -
uspace/lib/libc/generic/udebug.c
rbb0d3d24 r2314381 69 69 } 70 70 71 int 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 71 86 int udebug_areas_read(int phoneid, void *buffer, size_t n, 72 87 size_t *copied, size_t *needed) … … 84 99 } 85 100 86 87 101 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n) 88 102 { … … 94 108 { 95 109 return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_ARGS_READ, 110 tid, (sysarg_t)buffer); 111 } 112 113 int 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, 96 116 tid, (sysarg_t)buffer); 97 117 } -
uspace/lib/libc/include/stacktrace.h
rbb0d3d24 r2314381 1 1 /* 2 2 * Copyright (c) 2009 Jakub Jermar 3 * Copyright (c) 2010 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 39 40 #include <bool.h> 40 41 41 extern void stack_trace(void); 42 extern void stack_trace_fp_pc(uintptr_t, uintptr_t); 42 typedef struct { 43 void *op_arg; 44 int (*read_uintptr)(void *, uintptr_t, uintptr_t *); 45 } stacktrace_t; 46 47 extern void stacktrace_print(void); 48 extern void stacktrace_print_fp_pc(uintptr_t, uintptr_t); 43 49 44 50 /* 45 51 * The following interface is to be implemented by each architecture. 46 52 */ 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(); 53 extern bool stacktrace_fp_valid(stacktrace_t *, uintptr_t); 54 extern int stacktrace_fp_prev(stacktrace_t *, uintptr_t, uintptr_t *); 55 extern int stacktrace_ra_get(stacktrace_t *, uintptr_t, uintptr_t *); 56 57 extern void stacktrace_prepare(void); 58 extern uintptr_t stacktrace_fp_get(void); 59 extern uintptr_t stacktrace_pc_get(); 52 60 53 61 #endif -
uspace/lib/libc/include/stdlib.h
rbb0d3d24 r2314381 42 42 #define abort() \ 43 43 do { \ 44 stack _trace(); \44 stacktrace_print(); \ 45 45 _exit(1); \ 46 46 } while (0) -
uspace/lib/libc/include/udebug.h
rbb0d3d24 r2314381 47 47 int udebug_thread_read(int phoneid, void *buffer, size_t n, 48 48 size_t *copied, size_t *needed); 49 int udebug_name_read(int phoneid, void *buffer, size_t n, 50 size_t *copied, size_t *needed); 49 51 int udebug_areas_read(int phoneid, void *buffer, size_t n, 50 52 size_t *copied, size_t *needed); 51 53 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n); 52 54 int udebug_args_read(int phoneid, thash_t tid, sysarg_t *buffer); 55 int udebug_regs_read(int phoneid, thash_t tid, void *buffer); 53 56 int udebug_go(int phoneid, thash_t tid, udebug_event_t *ev_type, 54 57 sysarg_t *val0, sysarg_t *val1); -
uspace/srv/loader/arch/amd64/Makefile.inc
rbb0d3d24 r2314381 27 27 # 28 28 29 EXTRA_CFLAGS = -D__64_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/amd64.s -
uspace/srv/loader/arch/arm32/Makefile.inc
rbb0d3d24 r2314381 27 27 # 28 28 29 EXTRA_CFLAGS = -D__32_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/arm32.s -
uspace/srv/loader/arch/ia32/Makefile.inc
rbb0d3d24 r2314381 27 27 # 28 28 29 EXTRA_CFLAGS = -D__32_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/ia32.s -
uspace/srv/loader/arch/ia64/Makefile.inc
rbb0d3d24 r2314381 27 27 # 28 28 29 EXTRA_CFLAGS = -D__64_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/ia64.s 31 30 AFLAGS += -xexplicit -
uspace/srv/loader/arch/mips32/Makefile.inc
rbb0d3d24 r2314381 27 27 # 28 28 29 EXTRA_CFLAGS = -D__32_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/mips32.s -
uspace/srv/loader/arch/ppc32/Makefile.inc
rbb0d3d24 r2314381 27 27 # 28 28 29 EXTRA_CFLAGS = -D__32_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/ppc32.s -
uspace/srv/loader/arch/sparc64/Makefile.inc
rbb0d3d24 r2314381 27 27 # 28 28 29 EXTRA_CFLAGS = -D__64_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/sparc64.s
Note:
See TracChangeset
for help on using the changeset viewer.