Changeset 2314381 in mainline for kernel/generic/src/udebug
- Timestamp:
- 2010-01-26T22:49:26Z (16 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. - Location:
- kernel/generic/src/udebug
- Files:
-
- 3 edited
-
udebug.c (modified) (1 diff)
-
udebug_ipc.c (modified) (6 diffs)
-
udebug_ops.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
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 *
Note:
See TracChangeset
for help on using the changeset viewer.
