void tgdb_get_registers(mach_port_t thread, struct i386_thread_state *ss, struct i386_float_state *fs) { kern_return_t kr; mach_msg_type_number_t count; kr = thread_abort(thread); if (kr == KERN_NO_THREAD) { /* No thread attach to this activation */ bzero(ss, i386_THREAD_STATE_COUNT); bzero(fs, i386_FLOAT_STATE_COUNT); return; } if (kr != KERN_SUCCESS && kr != KERN_NO_THREAD) { printf("tgdb: can't abort thread\n"); return; } count = i386_THREAD_STATE_COUNT; kr = thread_get_state(thread, i386_THREAD_STATE, (thread_state_t) ss, &count); if (kr != KERN_SUCCESS) { printf("tgdb: can't get thread state\n"); return; } if (0 && tgdb_debug_flags & 256) { printf("\ntgdb_get_registers:\n"); print_thread_state(ss); } if (fs) { count = i386_FLOAT_STATE_COUNT; kr = thread_get_state(thread, i386_FLOAT_STATE, (thread_state_t)fs, &count); if (kr != KERN_SUCCESS) { printf("tgdb: can't get float thread state\n"); return; } } }
void tgdb_set_registers(mach_port_t thread, struct i386_thread_state *ss, struct i386_float_state *fs) { kern_return_t kr; kr = thread_abort(thread); if (kr == KERN_NO_THREAD) { return; } if (0 && tgdb_debug_flags & 256) { printf("\ntgdb_set_registers:\n"); print_thread_state(ss); } kr = thread_set_state(thread, i386_THREAD_STATE, (thread_state_t)ss, i386_THREAD_STATE_COUNT); if (kr != KERN_SUCCESS) { printf("tgdb: can't set thread state\n"); return; } if (fs) { kr = thread_set_state(thread, i386_FLOAT_STATE, (thread_state_t)fs, i386_FLOAT_STATE_COUNT); if (kr != KERN_SUCCESS) { printf("tgdb: can't set float state\n"); return; } } return; }
// Print the scheduler status. static void show_sched_status_wrk ( Bool host_stacktrace, Bool stack_usage, Bool exited_threads, const UnwindStartRegs* startRegsIN) { Int i; if (host_stacktrace) { const Bool save_clo_xml = VG_(clo_xml); Addr stacktop; Addr ips[BACKTRACE_DEPTH]; Int n_ips; ThreadState *tst = VG_(get_ThreadState)( VG_(lwpid_to_vgtid)( VG_(gettid)() ) ); // If necessary, fake up an ExeContext which is of our actual real CPU // state. Could cause problems if we got the panic/exception within the // execontext/stack dump/symtab code. But it's better than nothing. UnwindStartRegs startRegs; VG_(memset)(&startRegs, 0, sizeof(startRegs)); if (startRegsIN == NULL) { GET_STARTREGS(&startRegs); } else { startRegs = *startRegsIN; } stacktop = tst->os_state.valgrind_stack_init_SP; n_ips = VG_(get_StackTrace_wrk)( 0/*tid is unknown*/, ips, BACKTRACE_DEPTH, NULL/*array to dump SP values in*/, NULL/*array to dump FP values in*/, &startRegs, stacktop ); VG_(printf)("\nhost stacktrace:\n"); VG_(clo_xml) = False; VG_(pp_StackTrace) (ips, n_ips); VG_(clo_xml) = save_clo_xml; } VG_(printf)("\nsched status:\n"); if (VG_(threads) == NULL) { VG_(printf)(" scheduler not yet initialised\n"); } else { VG_(printf)(" running_tid=%u\n", VG_(get_running_tid)()); for (i = 1; i < VG_N_THREADS; i++) { VgStack *stack = (VgStack*)VG_(threads)[i].os_state.valgrind_stack_base; /* If a thread slot was never used (yet), valgrind_stack_base is 0. If a thread slot is used by a thread or was used by a thread which has exited, then valgrind_stack_base points to the stack base. */ if (VG_(threads)[i].status == VgTs_Empty && (!exited_threads || stack == 0)) continue; print_thread_state(stack_usage, "", i); if (VG_(inner_threads) != NULL) { /* An inner V has informed us (the outer) of its thread array. Report the inner guest stack trace. */ UInt inner_tid; for (inner_tid = 1; inner_tid < VG_N_THREADS; inner_tid++) { if (VG_(threads)[i].os_state.lwpid == VG_(inner_threads)[inner_tid].os_state.lwpid) { ThreadState* save_outer_vg_threads = VG_(threads); VG_(threads) = VG_(inner_threads); print_thread_state(stack_usage, "INNER ", inner_tid); VG_(threads) = save_outer_vg_threads; break; } } } } } VG_(printf)("\n"); }