Changes in / [bca408b:1715b6af] in mainline
- Files:
-
- 10 added
- 65 deleted
- 42 edited
Legend:
- Unmodified
- Added
- Removed
-
HelenOS.config
rbca408b r1715b6af 31 31 32 32 % Platform 33 @ "abs32le" abstract 32-bit little endian34 33 @ "amd64" AMD64/Intel EM64T (PC) 35 34 @ "arm32" ARM 32-bit … … 92 91 93 92 % Kernel architecture 94 @ "abs32le"95 ! [PLATFORM=abs32le] KARCH (choice)96 97 % Kernel architecture98 93 @ "amd64" 99 94 ! [PLATFORM=amd64] KARCH (choice) … … 135 130 136 131 % User space architecture 137 @ "abs32le"138 ! [PLATFORM=abs32le] UARCH (choice)139 140 % User space architecture141 132 @ "amd64" 142 133 ! [PLATFORM=amd64] UARCH (choice) … … 176 167 177 168 ## Mapping between platform and boot architecture 178 179 % Boot architecture180 @ "abs32le"181 ! [PLATFORM=abs32le] BARCH (choice)182 169 183 170 % Boot architecture … … 256 243 ! [PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] COMPILER (choice) 257 244 258 % Compiler259 @ "gcc_native" GNU C Compiler (native)260 @ "clang" Clang261 ! [PLATFORM=abs32le] COMPILER (choice)262 263 245 264 246 ## Kernel configuration … … 277 259 278 260 % Hierarchical page tables support 279 ! [PLATFORM= abs32le|PLATFORM=ia32|PLATFORM=amd64|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] CONFIG_PAGE_PT (y)261 ! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] CONFIG_PAGE_PT (y) 280 262 281 263 % Page hash table support … … 504 486 % Mount /data on startup 505 487 ! [CONFIG_START_BD=y] CONFIG_MOUNT_DATA (n/y) 506 507 % Verbose task dumps508 ! CONFIG_VERBOSE_DUMPS (n/y) -
Makefile
rbca408b r1715b6af 59 59 60 60 distclean: clean 61 rm -f $(CSCOPE).out Makefile.config config.h config.defs tools/*.pyc tools/checkers/*.pyc61 rm -f $(CSCOPE).out Makefile.config config.h config.defs tools/*.pyc 62 62 63 63 clean: -
boot/Makefile.common
rbca408b r1715b6af 56 56 $(USPACEDIR)/srv/fs/devfs/devfs \ 57 57 $(USPACEDIR)/srv/fs/tmpfs/tmpfs \ 58 $(USPACEDIR)/srv/fs/fat/fat \ 59 $(USPACEDIR)/srv/taskmon/taskmon 58 $(USPACEDIR)/srv/fs/fat/fat 60 59 61 60 RD_APPS = \ … … 66 65 $(USPACEDIR)/app/mkfat/mkfat \ 67 66 $(USPACEDIR)/app/redir/redir \ 68 $(USPACEDIR)/app/taskdump/taskdump \69 67 $(USPACEDIR)/app/tester/tester \ 70 68 $(USPACEDIR)/app/tetris/tetris \ -
kernel/generic/include/interrupt.h
rbca408b r1715b6af 46 46 typedef void (* iroutine)(int n, istate_t *istate); 47 47 48 extern void fault_if_from_uspace(istate_t *istate, char *fmt, ...); 48 #define fault_if_from_uspace(istate, fmt, ...) \ 49 { \ 50 if (istate_from_uspace(istate)) { \ 51 task_t *task = TASK; \ 52 printf("Task %s (%" PRIu64 ") killed due to an exception at " \ 53 "program counter %p.\n", task->name, task->taskid, istate_get_pc(istate)); \ 54 stack_trace_istate(istate); \ 55 printf("Kill message: " fmt "\n", ##__VA_ARGS__); \ 56 task_kill(task->taskid); \ 57 thread_exit(); \ 58 } \ 59 } 60 49 61 extern iroutine exc_register(int n, const char *name, iroutine f); 50 62 extern void exc_dispatch(int n, istate_t *t); -
kernel/generic/include/ipc/event_types.h
rbca408b r1715b6af 37 37 38 38 typedef enum event_type { 39 /** New data available in kernel log */40 39 EVENT_KLOG = 0, 41 /** Returning from kernel console to userspace */42 40 EVENT_KCONSOLE, 43 /** A thread has faulted and will be terminated */44 EVENT_FAULT,45 41 EVENT_END 46 42 } event_type_t; -
kernel/generic/include/mm/as.h
rbca408b r1715b6af 36 36 #define KERN_AS_H_ 37 37 38 #ifdef KERNEL39 #include <arch/types.h>40 #else41 #include <sys/types.h>42 #endif43 44 38 /** Address space area flags. */ 45 39 #define AS_AREA_READ 1 … … 47 41 #define AS_AREA_EXEC 4 48 42 #define AS_AREA_CACHEABLE 8 49 50 /** Address space area info exported to userspace. */51 typedef struct {52 /** Starting address */53 uintptr_t start_addr;54 55 /** Area size */56 size_t size;57 58 /** Area flags */59 int flags;60 } as_area_info_t;61 43 62 44 #ifdef KERNEL … … 286 268 287 269 /* Introspection functions. */ 288 extern void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize);289 270 extern void as_print(as_t *as); 290 271 -
kernel/generic/include/udebug/udebug.h
rbca408b r1715b6af 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 identification88 * - ARG3 - destination address in the caller's address space89 *90 * or, on error, retval will be91 * - ENOENT - thread does not exist92 * - EBUSY - register state not available93 */94 UDEBUG_M_REGS_READ,95 96 85 /** Read the list of the debugged tasks's threads. 97 86 * … … 107 96 */ 108 97 UDEBUG_M_THREAD_READ, 109 110 /** Read the name of the debugged task.111 *112 * - ARG2 - destination address in the caller's address space113 * - ARG3 - size of receiving buffer in bytes114 *115 * The kernel fills the buffer with a non-terminated string.116 *117 * - ARG2 - number of bytes that were actually copied118 * - ARG3 - number of bytes of the complete data119 *120 */121 UDEBUG_M_NAME_READ,122 123 /** Read the list of the debugged task's address space areas.124 *125 * - ARG2 - destination address in the caller's address space126 * - ARG3 - size of receiving buffer in bytes127 *128 * The kernel fills the buffer with a series of as_area_info_t structures.129 * Upon answer, the kernel will set:130 *131 * - ARG2 - number of bytes that were actually copied132 * - ARG3 - number of bytes of the complete data133 *134 */135 UDEBUG_M_AREAS_READ,136 98 137 99 /** Read the debugged tasks's memory. … … 146 108 } udebug_method_t; 147 109 148 110 149 111 typedef enum { 150 112 UDEBUG_EVENT_FINISHED = 1, /**< Debuging session has finished */ … … 177 139 178 140 #include <synch/mutex.h> 179 #include <synch/condvar.h>180 141 #include <arch/interrupt.h> 181 142 #include <atomic.h> … … 220 181 bool stoppable; /**< thread is stoppable */ 221 182 bool active; /**< thread is in a debugging session */ 222 condvar_t active_cv;223 183 } udebug_thread_t; 224 184 … … 242 202 243 203 int udebug_task_cleanup(struct task *ta); 244 void udebug_thread_fault(void);245 204 246 205 #endif -
kernel/generic/include/udebug/udebug_ops.h
rbca408b r1715b6af 45 45 int udebug_stop(thread_t *t, call_t *call); 46 46 47 int udebug_thread_read(void **buffer, size_t buf_size, size_t *stored, 48 size_t *needed); 49 int udebug_name_read(char **data, size_t *data_size); 47 int udebug_thread_read(void **buffer, size_t buf_size, size_t *n); 50 48 int udebug_args_read(thread_t *t, void **buffer); 51 52 int udebug_regs_read(thread_t *t, void **buffer);53 49 54 50 int udebug_mem_read(unative_t uspace_addr, size_t n, void **buffer); -
kernel/generic/src/interrupt/interrupt.c
rbca408b r1715b6af 44 44 #include <console/console.h> 45 45 #include <console/cmd.h> 46 #include <ipc/event.h>47 #include <synch/mutex.h>48 #include <time/delay.h>49 #include <macros.h>50 46 #include <panic.h> 51 47 #include <print.h> … … 111 107 fault_if_from_uspace(istate, "Unhandled exception %d.", n); 112 108 panic("Unhandled exception %d.", n); 113 }114 115 /** Terminate thread and task if exception came from userspace. */116 void fault_if_from_uspace(istate_t *istate, char *fmt, ...)117 {118 task_t *task = TASK;119 va_list args;120 121 if (!istate_from_uspace(istate))122 return;123 124 printf("Task %s (%" PRIu64 ") killed due to an exception at "125 "program counter %p.\n", task->name, task->taskid,126 istate_get_pc(istate));127 128 stack_trace_istate(istate);129 130 printf("Kill message: ");131 va_start(args, fmt);132 vprintf(fmt, args);133 va_end(args);134 printf("\n");135 136 /*137 * Userspace can subscribe for FAULT events to take action138 * 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 */142 if (event_is_subscribed(EVENT_FAULT)) {143 /* Notify the subscriber that a fault occurred. */144 event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid),145 UPPER32(TASK->taskid), (unative_t) THREAD);146 147 #ifdef CONFIG_UDEBUG148 /* Wait for a debugging session. */149 udebug_thread_fault();150 #endif151 }152 153 task_kill(task->taskid);154 thread_exit();155 109 } 156 110 -
kernel/generic/src/mm/as.c
rbca408b r1715b6af 1920 1920 } 1921 1921 1922 /** Get list of adress space areas.1923 *1924 * @param as Address space.1925 * @param obuf Place to save pointer to returned buffer.1926 * @param osize Place to save size of returned buffer.1927 */1928 void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize)1929 {1930 ipl_t ipl;1931 size_t area_cnt, area_idx, i;1932 link_t *cur;1933 1934 as_area_info_t *info;1935 size_t isize;1936 1937 ipl = interrupts_disable();1938 mutex_lock(&as->lock);1939 1940 /* First pass, count number of areas. */1941 1942 area_cnt = 0;1943 1944 for (cur = as->as_area_btree.leaf_head.next;1945 cur != &as->as_area_btree.leaf_head; cur = cur->next) {1946 btree_node_t *node;1947 1948 node = list_get_instance(cur, btree_node_t, leaf_link);1949 area_cnt += node->keys;1950 }1951 1952 isize = area_cnt * sizeof(as_area_info_t);1953 info = malloc(isize, 0);1954 1955 /* Second pass, record data. */1956 1957 area_idx = 0;1958 1959 for (cur = as->as_area_btree.leaf_head.next;1960 cur != &as->as_area_btree.leaf_head; cur = cur->next) {1961 btree_node_t *node;1962 1963 node = list_get_instance(cur, btree_node_t, leaf_link);1964 1965 for (i = 0; i < node->keys; i++) {1966 as_area_t *area = node->value[i];1967 1968 ASSERT(area_idx < area_cnt);1969 mutex_lock(&area->lock);1970 1971 info[area_idx].start_addr = area->base;1972 info[area_idx].size = FRAMES2SIZE(area->pages);1973 info[area_idx].flags = area->flags;1974 ++area_idx;1975 1976 mutex_unlock(&area->lock);1977 }1978 }1979 1980 mutex_unlock(&as->lock);1981 interrupts_restore(ipl);1982 1983 *obuf = info;1984 *osize = isize;1985 }1986 1987 1988 1922 /** Print out information about address space. 1989 1923 * -
kernel/generic/src/udebug/udebug.c
rbca408b r1715b6af 69 69 mutex_initialize(&ut->lock, MUTEX_PASSIVE); 70 70 waitq_initialize(&ut->go_wq); 71 condvar_initialize(&ut->active_cv);72 71 73 72 ut->go_call = NULL; … … 447 446 waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST); 448 447 } 449 mutex_unlock(&t->udebug.lock);450 condvar_broadcast(&t->udebug.active_cv);451 } else {452 mutex_unlock(&t->udebug.lock);453 448 } 449 mutex_unlock(&t->udebug.lock); 454 450 } 455 451 … … 460 456 } 461 457 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 userspace466 * a chance to examine the faulting thead/task. When the debugging session467 * 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 }487 458 488 459 /** @} -
kernel/generic/src/udebug/udebug_ipc.c
rbca408b r1715b6af 41 41 #include <proc/task.h> 42 42 #include <proc/thread.h> 43 #include <mm/as.h>44 43 #include <arch.h> 45 44 #include <errno.h> … … 166 165 static void udebug_receive_thread_read(call_t *call) 167 166 { 168 uintptr_t uspace_addr; 169 size_t buf_size; 167 unative_t uspace_addr; 168 unative_t to_copy; 169 unsigned total_bytes; 170 unsigned buf_size; 170 171 void *buffer; 171 size_t copied, needed;172 size_t n; 172 173 int rc; 173 174 … … 179 180 * of threads times thread-id size. 180 181 */ 181 rc = udebug_thread_read(&buffer, buf_size, & copied, &needed);182 rc = udebug_thread_read(&buffer, buf_size, &n); 182 183 if (rc < 0) { 183 184 IPC_SET_RETVAL(call->data, rc); … … 186 187 } 187 188 188 /* 189 * Make use of call->buffer to transfer data to caller's userspace 190 */ 191 192 IPC_SET_RETVAL(call->data, 0); 193 /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that 194 same code in process_answer() can be used 195 (no way to distinguish method in answer) */ 196 IPC_SET_ARG1(call->data, uspace_addr); 197 IPC_SET_ARG2(call->data, copied); 198 IPC_SET_ARG3(call->data, needed); 199 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 */ 210 static 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; 189 total_bytes = n; 190 191 /* Copy MAX(buf_size, total_bytes) bytes */ 192 193 if (buf_size > total_bytes) 194 to_copy = total_bytes; 230 195 else 231 196 to_copy = buf_size; … … 242 207 IPC_SET_ARG2(call->data, to_copy); 243 208 244 IPC_SET_ARG3(call->data, data_size); 245 call->buffer = data; 246 247 ipc_answer(&TASK->kb.box, call); 248 } 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 209 IPC_SET_ARG3(call->data, total_bytes); 210 call->buffer = buffer; 211 212 ipc_answer(&TASK->kb.box, call); 213 } 297 214 298 215 /** Process an ARGS_READ call. … … 333 250 ipc_answer(&TASK->kb.box, call); 334 251 } 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 userspace359 */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 that366 same code in process_answer() can be used367 (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 376 252 377 253 /** Process an MEM_READ call. … … 455 331 udebug_receive_thread_read(call); 456 332 break; 457 case UDEBUG_M_NAME_READ:458 udebug_receive_name_read(call);459 break;460 case UDEBUG_M_AREAS_READ:461 udebug_receive_areas_read(call);462 break;463 333 case UDEBUG_M_ARGS_READ: 464 334 udebug_receive_args_read(call); 465 335 break; 466 case UDEBUG_M_REGS_READ:467 udebug_receive_regs_read(call);468 break;469 336 case UDEBUG_M_MEM_READ: 470 337 udebug_receive_mem_read(call); -
kernel/generic/src/udebug/udebug_ops.c
rbca408b r1715b6af 46 46 #include <errno.h> 47 47 #include <print.h> 48 #include <string.h>49 48 #include <syscall/copy.h> 50 49 #include <ipc/ipc.h> … … 210 209 211 210 mutex_lock(&t->udebug.lock); 212 if ((t->flags & THREAD_FLAG_USPACE) != 0) {211 if ((t->flags & THREAD_FLAG_USPACE) != 0) 213 212 t->udebug.active = true; 214 mutex_unlock(&t->udebug.lock); 215 condvar_broadcast(&t->udebug.active_cv); 216 } else { 217 mutex_unlock(&t->udebug.lock); 218 } 213 mutex_unlock(&t->udebug.lock); 219 214 } 220 215 … … 360 355 * 361 356 * If the sequence is longer than @a buf_size bytes, only as much hashes 362 * as can fit are copied. The number of bytes copied is stored in @a stored. 363 * The total number of thread bytes that could have been saved had there been 364 * enough space is stored in @a needed. 357 * as can fit are copied. The number of thread hashes copied is stored 358 * in @a n. 365 359 * 366 360 * The rationale for having @a buf_size is that this function is only … … 370 364 * @param buffer The buffer for storing thread hashes. 371 365 * @param buf_size Buffer size in bytes. 372 * @param stored The actual number of bytes copied will be stored here. 373 * @param needed Total number of hashes that could have been saved. 374 */ 375 int udebug_thread_read(void **buffer, size_t buf_size, size_t *stored, 376 size_t *needed) 366 * @param n The actual number of hashes copied will be stored here. 367 */ 368 int udebug_thread_read(void **buffer, size_t buf_size, size_t *n) 377 369 { 378 370 thread_t *t; 379 371 link_t *cur; 380 372 unative_t tid; 381 size_t copied_ids; 382 size_t extra_ids; 373 unsigned copied_ids; 383 374 ipl_t ipl; 384 375 unative_t *id_buffer; … … 389 380 390 381 /* Allocate a buffer to hold thread IDs */ 391 id_buffer = malloc(buf_size + 1, 0);382 id_buffer = malloc(buf_size, 0); 392 383 393 384 mutex_lock(&TASK->udebug.lock); … … 405 396 max_ids = buf_size / sizeof(unative_t); 406 397 copied_ids = 0; 407 extra_ids = 0;408 398 409 399 /* FIXME: make sure the thread isn't past debug shutdown... */ 410 400 for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) { 401 /* Do not write past end of buffer */ 402 if (copied_ids >= max_ids) break; 403 411 404 t = list_get_instance(cur, thread_t, th_link); 412 405 … … 416 409 417 410 /* Not interested in kernel threads. */ 418 if ((flags & THREAD_FLAG_USPACE) == 0) 419 continue; 420 421 if (copied_ids < max_ids) { 411 if ((flags & THREAD_FLAG_USPACE) != 0) { 422 412 /* Using thread struct pointer as identification hash */ 423 413 tid = (unative_t) t; 424 414 id_buffer[copied_ids++] = tid; 425 } else {426 extra_ids++;427 415 } 428 416 } … … 434 422 435 423 *buffer = id_buffer; 436 *stored = copied_ids * sizeof(unative_t); 437 *needed = (copied_ids + extra_ids) * sizeof(unative_t); 438 439 return 0; 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); 424 *n = copied_ids * sizeof(unative_t); 461 425 462 426 return 0; … … 473 437 * this function will fail with an EINVAL error code. 474 438 * 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. 439 * @param buffer The buffer for storing thread hashes. 479 440 */ 480 441 int udebug_args_read(thread_t *t, void **buffer) … … 508 469 } 509 470 510 /** Read the register state of the thread.511 *512 * The contents of the thread's istate structure are copied to a newly513 * allocated buffer and a pointer to it is written to @a buffer. The size of514 * the buffer will be sizeof(istate_t).515 *516 * Currently register state cannot be read if the thread is inside a system517 * 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, EINVAL522 * if thread is not in valid state, EBUSY if istate523 * 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 554 471 /** Read the memory of the debugged task. 555 472 * -
uspace/Makefile
rbca408b r1715b6af 40 40 app/mkfat \ 41 41 app/redir \ 42 app/taskdump \43 42 app/tester \ 44 43 app/tetris \ … … 48 47 srv/loader \ 49 48 srv/ns \ 50 srv/taskmon \51 49 srv/vfs \ 52 50 srv/bd/ata_bd \ -
uspace/app/init/init.c
rbca408b r1715b6af 233 233 } 234 234 235 static void mount_scratch(void)236 {237 int rc;238 239 printf("Trying to mount null/0 on /scratch... ");240 fflush(stdout);241 242 rc = mount("tmpfs", "/scratch", "null/0", "", 0);243 if (rc == EOK)244 printf("OK\n");245 else246 printf("Failed\n");247 }248 249 235 static void mount_data(void) 250 236 { … … 269 255 return -1; 270 256 } 271 272 /* Make sure tmpfs is running. */273 if (str_cmp(STRING(RDFMT), "tmpfs") != 0) {274 spawn("/srv/tmpfs");275 }276 257 277 258 spawn("/srv/devfs"); 278 spawn("/srv/taskmon");279 259 280 260 if (!mount_devfs()) { … … 282 262 return -2; 283 263 } 284 285 mount_scratch();286 264 287 265 spawn("/srv/fhc"); -
uspace/lib/libc/arch/amd64/Makefile.inc
rbca408b r1715b6af 37 37 arch/$(UARCH)/src/fibril.S \ 38 38 arch/$(UARCH)/src/tls.c \ 39 arch/$(UARCH)/src/stacktrace.c \ 40 arch/$(UARCH)/src/stacktrace_asm.S 39 arch/$(UARCH)/src/stacktrace.S 41 40 42 41 GCC_CFLAGS += -fno-omit-frame-pointer -
uspace/lib/libc/arch/amd64/include/types.h
rbca408b r1715b6af 36 36 #define LIBC_amd64_TYPES_H_ 37 37 38 #define __64_BITS__39 40 38 typedef unsigned long long sysarg_t; 41 39 -
uspace/lib/libc/arch/arm32/Makefile.inc
rbca408b r1715b6af 38 38 arch/$(UARCH)/src/tls.c \ 39 39 arch/$(UARCH)/src/eabi.S \ 40 arch/$(UARCH)/src/stacktrace.c \ 41 arch/$(UARCH)/src/stacktrace_asm.S 40 arch/$(UARCH)/src/stacktrace.S 42 41 43 42 GCC_CFLAGS += -ffixed-r9 -mtp=soft -mapcs-frame -fno-omit-frame-pointer -
uspace/lib/libc/arch/arm32/include/types.h
rbca408b r1715b6af 37 37 #define LIBC_arm32_TYPES_H_ 38 38 39 #define __32_BITS__40 41 39 typedef unsigned int sysarg_t; 42 40 -
uspace/lib/libc/arch/ia32/Makefile.inc
rbca408b r1715b6af 38 38 arch/$(UARCH)/src/tls.c \ 39 39 arch/$(UARCH)/src/setjmp.S \ 40 arch/$(UARCH)/src/stacktrace.c \ 41 arch/$(UARCH)/src/stacktrace_asm.S 40 arch/$(UARCH)/src/stacktrace.S 42 41 43 42 GCC_CFLAGS += -march=pentium -
uspace/lib/libc/arch/ia32/include/types.h
rbca408b r1715b6af 36 36 #define LIBC_ia32_TYPES_H_ 37 37 38 #define __32_BITS__39 40 38 typedef unsigned int sysarg_t; 41 39 -
uspace/lib/libc/arch/ia64/Makefile.inc
rbca408b r1715b6af 37 37 arch/$(UARCH)/src/tls.c \ 38 38 arch/$(UARCH)/src/ddi.c \ 39 arch/$(UARCH)/src/stacktrace.c \ 40 arch/$(UARCH)/src/stacktrace_asm.S 39 arch/$(UARCH)/src/stacktrace.S 41 40 42 41 GCC_CFLAGS += -fno-unwind-tables -
uspace/lib/libc/arch/ia64/include/types.h
rbca408b r1715b6af 36 36 #define LIBC_ia64_TYPES_H_ 37 37 38 #define __64_BITS__39 40 38 typedef unsigned long long sysarg_t; 41 39 -
uspace/lib/libc/arch/mips32/Makefile.inc
rbca408b r1715b6af 36 36 arch/$(UARCH)/src/fibril.S \ 37 37 arch/$(UARCH)/src/tls.c \ 38 arch/$(UARCH)/src/stacktrace.c \ 39 arch/$(UARCH)/src/stacktrace_asm.S 38 arch/$(UARCH)/src/stacktrace.S 40 39 41 40 GCC_CFLAGS += -mips3 -
uspace/lib/libc/arch/mips32/include/types.h
rbca408b r1715b6af 37 37 #define LIBC_mips32_TYPES_H_ 38 38 39 #define __32_BITS__40 41 39 typedef unsigned int sysarg_t; 42 40 -
uspace/lib/libc/arch/mips32eb/Makefile.inc
rbca408b r1715b6af 36 36 arch/$(UARCH)/src/fibril.S \ 37 37 arch/$(UARCH)/src/tls.c \ 38 arch/$(UARCH)/src/stacktrace.c \ 39 arch/$(UARCH)/src/stacktrace_asm.S 38 arch/$(UARCH)/src/stacktrace.S 40 39 41 40 GCC_CFLAGS += -mips3 -
uspace/lib/libc/arch/ppc32/Makefile.inc
rbca408b r1715b6af 36 36 arch/$(UARCH)/src/fibril.S \ 37 37 arch/$(UARCH)/src/tls.c \ 38 arch/$(UARCH)/src/stacktrace.c \ 39 arch/$(UARCH)/src/stacktrace_asm.S 38 arch/$(UARCH)/src/stacktrace.S 40 39 41 40 GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32 -
uspace/lib/libc/arch/ppc32/include/types.h
rbca408b r1715b6af 36 36 #define LIBC_ppc32_TYPES_H_ 37 37 38 #define __32_BITS__39 40 38 typedef unsigned int sysarg_t; 41 39 -
uspace/lib/libc/arch/sparc64/Makefile.inc
rbca408b r1715b6af 35 35 ARCH_SOURCES += arch/$(UARCH)/src/fibril.S \ 36 36 arch/$(UARCH)/src/tls.c \ 37 arch/$(UARCH)/src/stacktrace.c \ 38 arch/$(UARCH)/src/stacktrace_asm.S 37 arch/$(UARCH)/src/stacktrace.S 39 38 40 39 GCC_CFLAGS += -mcpu=ultrasparc -m64 -
uspace/lib/libc/arch/sparc64/include/types.h
rbca408b r1715b6af 36 36 #define LIBC_sparc64_TYPES_H_ 37 37 38 #define __64_BITS__39 40 38 typedef unsigned long sysarg_t; 41 39 -
uspace/lib/libc/generic/stacktrace.c
rbca408b r1715b6af 1 1 /* 2 2 * Copyright (c) 2009 Jakub Jermar 3 * Copyright (c) 2010 Jiri Svoboda4 3 * All rights reserved. 5 4 * … … 37 36 #include <stdio.h> 38 37 #include <sys/types.h> 39 #include <errno.h>40 38 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) 39 void stack_trace_fp_pc(uintptr_t fp, uintptr_t pc) 44 40 { 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)) { 41 while (frame_pointer_validate(fp)) { 52 42 printf("%p: %p()\n", fp, pc); 53 (void) stacktrace_ra_get(&st, fp, &pc); 54 (void) stacktrace_fp_prev(&st, fp, &nfp); 55 fp = nfp; 43 pc = return_address_get(fp); 44 fp = frame_pointer_prev(fp); 56 45 } 57 46 } 58 47 59 void stack trace_print(void)48 void stack_trace(void) 60 49 { 61 stacktrace_prepare(); 62 stacktrace_print_fp_pc(stacktrace_fp_get(), stacktrace_pc_get()); 50 stack_trace_fp_pc(frame_pointer_get(), program_counter_get()); 63 51 /* 64 52 * Prevent the tail call optimization of the previous call by 65 53 * making it a non-tail call. 66 54 */ 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; 55 (void) frame_pointer_get(); 75 56 } 76 57 -
uspace/lib/libc/generic/udebug.c
rbca408b r1715b6af 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 86 int udebug_areas_read(int phoneid, void *buffer, size_t n,87 size_t *copied, size_t *needed)88 {89 ipcarg_t a_copied, a_needed;90 int rc;91 92 rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_AREAS_READ,93 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);94 95 *copied = (size_t)a_copied;96 *needed = (size_t)a_needed;97 98 return rc;99 }100 101 71 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n) 102 72 { … … 108 78 { 109 79 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,116 80 tid, (sysarg_t)buffer); 117 81 } -
uspace/lib/libc/include/stacktrace.h
rbca408b r1715b6af 1 1 /* 2 2 * Copyright (c) 2009 Jakub Jermar 3 * Copyright (c) 2010 Jiri Svoboda4 3 * All rights reserved. 5 4 * … … 40 39 #include <bool.h> 41 40 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); 41 extern void stack_trace(void); 42 extern void stack_trace_fp_pc(uintptr_t, uintptr_t); 49 43 50 44 /* 51 45 * The following interface is to be implemented by each architecture. 52 46 */ 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(); 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(); 60 52 61 53 #endif -
uspace/lib/libc/include/stdlib.h
rbca408b r1715b6af 42 42 #define abort() \ 43 43 do { \ 44 stack trace_print(); \44 stack_trace(); \ 45 45 _exit(1); \ 46 46 } while (0) -
uspace/lib/libc/include/udebug.h
rbca408b r1715b6af 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);51 int udebug_areas_read(int phoneid, void *buffer, size_t n,52 size_t *copied, size_t *needed);53 49 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n); 54 50 int udebug_args_read(int phoneid, thash_t tid, sysarg_t *buffer); 55 int udebug_regs_read(int phoneid, thash_t tid, void *buffer);56 51 int udebug_go(int phoneid, thash_t tid, udebug_event_t *ev_type, 57 52 sysarg_t *val0, sysarg_t *val1); -
uspace/srv/loader/arch/amd64/Makefile.inc
rbca408b r1715b6af 27 27 # 28 28 29 EXTRA_CFLAGS = -D__64_BITS__ 29 30 ARCH_SOURCES := arch/$(UARCH)/amd64.s -
uspace/srv/loader/arch/arm32/Makefile.inc
rbca408b r1715b6af 27 27 # 28 28 29 EXTRA_CFLAGS = -D__32_BITS__ 29 30 ARCH_SOURCES := arch/$(UARCH)/arm32.s -
uspace/srv/loader/arch/ia32/Makefile.inc
rbca408b r1715b6af 27 27 # 28 28 29 EXTRA_CFLAGS = -D__32_BITS__ 29 30 ARCH_SOURCES := arch/$(UARCH)/ia32.s -
uspace/srv/loader/arch/ia64/Makefile.inc
rbca408b r1715b6af 27 27 # 28 28 29 EXTRA_CFLAGS = -D__64_BITS__ 29 30 ARCH_SOURCES := arch/$(UARCH)/ia64.s 30 31 AFLAGS += -xexplicit -
uspace/srv/loader/arch/mips32/Makefile.inc
rbca408b r1715b6af 27 27 # 28 28 29 EXTRA_CFLAGS = -D__32_BITS__ 29 30 ARCH_SOURCES := arch/$(UARCH)/mips32.s -
uspace/srv/loader/arch/ppc32/Makefile.inc
rbca408b r1715b6af 27 27 # 28 28 29 EXTRA_CFLAGS = -D__32_BITS__ 29 30 ARCH_SOURCES := arch/$(UARCH)/ppc32.s -
uspace/srv/loader/arch/sparc64/Makefile.inc
rbca408b r1715b6af 27 27 # 28 28 29 EXTRA_CFLAGS = -D__64_BITS__ 29 30 ARCH_SOURCES := arch/$(UARCH)/sparc64.s
Note:
See TracChangeset
for help on using the changeset viewer.