source: dev/BasicCompiler64/Debug.cpp@ 3

Last change on this file since 3 was 3, checked in by dai_9181, 17 years ago
File size: 20.0 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "opcode.h"
3
4ULONG_PTR rva_to_real(DWORD p){
5 extern DWORD ImageBase;
6 extern int MemPos_CodeSection;
7 return p+ImageBase+MemPos_CodeSection;
8}
9
10void ShowVarList(DEBUG_EVENT *pde,BOOL bExit){
11 extern DWORD ImageBase;
12 extern DWORD _DebugSys_dwThreadID[256];
13 extern HANDLE hDebugProcess;
14 extern int MemPos_RWSection;
15 SIZE_T stAccBytes;
16 ReadProcessMemory(hDebugProcess,
17 (void *)(LONG_PTR)(ImageBase+MemPos_RWSection),
18 _DebugSys_dwThreadID,sizeof(DWORD)*256,&stAccBytes);
19
20 //デバッグダイアログを表示
21 extern HINSTANCE hInst;
22 extern HWND hMainDlg;
23 extern HWND hDebugWnd;
24 extern DWORD dwStepRun;
25 dwStepRun=0;
26 if(!hDebugWnd) SendMessage(hMainDlg,WM_SHOWVARLIST,0,pde->dwThreadId);
27 else InitVarList(pde->dwThreadId);
28
29 if(bExit){
30 //"中断"
31 SetDlgItemText(hMainDlg,IDOK,STRING_CLOSE);
32
33 extern HWND hDebuggerToolbar;
34 SendMessage(hDebuggerToolbar,TB_SETSTATE,IDC_DEBUG_START,TBSTATE_INDETERMINATE);
35 SendMessage(hDebuggerToolbar,TB_SETSTATE,IDC_DEBUG_STEPOVER,TBSTATE_INDETERMINATE);
36 SendMessage(hDebuggerToolbar,TB_SETSTATE,IDC_DEBUG_STEPIN,TBSTATE_INDETERMINATE);
37 }
38 else{
39 //"継続"
40 SetDlgItemText(hDebugWnd,IDCANCEL,STRING_CONTINUE);
41 }
42 while(hDebugWnd&&dwStepRun==0) Sleep(1);
43}
44void DebugMessage(char *buffer){
45 extern HWND hMainDlg;
46 int pos;
47
48 if(!IsWindowEnabled(GetDlgItem(hMainDlg,IDC_DEBUGLIST))){
49 SetDlgItemText(hMainDlg,IDC_DEBUGLIST,"");
50 EnableWindow(GetDlgItem(hMainDlg,IDC_DEBUGLIST),1);
51 }
52
53 pos=GetWindowTextLength(GetDlgItem(hMainDlg,IDC_DEBUGLIST));
54 SendDlgItemMessage(hMainDlg,IDC_DEBUGLIST,EM_SETSEL,pos,pos);
55 SendDlgItemMessage(hMainDlg,IDC_DEBUGLIST,EM_REPLACESEL,0,(LPARAM)buffer);
56}
57SUBINFO *GetSubFromObp(ULONG_PTR pos){
58 extern SUBINFO **ppSubHash;
59 SUBINFO *psi;
60 int i2;
61
62 for(i2=0;i2<MAX_HASH;i2++){
63 psi=ppSubHash[i2];
64 while(psi){
65 if(rva_to_real(psi->CompileAddress) <= pos &&
66 pos < rva_to_real(psi->EndOpAddr))
67 return psi;
68
69 psi=psi->pNextData;
70 }
71 }
72 return 0;
73}
74void ReleaseSingleStep(HANDLE hThread,CONTEXT *pContext){
75 //以前にシングルステップ実行をした場合
76 extern HANDLE hDebugProcess;
77 extern DWORD *lpdwDebugThreadID;
78 extern HANDLE *lphDebugThread;
79 extern int DebugThreadNum;
80 extern DWORD ImageBase;
81 extern int MemPos_CodeSection;
82 extern int FileSize_CodeSection;
83 extern char *OpBuffer;
84 int i2;
85 SIZE_T stAccBytes;
86
87 //シングルステップOFF
88 WriteProcessMemory(hDebugProcess,
89 (void *)(LONG_PTR)(ImageBase+MemPos_CodeSection),
90 OpBuffer,FileSize_CodeSection,&stAccBytes);
91
92 if(ImageBase+MemPos_CodeSection <= pContext->Rip &&
93 pContext->Rip < ImageBase+MemPos_CodeSection+FileSize_CodeSection){
94 //オリジナルコード内のみ、シングルステップ用の"int 3"を考慮
95 pContext->Rip--;
96 SetThreadContext(hThread,pContext);
97 }
98
99 //他のスレッドのサスペンドを解除
100 for(i2=0;i2<DebugThreadNum;i2++){
101 if(hThread!=lphDebugThread[i2])
102 ResumeThread(lphDebugThread[i2]);
103 }
104}
105void SetThreadId_ToProcessMemory(DWORD dwThreadId,BOOL bReset){
106 extern DWORD ImageBase;
107 extern int MemPos_RWSection;
108 extern HANDLE hDebugProcess;
109
110 DWORD array_dwData[256];
111 SIZE_T stAccBytes;
112
113 ReadProcessMemory(hDebugProcess,
114 (void *)(LONG_PTR)(ImageBase+MemPos_RWSection),
115 array_dwData,sizeof(DWORD)*256,&stAccBytes);
116
117 int i2;
118 for(i2=0;i2<256;i2++){
119 if(bReset==0){
120 if(array_dwData[i2]==0){
121 array_dwData[i2]=dwThreadId;
122 break;
123 }
124 }
125 else{
126 if(array_dwData[i2]==dwThreadId){
127 array_dwData[i2]=0;
128 break;
129 }
130 }
131 }
132
133 WriteProcessMemory(hDebugProcess,
134 (void *)(LONG_PTR)(ImageBase+MemPos_RWSection),
135 array_dwData,sizeof(DWORD)*256,&stAccBytes);
136}
137void AddThread(DWORD dwThreadId, HANDLE hThread){
138 extern HANDLE hDebugProcess;
139 extern DWORD ImageBase;
140 extern int MemPos_RWSection;
141
142 //プロセスIDをターゲットアプリのメモリに書き込む
143 SetThreadId_ToProcessMemory(dwThreadId,0);
144
145 extern int DebugThreadNum;
146
147 //デバッグID
148 extern DWORD *lpdwDebugThreadID;
149 lpdwDebugThreadID=(DWORD *)HeapReAlloc(hHeap,0,lpdwDebugThreadID,(DebugThreadNum+1)*sizeof(DWORD));
150 lpdwDebugThreadID[DebugThreadNum]=dwThreadId;
151
152 //デバッグハンドル
153 extern HANDLE *lphDebugThread;
154 lphDebugThread=(HANDLE *)HeapReAlloc(hHeap,0,lphDebugThread,(DebugThreadNum+1)*sizeof(HANDLE));
155 lphDebugThread[DebugThreadNum]=hThread;
156
157 //カウンタ
158 DebugThreadNum++;
159}
160void ReadOpBuffer(){
161 extern int FileSize_CodeSection;
162
163 extern char *OpBuffer;
164 if(OpBuffer) HeapDefaultFree(OpBuffer);
165 OpBuffer=(char *)HeapAlloc(hHeap,0,FileSize_CodeSection);
166
167 extern HANDLE hDebugProcess;
168 extern DWORD ImageBase;
169 extern int MemPos_CodeSection;
170 SIZE_T stAccByte;
171 ReadProcessMemory(hDebugProcess,(void *)(LONG_PTR)(ImageBase+MemPos_CodeSection),OpBuffer,FileSize_CodeSection,&stAccByte);
172}
173char *MakeSingleStepCode(){
174 extern DWORD ImageBase;
175 extern int MemPos_CodeSection;
176
177 extern int FileSize_CodeSection;
178 char *buffer;
179 buffer=(char *)HeapAlloc(hHeap,0,FileSize_CodeSection);
180
181 extern char *OpBuffer;
182 memcpy(buffer,OpBuffer,FileSize_CodeSection);
183
184 extern int MaxLineInfoNum;
185 extern LINEINFO *pLineInfo;
186 int i2;
187 for(i2=0;i2<MaxLineInfoNum;i2++){
188 if(!(
189 pLineInfo[i2].dwCodeType&CODETYPE_SYSTEMPROC||
190 pLineInfo[i2].dwCodeType&CODETYPE_DEBUGPROC
191 )){
192 //int 3
193 buffer[pLineInfo[i2].TopObp]=(char)0xCC;
194 }
195 }
196
197 return buffer;
198}
199void DeleteDebugInfo(void);
200void DebugProgram(void){
201 extern HWND hMainDlg;
202 extern char OutputFileName[MAX_PATH];
203 extern DWORD ImageBase;
204 extern int MemPos_CodeSection;
205 extern int MemPos_RWSection;
206 extern int FileSize_CodeSection;
207 extern char *OpBuffer;
208 int i2,i3,i4;
209 char temporary[VN_SIZE];
210 DWORD dwData[256];
211 SIZE_T stAccBytes;
212
213 extern BOOL bDll;
214 char ExeFilePathForDll[MAX_PATH];
215 if(bDll){
216 //DLLをデバッグする場合
217 extern char szDebugExeForDll[1024];
218 if(szDebugExeForDll[0]){
219 //指定済み
220 lstrcpy(ExeFilePathForDll,szDebugExeForDll);
221 }
222 else{
223 //ユーザーに実行ファイルを選択させる
224 extern HWND hOwnerEditor;
225 extern LPSTR ExeFileFilter;
226 if(!GetFilePathDialog(hOwnerEditor,ExeFilePathForDll,ExeFileFilter,"デバッグ用の実行可能ファイルを指定してください。",1)) return;
227 }
228 }
229
230 //"中断"
231 SetDlgItemText(hMainDlg,IDOK,STRING_STOP);
232
233 //スレッド情報
234 extern DWORD *lpdwDebugThreadID;
235 extern HANDLE *lphDebugThread;
236 extern int DebugThreadNum;
237 lpdwDebugThreadID=(DWORD *)HeapAlloc(hHeap,0,1);
238 lphDebugThread=(HANDLE *)HeapAlloc(hHeap,0,1);
239 DebugThreadNum=0;
240
241 //カレントディレクトリを設定
242 extern char BasicCurDir[MAX_PATH];
243 SetCurrentDirectory(BasicCurDir);
244
245 SendDlgItemMessage(hMainDlg,IDC_SHOWERROR,BM_SETCHECK,BST_UNCHECKED,0);
246 SendDlgItemMessage(hMainDlg,IDC_SHOWDEBUG,BM_SETCHECK,BST_CHECKED,0);
247 SendMessage(hMainDlg,WM_COMMAND,IDC_SHOWDEBUG,0);
248
249
250
251 extern BOOL bAttach;
252 if(bAttach){
253 extern DWORD dwAttachProcessId;
254
255 //プロセスIDを元にハンドルを取得
256 HANDLE hProcess;
257 hProcess=OpenProcess(PROCESS_ALL_ACCESS,0,dwAttachProcessId);
258 if(!hProcess) goto AttachError;
259
260 //そのプロセスにおける実行モジュールのインスタンスハンドルを取得
261 HINSTANCE hModule;
262 DWORD cbReturned;
263 if(!EnumProcessModules( hProcess, &hModule, sizeof(HINSTANCE), &cbReturned )) goto AttachError;
264
265 //実行ファイル名を取得
266 GetModuleFileNameEx(hProcess,hModule,OutputFileName,MAX_PATH);
267
268 CloseHandle(hProcess);
269
270
271 //デバッグ用の拡張情報を取得
272 ReadDebugFile();
273
274 if(!DebugActiveProcess(dwAttachProcessId)){
275AttachError:
276 DebugMessage("アタッチに失敗しました。");
277 return;
278 }
279 }
280 else{
281 if(!ReadDebugFile()){
282 extern BOOL bDebugCompile;
283 bDebugCompile=1;
284 OutputExe();
285 ReadDebugFile();
286 }
287
288 //スレッドを生成
289 STARTUPINFO si;
290 PROCESS_INFORMATION pi;
291 memset(&si,0,sizeof(STARTUPINFO));
292 si.cb=sizeof(STARTUPINFO);
293 if(!bDll){
294 //EXEファイルをデバッグ
295 CreateProcess(OutputFileName,"",NULL,NULL,0,NORMAL_PRIORITY_CLASS|DEBUG_ONLY_THIS_PROCESS,NULL,NULL,&si,&pi);
296 }
297 else{
298 //DLLファイルをデバッグ
299 CreateProcess(ExeFilePathForDll,"",NULL,NULL,0,NORMAL_PRIORITY_CLASS|DEBUG_ONLY_THIS_PROCESS,NULL,NULL,&si,&pi);
300 }
301
302 CloseHandle(pi.hProcess);
303 CloseHandle(pi.hThread);
304 }
305
306
307
308 extern BOOL bClipCompileView;
309 //"プログラムを実行しています(デバッグ中)"
310 MakeMessageText(temporary,STRING_DEBUGGING,0);
311 SetDlgItemText(hMainDlg,IDC_MESSAGE,temporary);
312 if(bClipCompileView) InvalidateRect(GetDlgItem(hMainDlg,IDC_PROGRESS),NULL,1);
313
314 char *SingleStepCodeBuffer;
315 SingleStepCodeBuffer=0;
316
317 SUBINFO *psi;
318
319 extern DWORD dwStepRun;
320 BOOL bFirstBreak=1;
321 CONTEXT Context;
322 HANDLE hMainThread;
323 extern HANDLE hDebugProcess;
324
325 DEBUG_EVENT de;
326 memset(&de,0,sizeof(DEBUG_EVENT));
327
328 while(WaitForDebugEvent(&de,INFINITE)){
329 if(de.dwDebugEventCode==LOAD_DLL_DEBUG_EVENT){
330 WCHAR wcBuf[MAX_PATH];
331 LONG_PTR lpData;
332
333 wcBuf[0]=0;
334 temporary[0]=0;
335
336 if(de.u.LoadDll.lpImageName){
337 if(!ReadProcessMemory(hDebugProcess,de.u.LoadDll.lpImageName,&lpData,sizeof(LONG_PTR),&stAccBytes)){
338 sprintf(temporary,"ロードされたDLLの名前取得(アドレス:&H%08x)に失敗しました。\r\n",(DWORD)(LONG_PTR)de.u.LoadDll.lpImageName);
339 DebugMessage(temporary);
340 goto NextContinue;
341 }
342 if(!ReadProcessMemory(hDebugProcess,(void *)lpData,wcBuf,sizeof(WCHAR)*MAX_PATH,&stAccBytes)){
343 sprintf(temporary,"ロードされたDLLの名前取得(アドレス:&H%08x)に失敗しました。\r\n",lpData);
344 DebugMessage(temporary);
345 goto NextContinue;
346 }
347
348 if(de.dwThreadId,de.u.LoadDll.fUnicode)
349 WideCharToMultiByte(CP_ACP,0,wcBuf,-1,temporary,255,NULL,NULL);
350 else lstrcpy(temporary,(char *)wcBuf);
351 }
352 else{
353 //アタッチした場合
354 GetModuleFileNameEx(hDebugProcess,(HINSTANCE)de.u.LoadDll.lpBaseOfDll,temporary,MAX_PATH);
355 }
356
357 char temp2[1024];
358 sprintf(temp2,"\"%s\" をロードしました。\r\n",temporary);
359 DebugMessage(temp2);
360
361 if(lstrcmpi(temporary, OutputFileName)==0){
362 ImageBase=(DWORD)(LONG_PTR)de.u.LoadDll.lpBaseOfDll;
363 AddThread(de.dwThreadId,hMainThread);
364
365 //実行用コードバッファを読み取る
366 ReadOpBuffer();
367
368 //シングルステップ用のコードバッファを作成
369 SingleStepCodeBuffer=MakeSingleStepCode();
370 }
371 }
372
373 else if(de.dwDebugEventCode==CREATE_PROCESS_DEBUG_EVENT){
374 hDebugProcess=de.u.CreateProcessInfo.hProcess;
375 hMainThread=de.u.CreateProcessInfo.hThread;
376 if(bDll) goto NextContinue;
377
378 //実行用コードバッファを読み取る
379 ReadOpBuffer();
380
381 //シングルステップ用のコードバッファを作成
382 SingleStepCodeBuffer=MakeSingleStepCode();
383
384 AddThread(de.dwThreadId,de.u.CreateProcessInfo.hThread);
385 }
386 else if(de.dwDebugEventCode==CREATE_THREAD_DEBUG_EVENT){
387 AddThread(de.dwThreadId,de.u.CreateThread.hThread);
388 }
389 else if(de.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT){
390 //プロセスIDをターゲットアプリのメモリから消去
391 SetThreadId_ToProcessMemory(de.dwThreadId,1);
392
393 //"スレッド(&H%X)はコード &H%X で終了しました。\r\n"
394 sprintf(temporary,STRING_DEBUG_THREADFINISH,de.dwThreadId,de.u.ExitProcess.dwExitCode);
395 DebugMessage(temporary);
396
397 //"デバッグは正常に終了しました。"
398 MakeMessageText(temporary,STRING_DEBUG_FINISH,0);
399 SetDlgItemText(hMainDlg,IDC_MESSAGE,temporary);
400 if(bClipCompileView) InvalidateRect(GetDlgItem(hMainDlg,IDC_PROGRESS),NULL,1);
401
402 //"プログラムはコード &H%X で終了しました。\r\n"
403 sprintf(temporary,STRING_DEBUG_PROCESSFINISH,de.u.ExitProcess.dwExitCode);
404 DebugMessage(temporary);
405 break;
406 }
407 else if(de.dwDebugEventCode==EXIT_THREAD_DEBUG_EVENT){
408 //プロセスIDをターゲットアプリのメモリから消去
409 SetThreadId_ToProcessMemory(de.dwThreadId,1);
410
411 //"スレッド(&H%X)はコード &H%X で終了しました。\r\n"
412 sprintf(temporary,STRING_DEBUG_THREADFINISH,de.dwThreadId,de.u.ExitThread.dwExitCode);
413 DebugMessage(temporary);
414
415 //以前にシングルステップ実行をした場合
416 //ステップ実行を解除
417 if(dwStepRun){
418 extern HWND hDebugWnd;
419 if(hDebugWnd) SendMessage(hDebugWnd,WM_VARLIST_CLOSE,0,0);
420
421 for(i4=0;i4<DebugThreadNum;i4++){
422 if(de.dwThreadId==lpdwDebugThreadID[i4]) break;
423 }
424 Context.ContextFlags=CONTEXT_CONTROL;
425 GetThreadContext(lphDebugThread[i4],&Context);
426
427 ReleaseSingleStep(lphDebugThread[i4],&Context);
428 }
429
430 for(i2=0;i2<DebugThreadNum;i2++){
431 if(lpdwDebugThreadID[i2]==de.dwThreadId){
432 DebugThreadNum--;
433 for(;i2<DebugThreadNum;i2++){
434 lpdwDebugThreadID[i2]=lpdwDebugThreadID[i2+1];
435 lphDebugThread[i2]=lphDebugThread[i2+1];
436 }
437 break;
438 }
439 }
440 }
441 else if(de.dwDebugEventCode==OUTPUT_DEBUG_STRING_EVENT){
442 ReadProcessMemory(hDebugProcess,(void *)de.u.DebugString.lpDebugStringData,temporary,de.u.DebugString.nDebugStringLength,&stAccBytes);
443 DebugMessage(temporary);
444 }
445 else if(de.dwDebugEventCode==EXCEPTION_DEBUG_EVENT){
446
447 //初回例外は無視
448 if(bFirstBreak){
449 bFirstBreak=0;
450 goto NextContinue;
451 }
452
453 if(de.u.Exception.ExceptionRecord.ExceptionCode==STATUS_INVALID_HANDLE){
454
455 //"スレッド(&H%X)でハンドル違反がありました(EPI=&H%08X)。\r\n"
456 sprintf(temporary,STRING_DEBUG_THREAD_INVALID_HANDLE,de.dwThreadId,(LONG_PTR)de.u.Exception.ExceptionRecord.ExceptionAddress);
457 DebugMessage(temporary);
458
459 MessageBeep(MB_ICONEXCLAMATION);
460 ShowVarList(&de,1);
461 break;
462 }
463 if(de.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_ACCESS_VIOLATION){
464
465 //"スレッド(&H%X)でアクセス違反がありました(EPI=&H%08X)。\r\n"
466 sprintf(temporary,STRING_DEBUG_THREAD_ACCESSVIOLATION,de.dwThreadId,(LONG_PTR)de.u.Exception.ExceptionRecord.ExceptionAddress);
467 DebugMessage(temporary);
468
469 MessageBeep(MB_ICONEXCLAMATION);
470 ShowVarList(&de,1);
471 break;
472 }
473 else if(de.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT){
474 i3=dwStepRun;
475
476 for(i4=0;i4<DebugThreadNum;i4++){
477 if(de.dwThreadId==lpdwDebugThreadID[i4]) break;
478 }
479 Context.ContextFlags=CONTEXT_CONTROL;
480 GetThreadContext(lphDebugThread[i4],&Context);
481
482 if(i3==0||
483 i3&&(!(ImageBase+MemPos_CodeSection<=Context.Rip&&Context.Rip<ImageBase+MemPos_CodeSection+FileSize_CodeSection))
484 ){
485 //"スレッド(&H%X)のブレーク ポイント(EPI=&H%08X)。\r\n"
486 sprintf(temporary,STRING_DEBUG_BREAKPOINT,de.dwThreadId,(LONG_PTR)de.u.Exception.ExceptionRecord.ExceptionAddress);
487 DebugMessage(temporary);
488 }
489
490 ShowVarList(&de,0);
491
492 //以前にシングルステップ実行をした場合
493 //ステップ実行を解除
494 if(i3) ReleaseSingleStep(lphDebugThread[i4],&Context);
495
496 if(dwStepRun){
497 //新たにシングルステップを行う場合
498
499 if(ImageBase+MemPos_CodeSection <= Context.Rip &&
500 Context.Rip < ImageBase+MemPos_CodeSection+FileSize_CodeSection){
501 //Debug命令語が続く場合はシングルステップは不要になるので、無効にする
502 //(オリジナルコード内のみ)
503 if(OpBuffer[Context.Rip-ImageBase-MemPos_CodeSection]==(char)0xCC)
504 dwStepRun=0;
505 }
506 if(dwStepRun==1){
507 //ステップイン
508StepIn:
509 //シングルステップON
510 WriteProcessMemory(hDebugProcess,
511 (void *)(LONG_PTR)(ImageBase+MemPos_CodeSection),
512 SingleStepCodeBuffer,FileSize_CodeSection,&stAccBytes);
513
514 //次の命令語のブレーク命令は解除しておく(シングルステップ実行後のみ)
515 //(オリジナルコード内のみ)
516 if(i3&&ImageBase+MemPos_CodeSection<=Context.Rip&&Context.Rip<ImageBase+MemPos_CodeSection+FileSize_CodeSection)
517 WriteProcessMemory(hDebugProcess,(void *)Context.Rip,&OpBuffer[Context.Rip-ImageBase-MemPos_CodeSection],1,&stAccBytes);
518
519 //他のスレッドを一時中断
520 for(i4=0;i4<DebugThreadNum;i4++){
521 if(de.dwThreadId!=lpdwDebugThreadID[i4])
522 SuspendThread(lphDebugThread[i4]);
523 }
524 }
525 else if(dwStepRun==2){
526 //ステップオーバー
527
528 BOOL bRet;
529 bRet=ReadProcessMemory(hDebugProcess,
530 (void *)Context.Rip,
531 temporary,
532 5,
533 &stAccBytes);
534 if(!bRet) MessageBox(hMainDlg,"プロセスメモリーの読み込みに失敗","error",MB_OK);
535
536 extern SUBINFO *pSub_DebugSys_EndProc;
537 if((BYTE)temporary[0]==0xE8&&
538 *((long *)(temporary+1))+5==(long)rva_to_real(pSub_DebugSys_EndProc->CompileAddress)-(long)Context.Rip){
539 //プロシージャの終端位置の場合はステップインを行う
540 goto StepIn;
541 }
542
543 //スレッドのプロシージャ実行状況を取得
544 bRet=ReadProcessMemory(hDebugProcess,
545 (void *)(LONG_PTR)(ImageBase+MemPos_RWSection),
546 dwData,sizeof(DWORD)*256,&stAccBytes);
547 if(!bRet) MessageBox(hMainDlg,"プロセスメモリーの読み込みに失敗","error",MB_OK);
548 for(i2=0;;i2++){
549 if(dwData[i2]==de.dwThreadId) break;
550 }
551 GetDebugThreadInfo(i2);
552
553 extern int GlobalOpBufferSize;
554 extern DEBUG_PROCINFO dpi;
555 if(ImageBase+MemPos_CodeSection<=dpi.lpqwObp[dpi.num]&&
556 dpi.lpqwObp[dpi.num]<ImageBase+MemPos_CodeSection+GlobalOpBufferSize){
557 //シングルステップON
558 WriteProcessMemory(hDebugProcess,
559 (void *)(LONG_PTR)(ImageBase+MemPos_CodeSection),
560 SingleStepCodeBuffer,
561 GlobalOpBufferSize,
562 &stAccBytes);
563 }
564 else{
565 //プロシージャを識別
566 psi=GetSubFromObp(dpi.lpqwObp[dpi.num]);
567
568 //シングルステップON
569 WriteProcessMemory(hDebugProcess,
570 (void *)(LONG_PTR)rva_to_real(psi->CompileAddress),
571 SingleStepCodeBuffer+psi->CompileAddress,
572 psi->EndOpAddr-psi->CompileAddress,
573 &stAccBytes);
574 }
575 DeleteDebugThreadInfo();
576
577 //次の命令語のブレーク命令は解除しておく(シングルステップ実行後のみ)
578 //(オリジナルコード内のみ)
579 if(i3&&ImageBase+MemPos_CodeSection<=Context.Rip&&Context.Rip<ImageBase+MemPos_CodeSection+FileSize_CodeSection)
580 WriteProcessMemory(hDebugProcess,(void *)Context.Rip,&OpBuffer[Context.Rip-ImageBase-MemPos_CodeSection],1,&stAccBytes);
581
582 //他のスレッドを一時中断
583 for(i4=0;i4<DebugThreadNum;i4++){
584 if(de.dwThreadId!=lpdwDebugThreadID[i4])
585 SuspendThread(lphDebugThread[i4]);
586 }
587 }
588 }
589 }
590 else if(de.u.Exception.ExceptionRecord.ExceptionCode==STATUS_INTEGER_DIVIDE_BY_ZERO){
591 //"0による除算が行われました。スレッド(&H%X) ブレーク ポイント(EPI=&H%08X)。\r\n"
592 sprintf(temporary,STRING_DEBUG_DIVIDE_BY_ZERO,de.dwThreadId,(LONG_PTR)de.u.Exception.ExceptionRecord.ExceptionAddress);
593 DebugMessage(temporary);
594
595 ShowVarList(&de,1);
596 break;
597 }
598 else{
599 //"例外処理\ncode:%X"
600 sprintf(temporary,STRING_DEBUG_ERROR,de.u.Exception.ExceptionRecord.ExceptionCode);
601 MessageBox(0,temporary,"ActiveBasic Debug",0);
602 }
603 }
604NextContinue:
605 ContinueDebugEvent(de.dwProcessId,de.dwThreadId,DBG_CONTINUE);
606 }
607
608 //シングルステップ用のコードバッファを解放
609 if(SingleStepCodeBuffer) HeapDefaultFree(SingleStepCodeBuffer);
610
611 extern HWND hDebugWnd;
612 if(hDebugWnd) SendMessage(hDebugWnd,WM_COMMAND,IDCANCEL,0);
613
614 //スレッド情報を解放
615 HeapDefaultFree(lpdwDebugThreadID);
616 HeapDefaultFree(lphDebugThread);
617
618 //デバッグに利用した情報を解放(ReadDebugで確保した情報)
619 DeleteDebugInfo();
620
621 //"閉じる"
622 SetDlgItemText(hMainDlg,IDOK,STRING_CLOSE);
623}
624void DeleteDebugInfo(void){
625 int i2;
626
627 //インクルード情報を解放
628 extern INCLUDEFILEINFO IncludeFileInfo;
629 for(i2=0;i2<IncludeFileInfo.FilesNum;i2++)
630 HeapDefaultFree(IncludeFileInfo.ppFileNames[i2]);
631 HeapDefaultFree(IncludeFileInfo.ppFileNames);
632
633 //グローバル変数に関する情報を解放
634 extern VARIABLE *GlobalVar;
635 HeapDefaultFree(GlobalVar);
636
637 //ローカル変数に関する情報を解放
638 extern SUBINFO **ppSubHash;
639 SUBINFO *psi;
640 for(i2=0;i2<MAX_HASH;i2++){
641 psi=ppSubHash[i2];
642 while(psi){
643 if(psi->bCompile)
644 HeapDefaultFree(psi->pVar);
645
646 psi=psi->pNextData;
647 }
648 }
649
650 //列挙型に関するメモリを解放
651 DeleteEnumInfo();
652
653 //クラスに関するメモリを解放
654 delete pobj_DBClass;
655 pobj_DBClass=0;
656
657 //サブルーチン情報のメモリ解放
658 DeleteSubInfo();
659
660 //定数に関する情報を解放
661 DeleteConstInfo();
662
663 //ソースコードを解放
664 extern char *pBaseBuffer;
665 HeapDefaultFree(pBaseBuffer);
666
667 //コードと行番号の関係を解放
668 extern LINEINFO *pLineInfo;
669 HeapDefaultFree(pLineInfo);
670
671 //コードバッファを解放
672 extern char *OpBuffer;
673 if(OpBuffer){
674 HeapDefaultFree(OpBuffer);
675 OpBuffer=0;
676 }
677}
Note: See TracBrowser for help on using the repository browser.