/* * RecordSample - record a sample in a specific thread */ void RecordSample( unsigned offset, unsigned short segment, DWORD real_tid ) { samp_block *old_samples; unsigned old_sample_index; unsigned old_sample_count; thread_info *ti; DWORD tid; ti = getThreadInfo( real_tid ); if( ti == NULL ) { return; } tid = ti->index; LastSampleIndex = ti->SampleIndex; if( ti->SampleIndex == 0 ) { ti->Samples->pref.tick = CurrTick; if( CallGraphMode ) { ti->CallGraph->pref.tick = CurrTick; } } ++CurrTick; ti->Samples->d.sample.sample[ti->SampleIndex].offset = offset; ti->Samples->d.sample.sample[ti->SampleIndex].segment = segment; ti->SampleIndex++; if( CallGraphMode ) { ti->SampleCount++; } if( CallGraphMode && tid == 0 ) { old_sample_count = SampleCount; old_samples = Samples; /* since RecordCGraph isn't */ old_sample_index = SampleIndex; /* used to threads, we fool */ Samples = ti->Samples; /* it into storing the info */ SampleIndex = ti->SampleIndex; /* in the right place by */ SampleCount = ti->SampleCount; RecordCGraph(); /* changing its pointers */ ti->Samples = Samples; /* and restoring them later */ ti->SampleIndex = SampleIndex; ti->SampleCount = SampleCount; Samples = old_samples; SampleIndex = old_sample_index; SampleCount = old_sample_count; } if( ti->SampleIndex >= Margin ) { StopAndSave(); } } /* RecordSample */
static void RecordSample( unsigned offset, unsigned tid ) { samp_block *old_samples; unsigned old_sample_index; unsigned old_sample_count; if( tid > MaxThread ) { GrowArrays( tid ); } --tid; LastSampleIndex = SampleIndexP[tid]; if( SampleIndexP[tid] == 0 ) { SamplesP[tid]->pref.tick = CurrTick; if( CallGraphMode ) { CallGraphP[tid]->pref.tick = CurrTick; } } ++CurrTick; SamplesP[tid]->d.sample.sample[SampleIndexP[tid]].offset = offset; SamplesP[tid]->d.sample.sample[SampleIndexP[tid]].segment = FlatSeg; SampleIndexP[tid]++; if( CallGraphMode ) { SampleCountP[tid]++; } if( CallGraphMode && tid == 0 ) { old_sample_count = SampleCount; old_samples = Samples; /* since RecordCGraph isn't */ old_sample_index = SampleIndex; /* used to threads, we fool */ Samples = SamplesP[tid]; /* it into storing the info */ SampleIndex = SampleIndexP[tid]; /* in the right place by */ SampleCount = SampleCountP[tid]; RecordCGraph(); /* changing its pointers */ SamplesP[tid] = Samples; /* and restoring them later */ SampleIndexP[tid] = SampleIndex; SampleCountP[tid] = SampleCount; Samples = old_samples; SampleIndex = old_sample_index; SampleCount = old_sample_count; } if( SampleIndexP[tid] >= Margin ) { StopAndSave(); } }
LRESULT CALLBACK WinKongZhiProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { switch(uMsg) { case WM_LBUTTONDOWN: { if (!m_bRecording) { StartRecord(hwnd); m_bRecording = TRUE; } else { StopAndSave(); PostQuitMessage(0); } break; } case WM_CLOSE: if(IDYES==MessageBox(hwnd,"是否真的结束?",NULL,MB_YESNO)) { DestroyWindow(hwnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,uMsg,wParam,lParam); } return 0; }
void interrupt far timer_handler( union INTPACK r ) { if( --TimerMod == 0 ) { TimerMod = TimerMult; _CHAIN_TO( old_timer_handler ); } else { /* end of interrupt (expected by 8259 before you do RETI) */ outp( INT_CTRL, EOI ); } if( ! SamplerOff ) { if( InsiderTime == 0 ) { ++InsiderTime; if( SampleIndex == 0 ) { Samples->pref.tick = CurrTick; if( CallGraphMode ) { CallGraph->pref.tick = CurrTick; } } ++CurrTick; #ifdef __NETWARE__ /* avoid pointer truncation warning */ RecordSample( (union INTPACK *)FP_OFF(&r) ); #else RecordSample( &r ); #endif if( SampleIndex >= Margin ) { if( InDOS() ) { Save_Request = TRUE; } else { /* We are not in DOS so we can suspend things for a while and save our block of samples */ if( Save_Request ) { Save_Request = 0; } StopAndSave(); } if( SampleIndex >= Ceiling ) { if( CallGraphMode ) { --SampleCount; SampleIndex = LastSampleIndex; } else { --SampleIndex; } LostData = TRUE; } } --InsiderTime; } } }
void StartProg( char *cmd, char *prog, char *full_args, char *dos_args ) { seg_offset where; int error_num; char buff[BSIZE]; Fptr32 fp; short initial_cs; int len; cmd = cmd; SampleIndex = 0; CurrTick = 0L; D32HookTimer( TimerMult ); /* ask for timer - before D32DebugInit!! */ D32DebugBreakOp(&Break); /* Get the 1 byte break op */ error_num = D32DebugInit( &Proc ); if( error_num == 0 ) { strcpy( buff, full_args ); error_num = D32DebugLoad( prog, buff, &Proc ); } if( error_num != 0 ) { Output( MsgArray[MSG_SAMPLE_2-ERR_FIRST_MESSAGE] ); Output( prog ); Output( "\r\n" ); MsgFini(); exit(1); } where.offset = 0; where.segment = 0; WriteCodeLoad( where, ExeName, SAMP_MAIN_LOAD ); fp.sel = 1; fp.off = 0; D32Relocate(&fp); WriteAddrMap( 1, fp.sel, fp.off ); initial_cs = Proc.cs; for( ;; ) { D32DebugRun( &Proc ); if( SampleIndex > Margin && Proc.cs == initial_cs ) { StopAndSave(); } if( Proc.int_id == 8 ) { ++InsiderTime; RecordSample( Proc.eip, Proc.cs ); --InsiderTime; } else if( Proc.int_id == 3 && (Proc.edx & 0xffff) != 0 ) { len = 0; /* this is a mark */ where.segment = Proc.edx & 0xffff; where.offset = Proc.eax; for( ;; ) { if( !D32AddressCheck( where.segment, where.offset, 1, NULL ) ) break; D32DebugRead( where.offset, where.segment, 0, &buff[len], 1 ); if( len == BSIZE ) break; if( buff[len] == '\0' ) break; len++; where.offset++; } buff[len] = '\0'; where.segment = Proc.cs; where.offset = Proc.eip; WriteMark( buff, where ); Proc.eip++; } else if( Proc.int_id == 3 ) { /* remember common storage */ CommonAddr.segment = Proc.ecx & 0xffff; /* area ... */ CommonAddr.offset = Proc.ebx; Proc.eip++; } else { break; } } D32UnHookTimer(); if( Proc.int_id != 0x21 ) { Output( MsgArray[MSG_SAMPLE_1-ERR_FIRST_MESSAGE] ); Output( MsgArray[Exceptions[Proc.int_id]+MSG_EXCEPT_0-ERR_FIRST_MESSAGE] ); Output( "\r\n" ); } D32DebugTerm(); report(); }