+void Proc_DumpThreadCPUState(tThread *Thread)
+{
+ Uint32 *stack = (void *)Thread->SavedState.EBP; // EBP = ESP after call and PUSH
+
+ if( Thread->CurCPU > -1 )
+ {
+ Log(" Currently running");
+ return ;
+ }
+
+ #if 1
+ tVAddr diffFromScheduler = Thread->SavedState.EIP - (tVAddr)Proc_Scheduler;
+ tVAddr diffFromClone = Thread->SavedState.EIP - (tVAddr)Proc_Clone;
+ tVAddr diffFromSpawn = Thread->SavedState.EIP - (tVAddr)Proc_SpawnWorker;
+
+ if( diffFromClone > 0 && diffFromClone < 512 ) // When I last checked, GetEIP was at .+0x183
+ {
+ // Just spawned full thread
+ Log(" Creating full thread");
+ return ;
+ }
+
+ if( diffFromSpawn > 0 && diffFromSpawn < 512 ) // When I last checked, GetEIP was at .+0x99
+ {
+ // Just spawned worker thread
+ Log(" Creating worker thread");
+ return ;
+ }
+
+ if( diffFromScheduler > 0 && diffFromScheduler < 256 ) // When I last checked, GetEIP was at .+0x60
+ #else
+ if( stack[1] == (Uint32)&IRQCommon + 25 )
+ {
+ tRegs *regs = (void *) stack[2];
+ Log(" oldebp = 0x%08x, ret = 0x%08x, regs = 0x%x",
+ stack[0], stack[1], stack[2]
+ );
+ // [EBP] = old EBP
+ // [EBP+0x04] = Return Addr
+ // [EBP+0x08] = Arg 1 (CPU Number)
+ // [EBP+0x0C] = Arg 2 (Thread)
+ // [EBP+0x10] = GS (start of tRegs)
+ Log(" IRQ%i from %02x:%08x", regs->int_num regs->cs, regs->eip);
+ }
+ if( stack[1] == (Uint32)&scheduler_return )
+ #endif
+ {
+ // Scheduled out
+ tRegs *regs = (void *) &stack[4];
+ Log(" oldebp = 0x%08x, ret = 0x%08x, cpu = %i, thread = 0x%x",
+ stack[0], stack[1], stack[2], stack[3]);
+ // [EBP] = old EBP
+ // [EBP+0x04] = Return Addr
+ // [EBP+0x08] = Arg 1 (CPU Number)
+ // [EBP+0x0C] = Arg 2 (Thread)
+ // [EBP+0x10] = GS (start of tRegs)
+ Log(" At %02x:%08x", regs->cs, regs->eip);
+ return ;
+ }
+
+ Log(" Just created");
+}
+