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

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

sourceをObjectModuleに入れた

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