source: dev/branches/egtra/ab5.0/abdev/BasicCompiler_Common/Debug.cpp@ 798

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

PSAPIを使用している箇所について、Toolhelp32と選択するよう修正

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