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

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