source: dev/trunk/abdev/BasicCompiler_Common/Debug.cpp@ 206

Last change on this file since 206 was 206, checked in by dai_9181, 17 years ago

コード全体のリファクタリングを実施

File size: 22.7 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4
5#include "../BasicCompiler_Common/common.h"
6#include "../BasicCompiler_Common/DebugSection.h"
7
8//デバッグ用
9#include "../BasicCompiler_Common/debug.h"
10
11extern char *OpBuffer;
12
13extern DWORD dwStepRun;
14
15HANDLE hDebugProcess;
16
17DWORD _DebugSys_dwThreadID[MAX_DEBUG_THREAD];
18HANDLE array_hDebugThread[MAX_DEBUG_THREAD];
19
20int StepCursorObpSchedule=-1;
21int StepCursor_BackupChar;
22
23int NextStepThreadNum;
24
25
26void Debugger_StepIn(void){
27 dwStepRun=1;
28}
29void Debugger_StepOver(void){
30 dwStepRun=2;
31}
32
33void Debugger_StepCursor(void){
34 char temporary[MAX_PATH];
35 GetTempPath(MAX_PATH,temporary);
36 if(temporary[lstrlen(temporary)-1]!='\\') lstrcat(temporary,"\\");
37 lstrcat(temporary,"ab_breakpoint.tmp");
38
39 char *buffer;
40 buffer=ReadBuffer_NonErrMsg(temporary);
41
42 int i=0;
43 char szFilePath[MAX_PATH];
44 i=GetOneParameter(buffer,i,szFilePath);
45 RemoveStringQuotes(szFilePath);
46
47 int iLineNum;
48 i=GetOneParameter(buffer,i,temporary);
49 iLineNum=atoi(temporary);
50
51
52
53 /////////////////////////////////////////////////////////
54 // デバッグ中プロセスのネイティブバッファ領域を更新
55 /////////////////////////////////////////////////////////
56
57 extern INCLUDEFILEINFO IncludeFileInfo;
58
59 int FileNum;
60 for(FileNum=0;FileNum<IncludeFileInfo.FilesNum;FileNum++){
61 if(lstrcmpi(IncludeFileInfo.ppFileNames[FileNum],szFilePath)==0) break;
62 }
63 if(FileNum==IncludeFileInfo.FilesNum) return;
64
65 for(i=0;;i++){
66 if(IncludeFileInfo.LineOfFile[i]==FileNum||
67 IncludeFileInfo.LineOfFile[i]==-1) break;
68 }
69 if(IncludeFileInfo.LineOfFile[i]==-1) return;
70
71 int FileBaseLine;
72 FileBaseLine=i;
73
74 int i2;
75 for(i2=0;;i++,i2++){
76 if(FileNum<IncludeFileInfo.LineOfFile[i]){
77 while(FileNum!=IncludeFileInfo.LineOfFile[i]) i++;
78 }
79
80 if(i2==iLineNum){
81 extern int MaxLineInfoNum;
82 extern LINEINFO *pLineInfo;
83
84loop:
85 int tempCp;
86 tempCp=GetCpFromLine(FileBaseLine+i2);
87
88 int i3;
89 for(i3=0;i3<MaxLineInfoNum-1;i3++){
90 if(pLineInfo[i3].TopCp==tempCp) break;
91 }
92 if(i3==MaxLineInfoNum-1){
93 i2--;
94 goto loop;
95 }
96
97 StepCursorObpSchedule=pLineInfo[i3].TopObp;
98 StepCursor_BackupChar=pobj_DBDebugSection->pobj_now->BreakStepCodeBuffer[StepCursorObpSchedule];
99
100 pobj_DBDebugSection->pobj_now->BreakStepCodeBuffer[StepCursorObpSchedule]=(char)0xCC;
101
102 break;
103 }
104 }
105
106 extern HWND hDebugWnd;
107 SendMessage(hDebugWnd,WM_DEBUG_CONTINUE,0,0);
108
109
110
111 HeapDefaultFree(buffer);
112}
113void Debugger_Stop(void){
114 //プロセスを終了
115 TerminateProcess(hDebugProcess,0);
116 hDebugProcess=0;
117
118 //デバッグダイアログを終了
119 extern HWND hDebugWnd;
120 if(hDebugWnd){
121 DestroyWindow(hDebugWnd);
122 }
123}
124void Debugger_Pause(void){
125 ///////////////////////////
126 // デバッグを一時中断
127 ///////////////////////////
128
129 //ターゲットプロセス内のスレッドを一時中断
130 int i;
131 for(i=0;i<MAX_DEBUG_THREAD;i++){
132 if(_DebugSys_dwThreadID[i])
133 SuspendThread(array_hDebugThread[i]);
134 }
135
136 //デバッグレジスタにフラグをセット
137 CONTEXT Context;
138 for(i=0;i<MAX_DEBUG_THREAD;i++){
139 if(_DebugSys_dwThreadID[i]){
140 Context.ContextFlags=CONTEXT_CONTROL|CONTEXT_DEBUG_REGISTERS;
141 GetThreadContext(array_hDebugThread[i],&Context);
142 Context.EFlags|=0x100;
143 SetThreadContext(array_hDebugThread[i],&Context);
144 }
145 }
146
147 //スレッドを再開
148 for(i=0;i<MAX_DEBUG_THREAD;i++){
149 if(_DebugSys_dwThreadID[i])
150 ResumeThread(array_hDebugThread[i]);
151 }
152}
153
154void ReleaseCPUSingleStep(void){
155 ////////////////////////////////////////
156 // CPU機構のシングルステップを解除
157 ////////////////////////////////////////
158
159 //ターゲットプロセス内のスレッドを一時中断
160 int i;
161 for(i=0;i<MAX_DEBUG_THREAD;i++){
162 if(_DebugSys_dwThreadID[i])
163 SuspendThread(array_hDebugThread[i]);
164 }
165
166 //デバッグレジスタにフラグをセット
167 CONTEXT Context;
168 for(i=0;i<MAX_DEBUG_THREAD;i++){
169 if(_DebugSys_dwThreadID[i]){
170 Context.ContextFlags=CONTEXT_CONTROL|CONTEXT_DEBUG_REGISTERS;
171 GetThreadContext(array_hDebugThread[i],&Context);
172 Context.EFlags&=~0x00000100;
173 SetThreadContext(array_hDebugThread[i],&Context);
174 }
175 }
176
177 //スレッドを再開
178 for(i=0;i<MAX_DEBUG_THREAD;i++){
179 if(_DebugSys_dwThreadID[i])
180 ResumeThread(array_hDebugThread[i]);
181 }
182}
183
184
185ULONG_PTR rva_to_real(DWORD p){
186 extern DWORD ImageBase;
187 extern int MemPos_CodeSection;
188 return p+ImageBase+MemPos_CodeSection;
189}
190
191void ShowVarList(DEBUG_EVENT *pde,BOOL bExit){
192 extern DWORD ImageBase;
193 extern int MemPos_RWSection;
194
195 //デバッグダイアログを表示
196 extern HINSTANCE hInst;
197 extern HWND hMainDlg;
198 extern HWND hDebugWnd;
199 dwStepRun=0;
200 if(!hDebugWnd) SendMessage(hMainDlg,WM_SHOWVARLIST,0,pde->dwThreadId);
201 else InitVarList(pde->dwThreadId);
202
203 if(bExit){
204 //"中断"
205 SetDlgItemText(hMainDlg,IDOK,STRING_CLOSE);
206
207 extern HWND hDebuggerToolbar;
208 SendMessage(hDebuggerToolbar,TB_SETSTATE,IDC_DEBUG_START,TBSTATE_INDETERMINATE);
209 SendMessage(hDebuggerToolbar,TB_SETSTATE,IDC_DEBUG_STEPOVER,TBSTATE_INDETERMINATE);
210 SendMessage(hDebuggerToolbar,TB_SETSTATE,IDC_DEBUG_STEPIN,TBSTATE_INDETERMINATE);
211 }
212 else{
213 //"継続"
214 SetDlgItemText(hDebugWnd,IDCANCEL,STRING_CONTINUE);
215 }
216 while(hDebugWnd&&dwStepRun==0) Sleep(1);
217}
218void DebugMessage(char *buffer){
219 extern HWND hMainDlg;
220 int pos;
221
222 if(!IsWindowEnabled(GetDlgItem(hMainDlg,IDC_DEBUGLIST))){
223 SetDlgItemText(hMainDlg,IDC_DEBUGLIST,"");
224 EnableWindow(GetDlgItem(hMainDlg,IDC_DEBUGLIST),1);
225 }
226
227 pos=GetWindowTextLength(GetDlgItem(hMainDlg,IDC_DEBUGLIST));
228 SendDlgItemMessage(hMainDlg,IDC_DEBUGLIST,EM_SETSEL,pos,pos);
229 SendDlgItemMessage(hMainDlg,IDC_DEBUGLIST,EM_REPLACESEL,0,(LPARAM)buffer);
230}
231UserProc *GetSubFromObp(ULONG_PTR pos){
232 compiler.GetMeta().GetUserProcs().Iterator_Reset();
233 while( compiler.GetMeta().GetUserProcs().Iterator_HasNext() )
234 {
235 UserProc *pUserProc = compiler.GetMeta().GetUserProcs().Iterator_GetNext();
236
237 if(rva_to_real(pUserProc->GetBeginOpAddress()) <= pos &&
238 pos < rva_to_real(pUserProc->GetEndOpAddress()))
239 {
240 return pUserProc;
241 }
242 }
243 return NULL;
244}
245void ReleaseSingleStep(DWORD dwBeforeStepRun,HANDLE hThread,CONTEXT *pContext){
246 //以前にシングルステップ実行をした場合
247 extern DWORD ImageBase;
248 extern int MemPos_CodeSection;
249 extern int FileSize_CodeSection;
250 int i2;
251 ULONG_PTR lpAccBytes;
252
253 ///////////////////////////
254 // シングルステップOFF
255 ///////////////////////////
256
257 //ユーザー指定のブレークポイントをセット
258 WriteProcessMemory(hDebugProcess,
259 (void *)(ULONG_PTR)(ImageBase+MemPos_CodeSection),
260 pobj_DBDebugSection->pobj_now->BreakStepCodeBuffer,
261 FileSize_CodeSection,&lpAccBytes);
262
263 //次に実行すべき命令はユーザー指定によるブレークポイントをはずしておく
264 if(ImageBase+MemPos_CodeSection<=EIP_RIP(*pContext)&&EIP_RIP(*pContext)<ImageBase+MemPos_CodeSection+FileSize_CodeSection){
265 if(OpBuffer[EIP_RIP(*pContext)-ImageBase-MemPos_CodeSection-1]!=
266 pobj_DBDebugSection->pobj_now->BreakStepCodeBuffer[EIP_RIP(*pContext)-ImageBase-MemPos_CodeSection-1]){
267 //直前のブレークポイントがユーザー指定によるものだったとき
268
269 //eip/ripを1だけ減少
270 EIP_RIP(*pContext)--;
271 SetThreadContext(hThread,pContext);
272
273 //ブレークポイントを解除
274 WriteProcessMemory(hDebugProcess,(void *)EIP_RIP(*pContext),&OpBuffer[EIP_RIP(*pContext)-ImageBase-MemPos_CodeSection],1,&lpAccBytes);
275
276
277 extern int StepCursorObpSchedule;
278 if(StepCursorObpSchedule==(int)(EIP_RIP(*pContext)-ImageBase-MemPos_CodeSection)){
279 //カーソル行までのステップ実行の場合
280 pobj_DBDebugSection->pobj_now->BreakStepCodeBuffer[StepCursorObpSchedule]=StepCursor_BackupChar;
281 StepCursorObpSchedule=-1;
282 }
283
284 return;
285 }
286 }
287
288
289 if(dwBeforeStepRun){
290 //直前にシングルステップを行った場合
291 if(ImageBase+MemPos_CodeSection <= EIP_RIP(*pContext) &&
292 EIP_RIP(*pContext) < ImageBase+MemPos_CodeSection+FileSize_CodeSection){
293 //オリジナルコード内のみ、シングルステップ用の"int 3"を考慮
294 EIP_RIP(*pContext)--;
295 SetThreadContext(hThread,pContext);
296 }
297
298 //他のスレッドのサスペンドを解除
299 for(i2=0;i2<MAX_DEBUG_THREAD;i2++){
300 if(array_hDebugThread[i2] && hThread!=array_hDebugThread[i2])
301 ResumeThread(array_hDebugThread[i2]);
302 }
303 }
304}
305
306void Set_DebugSys_dwThreadID(){
307 int i;
308 for(i=0;i<pobj_DBDebugSection->num;i++){
309 ULONG_PTR lpAccBytes;
310 WriteProcessMemory(hDebugProcess,
311 (void *)(ULONG_PTR)(pobj_DBDebugSection->ppobj_ds[i]->dwImageBase + pobj_DBDebugSection->ppobj_ds[i]->dwRVA_RWSection),
312 _DebugSys_dwThreadID,sizeof(DWORD)*MAX_DEBUG_THREAD,&lpAccBytes);
313 }
314}
315void AddThread(DWORD dwThreadId, HANDLE hThread){
316 int i;
317
318
319 for(i=0;i<MAX_DEBUG_THREAD;i++){
320 if(_DebugSys_dwThreadID[i]==0){
321 _DebugSys_dwThreadID[i]=dwThreadId;
322 array_hDebugThread[i]=hThread;
323 break;
324 }
325 }
326
327 Set_DebugSys_dwThreadID();
328}
329void DeleteThread(DWORD dwThreadId){
330 int i;
331
332 for(i=0;i<MAX_DEBUG_THREAD;i++){
333 if(_DebugSys_dwThreadID[i]==dwThreadId){
334 _DebugSys_dwThreadID[i]=0;
335 array_hDebugThread[i]=0;
336 break;
337 }
338 }
339
340 Set_DebugSys_dwThreadID();
341}
342
343void DebugProgram(void){
344 extern HWND hMainDlg;
345 extern char OutputFileName[MAX_PATH];
346 extern DWORD ImageBase;
347 extern int MemPos_CodeSection;
348 extern int MemPos_RWSection;
349 extern int FileSize_CodeSection;
350 int i2,i3,i4;
351 char temporary[1024];
352
353 extern BOOL bDll;
354 char ExeFilePathForDll[MAX_PATH];
355 if(bDll){
356 //DLLをデバッグする場合
357 extern char szDebugExeForDll[1024];
358 if(szDebugExeForDll[0]){
359 //指定済み
360 lstrcpy(ExeFilePathForDll,szDebugExeForDll);
361 }
362 else{
363 //ユーザーに実行ファイルを選択させる
364 extern HWND hOwnerEditor;
365 extern LPSTR ExeFileFilter;
366 if(!GetFilePathDialog(hOwnerEditor,ExeFilePathForDll,ExeFileFilter,"デバッグ用の実行可能ファイルを指定してください。",1)) return;
367 }
368 }
369
370
371 //"中断"
372 SetDlgItemText(hMainDlg,IDOK,STRING_STOP);
373
374 SendMessage(hOwnerEditor,WM_SETDEBUGGERBASE,0,0);
375
376 //カレントディレクトリを設定
377 extern char BasicCurDir[MAX_PATH];
378 SetCurrentDirectory(BasicCurDir);
379
380 SendDlgItemMessage(hMainDlg,IDC_SHOWERROR,BM_SETCHECK,BST_UNCHECKED,0);
381 SendDlgItemMessage(hMainDlg,IDC_SHOWDEBUG,BM_SETCHECK,BST_CHECKED,0);
382 SendMessage(hMainDlg,WM_COMMAND,IDC_SHOWDEBUG,0);
383
384 //ブレークポイントを生成
385 pobj_DBBreakPoint=new CDBBreakPoint;
386
387
388 extern BOOL bAttach;
389 if(bAttach){
390 extern DWORD dwAttachProcessId;
391
392 //プロセスIDを元にハンドルを取得
393 HANDLE hProcess;
394 hProcess=OpenProcess(PROCESS_ALL_ACCESS,0,dwAttachProcessId);
395 if(!hProcess) goto AttachError;
396
397 //そのプロセスにおける実行モジュールのインスタンスハンドルを取得
398 HINSTANCE hModule;
399 DWORD cbReturned;
400 if(!EnumProcessModules( hProcess, &hModule, sizeof(HINSTANCE), &cbReturned )) goto AttachError;
401
402 //実行ファイル名を取得
403 GetModuleFileNameEx(hProcess,hModule,OutputFileName,MAX_PATH);
404
405 CloseHandle(hProcess);
406
407/*
408 //デバッグ用の拡張情報を取得
409 pobj_DebugSection->load(OutputFileName);*/
410
411 if(!DebugActiveProcess(dwAttachProcessId)){
412AttachError:
413 DebugMessage("アタッチに失敗しました。");
414 return;
415 }
416 }
417 else{
418 /*if(!pobj_DebugSection->load(OutputFileName)){
419 extern BOOL bDebugCompile;
420 bDebugCompile=1;
421 OutputExe();
422 pobj_DebugSection->load(OutputFileName);
423 }*/
424
425 //スレッドを生成
426 extern char szDebugCmdLine[1024];
427 STARTUPINFO si;
428 PROCESS_INFORMATION pi;
429 memset(&si,0,sizeof(STARTUPINFO));
430 si.cb=sizeof(STARTUPINFO);
431 if(!bDll){
432 //EXEファイルをデバッグ
433 CreateProcess(OutputFileName,szDebugCmdLine,NULL,NULL,0,NORMAL_PRIORITY_CLASS|DEBUG_ONLY_THIS_PROCESS,NULL,NULL,&si,&pi);
434 }
435 else{
436 //DLLファイルをデバッグ
437 CreateProcess(ExeFilePathForDll,szDebugCmdLine,NULL,NULL,0,NORMAL_PRIORITY_CLASS|DEBUG_ONLY_THIS_PROCESS,NULL,NULL,&si,&pi);
438 }
439
440 CloseHandle(pi.hProcess);
441 CloseHandle(pi.hThread);
442 }
443
444
445 //デバッグ情報データベースを生成
446 pobj_DBDebugSection=new CDBDebugSection();
447
448 //デバッグスレッド情報(プロシージャの階層構造を管理)を生成
449 pobj_dti=new CDebugThreadInfo();
450
451 UserProc *pUserProc;
452
453 extern DWORD dwStepRun;
454 BOOL bFirstBreak=1;
455 CONTEXT Context;
456 HANDLE hMainThread;
457 ULONG_PTR lpAccBytes;
458
459 DEBUG_EVENT de;
460 memset(&de,0,sizeof(DEBUG_EVENT));
461
462 while(WaitForDebugEvent(&de,INFINITE)){
463 if(de.dwDebugEventCode==LOAD_DLL_DEBUG_EVENT){
464 WCHAR wcBuf[MAX_PATH];
465 LONG_PTR lpData;
466
467 wcBuf[0]=0;
468 temporary[0]=0;
469
470 if(de.u.LoadDll.lpImageName){
471 if(!ReadProcessMemory(hDebugProcess,de.u.LoadDll.lpImageName,&lpData,sizeof(LONG_PTR),&lpAccBytes)){
472 sprintf(temporary,"ロードされたDLLの名前取得(アドレス:&H%08x)に失敗しました。\r\n",(ULONG_PTR)de.u.LoadDll.lpImageName);
473 DebugMessage(temporary);
474 goto NextContinue;
475 }
476 if(!lpData) goto Attach_DllLoad;
477
478 if(!ReadProcessMemory(hDebugProcess,(void *)lpData,wcBuf,sizeof(WCHAR)*MAX_PATH,&lpAccBytes)){
479 sprintf(temporary,"ロードされたDLLの名前取得(アドレス:&H%08x)に失敗しました。\r\n",lpData);
480 DebugMessage(temporary);
481 goto NextContinue;
482 }
483
484 if(de.dwThreadId,de.u.LoadDll.fUnicode)
485 WideCharToMultiByte(CP_ACP,0,wcBuf,-1,temporary,255,NULL,NULL);
486 else lstrcpy(temporary,(char *)wcBuf);
487 }
488 else{
489Attach_DllLoad:
490 //アタッチした場合
491 GetModuleFileNameEx(hDebugProcess,(HINSTANCE)de.u.LoadDll.lpBaseOfDll,temporary,MAX_PATH);
492 }
493
494 char temp2[1024];
495 sprintf(temp2,"\"%s\" をロードしました。\r\n",temporary);
496 DebugMessage(temp2);
497
498
499 //可能であればデバッグ情報を読みとる
500 if(pobj_DBDebugSection->add((HMODULE)de.u.LoadDll.lpBaseOfDll)){
501 pobj_DBDebugSection->choice(0);
502 Set_DebugSys_dwThreadID();
503 }
504
505
506 /*if(lstrcmpi(temporary, OutputFileName)==0){
507 ImageBase=(DWORD)de.u.LoadDll.lpBaseOfDll;
508
509 AddThread(de.dwThreadId,hMainThread);
510 }*/
511 }
512 else if(de.dwDebugEventCode==UNLOAD_DLL_DEBUG_EVENT){
513 //DLLのアンロード
514
515 pobj_DBDebugSection->del((HMODULE)de.u.UnloadDll.lpBaseOfDll);
516 }
517 else if(de.dwDebugEventCode==CREATE_PROCESS_DEBUG_EVENT){
518 hDebugProcess=de.u.CreateProcessInfo.hProcess;
519 hMainThread=de.u.CreateProcessInfo.hThread;
520
521 if(pobj_DBDebugSection->add((HMODULE)de.u.CreateProcessInfo.lpBaseOfImage)){
522 pobj_DBDebugSection->choice(0);
523 }
524
525 AddThread(de.dwThreadId,de.u.CreateProcessInfo.hThread);
526 }
527 else if(de.dwDebugEventCode==CREATE_THREAD_DEBUG_EVENT){
528 AddThread(de.dwThreadId,de.u.CreateThread.hThread);
529 }
530 else if(de.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT){
531 //デバッグダイアログを終了
532 SendMessage(hMainDlg,WM_CLOSE_DEBUGGER,0,0);
533
534 DeleteThread(de.dwThreadId);
535
536 //"スレッド(&H%X)はコード &H%X で終了しました。\r\n"
537 sprintf(temporary,STRING_DEBUG_THREADFINISH,de.dwThreadId,de.u.ExitProcess.dwExitCode);
538 DebugMessage(temporary);
539
540 //"プログラムはコード &H%X で終了しました。\r\n"
541 sprintf(temporary,STRING_DEBUG_PROCESSFINISH,de.u.ExitProcess.dwExitCode);
542 DebugMessage(temporary);
543 break;
544 }
545 else if(de.dwDebugEventCode==EXIT_THREAD_DEBUG_EVENT){
546 //"スレッド(&H%X)はコード &H%X で終了しました。\r\n"
547 sprintf(temporary,STRING_DEBUG_THREADFINISH,de.dwThreadId,de.u.ExitThread.dwExitCode);
548 DebugMessage(temporary);
549
550 //以前にシングルステップ実行をした場合
551 //ステップ実行を解除
552 if(dwStepRun){
553 extern HWND hDebugWnd;
554 if(hDebugWnd) SendMessage(hDebugWnd,WM_VARLIST_CLOSE,0,0);
555
556 for(i4=0;i4<MAX_DEBUG_THREAD;i4++){
557 if(de.dwThreadId==_DebugSys_dwThreadID[i4]) break;
558 }
559 Context.ContextFlags=CONTEXT_CONTROL;
560 GetThreadContext(array_hDebugThread[i4],&Context);
561
562 ReleaseSingleStep(dwStepRun,array_hDebugThread[i4],&Context);
563 }
564
565 DeleteThread(de.dwThreadId);
566 }
567 else if(de.dwDebugEventCode==OUTPUT_DEBUG_STRING_EVENT){
568 ReadProcessMemory(hDebugProcess,(void *)de.u.DebugString.lpDebugStringData,temporary,de.u.DebugString.nDebugStringLength,&lpAccBytes);
569 DebugMessage(temporary);
570 }
571 else if(de.dwDebugEventCode==EXCEPTION_DEBUG_EVENT){
572
573 //////////////////////////////////////
574 // モジュールを再確認
575 // ※DLLへのデバッグ分岐を可能にする
576 //////////////////////////////////////
577
578
579 //初回例外は無視
580 if(bFirstBreak){
581 bFirstBreak=0;
582 goto NextContinue;
583 }
584
585 for(i2=0;;i2++){
586 if(_DebugSys_dwThreadID[i2]==de.dwThreadId) break;
587 }
588
589 //スレッド情報をリフレッシュ
590 if(!pobj_dti->Reflesh(i2)){
591 MessageBox(hOwnerEditor,"デバッグ情報が壊れています。ターゲットファイルを再コンパイルしてください。","ActiveBasic",MB_OK|MB_ICONEXCLAMATION);
592
593 break;
594 }
595
596 if(de.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_ACCESS_VIOLATION){
597
598 //"スレッド(&H%X)でアクセス違反がありました(EPI=&H%08X)。\r\n"
599 sprintf(temporary,STRING_DEBUG_THREAD_ACCESSVIOLATION,de.dwThreadId,(ULONG_PTR)de.u.Exception.ExceptionRecord.ExceptionAddress);
600 DebugMessage(temporary);
601
602 MessageBeep(MB_ICONEXCLAMATION);
603 ShowVarList(&de,1);
604 break;
605 }
606 else if(de.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT||
607 de.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_SINGLE_STEP){
608 /////////////////////////
609 // ブレークポイント
610 /////////////////////////
611
612 if(de.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_SINGLE_STEP){
613 //CPU機構のシングルステップによるブレークポイント
614 //※シングルステップを解除
615 ReleaseCPUSingleStep();
616 }
617
618 i3=dwStepRun;
619
620 for(i4=0;i4<MAX_DEBUG_THREAD;i4++){
621 if(de.dwThreadId==_DebugSys_dwThreadID[i4]) break;
622 }
623 Context.ContextFlags=CONTEXT_CONTROL;
624 GetThreadContext(array_hDebugThread[i4],&Context);
625
626 if(i3==0||
627 i3&&(!(ImageBase+MemPos_CodeSection<=EIP_RIP(Context)&&EIP_RIP(Context)<ImageBase+MemPos_CodeSection+FileSize_CodeSection))
628 ){
629 //"スレッド(&H%X)のブレーク ポイント(EPI=&H%08X)。\r\n"
630 sprintf(temporary,STRING_DEBUG_BREAKPOINT,de.dwThreadId,(ULONG_PTR)de.u.Exception.ExceptionRecord.ExceptionAddress);
631 DebugMessage(temporary);
632 }
633
634 ShowVarList(&de,0);
635
636 //ステップ実行を解除
637 ReleaseSingleStep(i3,array_hDebugThread[i4],&Context);
638
639 if(dwStepRun){
640 //新たにシングルステップを行う場合
641
642 if(i4!=NextStepThreadNum){
643 //次回のステップ対象が別スレッドの場合
644 Context.ContextFlags=CONTEXT_CONTROL;
645 GetThreadContext(array_hDebugThread[NextStepThreadNum],&Context);
646 }
647
648 if(ImageBase+MemPos_CodeSection <= EIP_RIP(Context) &&
649 EIP_RIP(Context) < ImageBase+MemPos_CodeSection+FileSize_CodeSection){
650 //Debug命令語が続く場合はシングルステップは不要になるので、無効にする
651 //(オリジナルコード内のみ)
652 if(OpBuffer[EIP_RIP(Context)-ImageBase-MemPos_CodeSection]==(char)0xCC)
653 dwStepRun=0;
654 }
655 if(dwStepRun==1){
656 //ステップイン
657StepIn:
658 //シングルステップON
659 WriteProcessMemory(hDebugProcess,(void *)(ULONG_PTR)(ImageBase+MemPos_CodeSection),
660 pobj_DBDebugSection->pobj_now->SingleStepCodeBuffer,
661 FileSize_CodeSection,&lpAccBytes);
662
663 //次の命令語のブレーク命令は解除しておく(シングルステップ実行後のみ)
664 //(オリジナルコード内のみ)
665 if(i3&&ImageBase+MemPos_CodeSection<=EIP_RIP(Context)&&EIP_RIP(Context)<ImageBase+MemPos_CodeSection+FileSize_CodeSection)
666 WriteProcessMemory(hDebugProcess,(void *)EIP_RIP(Context),&OpBuffer[EIP_RIP(Context)-ImageBase-MemPos_CodeSection],1,&lpAccBytes);
667
668 //他のスレッドを一時中断
669 for(i4=0;i4<MAX_DEBUG_THREAD;i4++){
670 if(_DebugSys_dwThreadID[i4] && NextStepThreadNum!=i4)
671 SuspendThread(array_hDebugThread[i4]);
672 }
673 }
674 else if(dwStepRun==2){
675 //ステップオーバー
676
677 BOOL bRet;
678 bRet=ReadProcessMemory(hDebugProcess,
679 (void *)EIP_RIP(Context),
680 temporary,
681 5,
682 &lpAccBytes);
683 if(!bRet) MessageBox(hMainDlg,"プロセスメモリーの読み込みに失敗","error",MB_OK);
684
685 extern const UserProc *pSub_DebugSys_EndProc;
686 if((BYTE)temporary[0]==0xE8&&
687 *((long *)(temporary+1))+5==(long)rva_to_real(pSub_DebugSys_EndProc->GetBeginOpAddress())-(long)EIP_RIP(Context)){
688 //プロシージャの終端位置の場合はステップインを行う
689 goto StepIn;
690 }
691
692 extern int GlobalOpBufferSize;
693 if(ImageBase+MemPos_CodeSection<=pobj_dti->lplpObp[pobj_dti->iProcLevel]&&
694 pobj_dti->lplpObp[pobj_dti->iProcLevel]<ImageBase+MemPos_CodeSection+GlobalOpBufferSize){
695 //シングルステップON
696 WriteProcessMemory(hDebugProcess,
697 (void *)(ULONG_PTR)(ImageBase+MemPos_CodeSection),
698 pobj_DBDebugSection->pobj_now->SingleStepCodeBuffer,
699 GlobalOpBufferSize,
700 &lpAccBytes);
701 }
702 else{
703 //プロシージャを識別
704 pUserProc=GetSubFromObp(pobj_dti->lplpObp[pobj_dti->iProcLevel]);
705
706 //シングルステップON
707 WriteProcessMemory(hDebugProcess,
708 (void *)rva_to_real(pUserProc->GetBeginOpAddress()),
709 pobj_DBDebugSection->pobj_now->SingleStepCodeBuffer+pUserProc->GetBeginOpAddress(),
710 pUserProc->GetEndOpAddress()-pUserProc->GetBeginOpAddress(),
711 &lpAccBytes);
712 }
713
714 //次の命令語のブレーク命令は解除しておく(シングルステップ実行後のみ)
715 //(オリジナルコード内のみ)
716 if(i3&&ImageBase+MemPos_CodeSection<=EIP_RIP(Context)&&EIP_RIP(Context)<ImageBase+MemPos_CodeSection+FileSize_CodeSection)
717 WriteProcessMemory(hDebugProcess,(void *)EIP_RIP(Context),&OpBuffer[EIP_RIP(Context)-ImageBase-MemPos_CodeSection],1,&lpAccBytes);
718
719 //他のスレッドを一時中断
720 for(i4=0;i4<MAX_DEBUG_THREAD;i4++){
721 if(_DebugSys_dwThreadID[i4] && NextStepThreadNum!=i4)
722 SuspendThread(array_hDebugThread[i4]);
723 }
724 }
725 }
726 }
727 else if(de.u.Exception.ExceptionRecord.ExceptionCode==STATUS_INTEGER_DIVIDE_BY_ZERO){
728 //"0による除算が行われました。スレッド(&H%X) ブレーク ポイント(EPI=&H%08X)。\r\n"
729 sprintf(temporary,STRING_DEBUG_DIVIDE_BY_ZERO,de.dwThreadId,(ULONG_PTR)de.u.Exception.ExceptionRecord.ExceptionAddress);
730 DebugMessage(temporary);
731
732 ShowVarList(&de,1);
733 break;
734 }
735 else if(de.u.Exception.ExceptionRecord.ExceptionCode==STATUS_NO_MEMORY){
736 //"メモリ不足、またはヒープが壊れていることが原因で、メモリの割り当てに失敗しました。スレッド(&H%X) ブレーク ポイント(EPI=&H%08X)。\r\n"
737 sprintf(temporary,STRING_DEBUG_DIVIDE_NO_MEMORY,de.dwThreadId,(ULONG_PTR)de.u.Exception.ExceptionRecord.ExceptionAddress);
738 DebugMessage(temporary);
739
740 ShowVarList(&de,1);
741 break;
742 }
743 else{
744 //"例外処理\ncode:%X"
745 sprintf(temporary,STRING_DEBUG_ERROR,de.u.Exception.ExceptionRecord.ExceptionCode);
746 DebugMessage(temporary);
747 }
748 }
749NextContinue:
750 ContinueDebugEvent(de.dwProcessId,de.dwThreadId,DBG_CONTINUE);
751 }
752
753 extern HWND hDebugWnd;
754 if(hDebugWnd) SendMessage(hDebugWnd,WM_COMMAND,IDCANCEL,0);
755
756 //デバッグに利用した情報を解放
757 delete pobj_DBDebugSection;
758
759 //デバッグスレッド情報を解放
760 delete pobj_dti;
761
762 //ブレークポイントを解放
763 delete pobj_DBBreakPoint;
764
765 //"閉じる"
766 SetDlgItemText(hMainDlg,IDOK,STRING_CLOSE);
767
768 SendMessage(hOwnerEditor,WM_DESTROYDEBUGGERBASE,0,0);
769}
Note: See TracBrowser for help on using the repository browser.