source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/Debug.cpp@ 750

Last change on this file since 750 was 750, checked in by イグトランス (egtra), 16 years ago

BOOST_FOREACHを可能なものはVC++ 2005 for eachへ置換(やや速くなる)。

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