Changes in / [9d3133d:fea0ce6] in mainline
- Files:
-
- 4 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
HelenOS.config
r9d3133d rfea0ce6 486 486 % Mount /data on startup 487 487 ! [CONFIG_START_BD=y] CONFIG_MOUNT_DATA (n/y) 488 489 % Verbose task dumps 490 ! CONFIG_VERBOSE_DUMPS (n/y) -
boot/Makefile.common
r9d3133d rfea0ce6 56 56 $(USPACEDIR)/srv/fs/devfs/devfs \ 57 57 $(USPACEDIR)/srv/fs/tmpfs/tmpfs \ 58 $(USPACEDIR)/srv/fs/fat/fat 58 $(USPACEDIR)/srv/fs/fat/fat \ 59 $(USPACEDIR)/srv/taskmon/taskmon 59 60 60 61 RD_APPS = \ … … 65 66 $(USPACEDIR)/app/mkfat/mkfat \ 66 67 $(USPACEDIR)/app/redir/redir \ 68 $(USPACEDIR)/app/taskdump/taskdump \ 67 69 $(USPACEDIR)/app/tester/tester \ 68 70 $(USPACEDIR)/app/tetris/tetris \ -
kernel/generic/include/interrupt.h
r9d3133d rfea0ce6 46 46 typedef void (* iroutine)(int n, istate_t *istate); 47 47 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 48 extern void fault_if_from_uspace(istate_t *istate, char *fmt, ...); 61 49 extern iroutine exc_register(int n, const char *name, iroutine f); 62 50 extern void exc_dispatch(int n, istate_t *t); -
kernel/generic/include/ipc/event_types.h
r9d3133d rfea0ce6 37 37 38 38 typedef enum event_type { 39 /** New data available in kernel log */ 39 40 EVENT_KLOG = 0, 41 /** Returning from kernel console to userspace */ 40 42 EVENT_KCONSOLE, 43 /** A thread has faulted and will be terminated */ 44 EVENT_FAULT, 41 45 EVENT_END 42 46 } event_type_t; -
kernel/generic/include/mm/as.h
r9d3133d rfea0ce6 36 36 #define KERN_AS_H_ 37 37 38 #ifdef KERNEL 39 #include <arch/types.h> 40 #else 41 #include <sys/types.h> 42 #endif 43 38 44 /** Address space area flags. */ 39 45 #define AS_AREA_READ 1 … … 41 47 #define AS_AREA_EXEC 4 42 48 #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; 43 61 44 62 #ifdef KERNEL … … 268 286 269 287 /* Introspection functions. */ 288 extern void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize); 270 289 extern void as_print(as_t *as); 271 290 -
kernel/generic/include/udebug/udebug.h
r9d3133d rfea0ce6 96 96 */ 97 97 UDEBUG_M_THREAD_READ, 98 99 /** Read the list of the debugged task's address space areas. 100 * 101 * - ARG2 - destination address in the caller's address space 102 * - ARG3 - size of receiving buffer in bytes 103 * 104 * The kernel fills the buffer with a series of as_area_info_t structures. 105 * Upon answer, the kernel will set: 106 * 107 * - ARG2 - number of bytes that were actually copied 108 * - ARG3 - number of bytes of the complete data 109 * 110 */ 111 UDEBUG_M_AREAS_READ, 98 112 99 113 /** Read the debugged tasks's memory. … … 139 153 140 154 #include <synch/mutex.h> 155 #include <synch/condvar.h> 141 156 #include <arch/interrupt.h> 142 157 #include <atomic.h> … … 181 196 bool stoppable; /**< thread is stoppable */ 182 197 bool active; /**< thread is in a debugging session */ 198 condvar_t active_cv; 183 199 } udebug_thread_t; 184 200 -
kernel/generic/include/udebug/udebug_ops.h
r9d3133d rfea0ce6 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 *n); 47 int udebug_thread_read(void **buffer, size_t buf_size, size_t *stored, 48 size_t *needed); 48 49 int udebug_args_read(thread_t *t, void **buffer); 49 50 -
kernel/generic/src/interrupt/interrupt.c
r9d3133d rfea0ce6 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> 46 50 #include <panic.h> 47 51 #include <print.h> … … 107 111 fault_if_from_uspace(istate, "Unhandled exception %d.", n); 108 112 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 if (event_is_subscribed(EVENT_FAULT)) { 137 event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid), 138 UPPER32(TASK->taskid), (unative_t) THREAD); 139 } 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 157 158 task_kill(task->taskid); 159 thread_exit(); 109 160 } 110 161 -
kernel/generic/src/mm/as.c
r9d3133d rfea0ce6 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 1922 1988 /** Print out information about address space. 1923 1989 * -
kernel/generic/src/udebug/udebug.c
r9d3133d rfea0ce6 69 69 mutex_initialize(&ut->lock, MUTEX_PASSIVE); 70 70 waitq_initialize(&ut->go_wq); 71 condvar_initialize(&ut->active_cv); 71 72 72 73 ut->go_call = NULL; … … 446 447 waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST); 447 448 } 449 mutex_unlock(&t->udebug.lock); 450 condvar_broadcast(&t->udebug.active_cv); 451 } else { 452 mutex_unlock(&t->udebug.lock); 448 453 } 449 mutex_unlock(&t->udebug.lock);450 454 } 451 455 -
kernel/generic/src/udebug/udebug_ipc.c
r9d3133d rfea0ce6 41 41 #include <proc/task.h> 42 42 #include <proc/thread.h> 43 #include <mm/as.h> 43 44 #include <arch.h> 44 45 #include <errno.h> … … 165 166 static void udebug_receive_thread_read(call_t *call) 166 167 { 168 uintptr_t uspace_addr; 169 size_t buf_size; 170 void *buffer; 171 size_t copied, needed; 172 int rc; 173 174 uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */ 175 buf_size = IPC_GET_ARG3(call->data); /* Dest. buffer size */ 176 177 /* 178 * Read thread list. Variable n will be filled with actual number 179 * of threads times thread-id size. 180 */ 181 rc = udebug_thread_read(&buffer, buf_size, &copied, &needed); 182 if (rc < 0) { 183 IPC_SET_RETVAL(call->data, rc); 184 ipc_answer(&TASK->kb.box, call); 185 return; 186 } 187 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 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) 212 { 167 213 unative_t uspace_addr; 168 214 unative_t to_copy; 169 unsigned total_bytes; 170 unsigned buf_size; 171 void *buffer; 172 size_t n; 173 int rc; 215 size_t data_size; 216 size_t buf_size; 217 void *data; 174 218 175 219 uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */ … … 177 221 178 222 /* 179 * Read thread list. Variable n will be filled with actual number 180 * of threads times thread-id size. 181 */ 182 rc = udebug_thread_read(&buffer, buf_size, &n); 183 if (rc < 0) { 184 IPC_SET_RETVAL(call->data, rc); 185 ipc_answer(&TASK->kb.box, call); 186 return; 187 } 188 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; 223 * Read area list. 224 */ 225 as_get_area_info(AS, (as_area_info_t **) &data, &data_size); 226 227 /* Copy MAX(buf_size, data_size) bytes */ 228 229 if (buf_size > data_size) 230 to_copy = data_size; 195 231 else 196 232 to_copy = buf_size; … … 207 243 IPC_SET_ARG2(call->data, to_copy); 208 244 209 IPC_SET_ARG3(call->data, total_bytes); 210 call->buffer = buffer; 211 212 ipc_answer(&TASK->kb.box, call); 213 } 245 IPC_SET_ARG3(call->data, data_size); 246 call->buffer = data; 247 248 ipc_answer(&TASK->kb.box, call); 249 } 250 214 251 215 252 /** Process an ARGS_READ call. … … 331 368 udebug_receive_thread_read(call); 332 369 break; 370 case UDEBUG_M_AREAS_READ: 371 udebug_receive_areas_read(call); 372 break; 333 373 case UDEBUG_M_ARGS_READ: 334 374 udebug_receive_args_read(call); -
kernel/generic/src/udebug/udebug_ops.c
r9d3133d rfea0ce6 209 209 210 210 mutex_lock(&t->udebug.lock); 211 if ((t->flags & THREAD_FLAG_USPACE) != 0) 211 if ((t->flags & THREAD_FLAG_USPACE) != 0) { 212 212 t->udebug.active = true; 213 mutex_unlock(&t->udebug.lock); 213 mutex_unlock(&t->udebug.lock); 214 condvar_broadcast(&t->udebug.active_cv); 215 } else { 216 mutex_unlock(&t->udebug.lock); 217 } 214 218 } 215 219 … … 355 359 * 356 360 * If the sequence is longer than @a buf_size bytes, only as much hashes 357 * as can fit are copied. The number of thread hashes copied is stored 358 * in @a n. 361 * as can fit are copied. The number of bytes copied is stored in @a stored. 362 * The total number of thread bytes that could have been saved had there been 363 * enough space is stored in @a needed. 359 364 * 360 365 * The rationale for having @a buf_size is that this function is only … … 364 369 * @param buffer The buffer for storing thread hashes. 365 370 * @param buf_size Buffer size in bytes. 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) 371 * @param stored The actual number of bytes copied will be stored here. 372 * @param needed Total number of hashes that could have been saved. 373 */ 374 int udebug_thread_read(void **buffer, size_t buf_size, size_t *stored, 375 size_t *needed) 369 376 { 370 377 thread_t *t; 371 378 link_t *cur; 372 379 unative_t tid; 373 unsigned copied_ids; 380 size_t copied_ids; 381 size_t extra_ids; 374 382 ipl_t ipl; 375 383 unative_t *id_buffer; … … 380 388 381 389 /* Allocate a buffer to hold thread IDs */ 382 id_buffer = malloc(buf_size , 0);390 id_buffer = malloc(buf_size + 1, 0); 383 391 384 392 mutex_lock(&TASK->udebug.lock); … … 396 404 max_ids = buf_size / sizeof(unative_t); 397 405 copied_ids = 0; 406 extra_ids = 0; 398 407 399 408 /* FIXME: make sure the thread isn't past debug shutdown... */ 400 409 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 404 410 t = list_get_instance(cur, thread_t, th_link); 405 411 … … 409 415 410 416 /* Not interested in kernel threads. */ 411 if ((flags & THREAD_FLAG_USPACE) != 0) { 417 if ((flags & THREAD_FLAG_USPACE) == 0) 418 continue; 419 420 if (copied_ids < max_ids) { 412 421 /* Using thread struct pointer as identification hash */ 413 422 tid = (unative_t) t; 414 423 id_buffer[copied_ids++] = tid; 424 } else { 425 extra_ids++; 415 426 } 416 427 } … … 422 433 423 434 *buffer = id_buffer; 424 *n = copied_ids * sizeof(unative_t); 435 *stored = copied_ids * sizeof(unative_t); 436 *needed = (copied_ids + extra_ids) * sizeof(unative_t); 425 437 426 438 return 0; -
uspace/Makefile
r9d3133d rfea0ce6 40 40 app/mkfat \ 41 41 app/redir \ 42 app/taskdump \ 42 43 app/tester \ 43 44 app/tetris \ … … 47 48 srv/loader \ 48 49 srv/ns \ 50 srv/taskmon \ 49 51 srv/vfs \ 50 52 srv/bd/ata_bd \ -
uspace/app/init/init.c
r9d3133d rfea0ce6 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 else 246 printf("Failed\n"); 247 } 248 235 249 static void mount_data(void) 236 250 { … … 255 269 return -1; 256 270 } 271 272 /* Make sure tmpfs is running. */ 273 if (str_cmp(STRING(RDFMT), "tmpfs") != 0) { 274 spawn("/srv/tmpfs"); 275 } 257 276 258 277 spawn("/srv/devfs"); 278 spawn("/srv/taskmon"); 259 279 260 280 if (!mount_devfs()) { … … 262 282 return -2; 263 283 } 284 285 mount_scratch(); 264 286 265 287 spawn("/srv/fhc"); -
uspace/lib/libc/generic/udebug.c
r9d3133d rfea0ce6 69 69 } 70 70 71 int udebug_areas_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_AREAS_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 71 87 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n) 72 88 { -
uspace/lib/libc/include/udebug.h
r9d3133d rfea0ce6 47 47 int udebug_thread_read(int phoneid, void *buffer, size_t n, 48 48 size_t *copied, size_t *needed); 49 int udebug_areas_read(int phoneid, void *buffer, size_t n, 50 size_t *copied, size_t *needed); 49 51 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n); 50 52 int udebug_args_read(int phoneid, thash_t tid, sysarg_t *buffer);
Note:
See TracChangeset
for help on using the changeset viewer.