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

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

文字列のconst化など

File size: 24.2 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 foreach (auto pUserProc, compiler.GetObjectModule().meta.GetUserProcs())
279 {
280 if(rva_to_real(pUserProc->GetBeginOpAddress()) <= pos &&
281 pos < rva_to_real(pUserProc->GetEndOpAddress()))
282 {
283 return pUserProc;
284 }
285 }
286 return NULL;
287}
288void ReleaseSingleStep(DWORD dwBeforeStepRun,HANDLE hThread,CONTEXT *pContext){
289 //以前にシングルステップ実行をした場合
290 extern DWORD ImageBase;
291 extern int MemPos_CodeSection;
292 extern int FileSize_CodeSection;
293 int i2;
294 ULONG_PTR lpAccBytes;
295
296 ///////////////////////////
297 // シングルステップOFF
298 ///////////////////////////
299
300 //ユーザー指定のブレークポイントをセット
301 WriteProcessMemory(hDebugProcess,
302 (void *)(ULONG_PTR)(ImageBase+MemPos_CodeSection),
303 debugSectionCollection.GetCurrent().BreakStepCodeBuffer,
304 FileSize_CodeSection,&lpAccBytes);
305
306 //次に実行すべき命令はユーザー指定によるブレークポイントをはずしておく
307 if(ImageBase+MemPos_CodeSection<=EIP_RIP(*pContext)&&EIP_RIP(*pContext)<ImageBase+MemPos_CodeSection+FileSize_CodeSection){
308 if(OpBuffer[EIP_RIP(*pContext)-ImageBase-MemPos_CodeSection-1]!=
309 debugSectionCollection.GetCurrent().BreakStepCodeBuffer[EIP_RIP(*pContext)-ImageBase-MemPos_CodeSection-1]){
310 //直前のブレークポイントがユーザー指定によるものだったとき
311
312 //eip/ripを1だけ減少
313 EIP_RIP(*pContext)--;
314 SetThreadContext(hThread,pContext);
315
316 //ブレークポイントを解除
317 WriteProcessMemory(hDebugProcess,(void *)EIP_RIP(*pContext),&OpBuffer[EIP_RIP(*pContext)-ImageBase-MemPos_CodeSection],1,&lpAccBytes);
318
319
320 extern int StepCursorObpSchedule;
321 if(StepCursorObpSchedule==(int)(EIP_RIP(*pContext)-ImageBase-MemPos_CodeSection)){
322 //カーソル行までのステップ実行の場合
323 debugSectionCollection.GetCurrent().BreakStepCodeBuffer[StepCursorObpSchedule]=StepCursor_BackupChar;
324 StepCursorObpSchedule=-1;
325 }
326
327 return;
328 }
329 }
330
331
332 if(dwBeforeStepRun){
333 //直前にシングルステップを行った場合
334 if(ImageBase+MemPos_CodeSection <= EIP_RIP(*pContext) &&
335 EIP_RIP(*pContext) < ImageBase+MemPos_CodeSection+FileSize_CodeSection){
336 //オリジナルコード内のみ、シングルステップ用の"int 3"を考慮
337 EIP_RIP(*pContext)--;
338 SetThreadContext(hThread,pContext);
339 }
340
341 //他のスレッドのサスペンドを解除
342 for(i2=0;i2<MAX_DEBUG_THREAD;i2++){
343 if(array_hDebugThread[i2] && hThread!=array_hDebugThread[i2])
344 ResumeThread(array_hDebugThread[i2]);
345 }
346 }
347}
348
349void Set_DebugSys_dwThreadID()
350{
351 foreach( DebugSection *pDebugSection, debugSectionCollection.debugSections )
352 {
353 ULONG_PTR lpAccBytes;
354 WriteProcessMemory(hDebugProcess,
355 (void *)(ULONG_PTR)(pDebugSection->dwImageBase + pDebugSection->dwRVA_RWSection),
356 _DebugSys_dwThreadID,
357 sizeof(DWORD)*MAX_DEBUG_THREAD,
358 &lpAccBytes
359 );
360 }
361}
362void AddThread(DWORD dwThreadId, HANDLE hThread){
363 int i;
364
365
366 for(i=0;i<MAX_DEBUG_THREAD;i++){
367 if(_DebugSys_dwThreadID[i]==0){
368 _DebugSys_dwThreadID[i]=dwThreadId;
369 array_hDebugThread[i]=hThread;
370 break;
371 }
372 }
373
374 Set_DebugSys_dwThreadID();
375}
376void DeleteThread(DWORD dwThreadId){
377 int i;
378
379 for(i=0;i<MAX_DEBUG_THREAD;i++){
380 if(_DebugSys_dwThreadID[i]==dwThreadId){
381 _DebugSys_dwThreadID[i]=0;
382 array_hDebugThread[i]=0;
383 break;
384 }
385 }
386
387 Set_DebugSys_dwThreadID();
388}
389
390void DebugProgram(void){
391 extern HWND hMainDlg;
392 extern DWORD ImageBase;
393 extern int MemPos_CodeSection;
394 extern int MemPos_RWSection;
395 extern int FileSize_CodeSection;
396 int i2,i3,i4;
397 char temporary[1024];
398
399 char ExeFilePathForDll[MAX_PATH];
400 if( compiler.IsDll() ){
401 //DLLをデバッグする場合
402 extern char szDebugExeForDll[1024];
403 if(szDebugExeForDll[0]){
404 //指定済み
405 lstrcpy(ExeFilePathForDll,szDebugExeForDll);
406 }
407 else{
408 //ユーザーに実行ファイルを選択させる
409 extern HWND hOwnerEditor;
410 extern const LPCSTR ExeFileFilter;
411 if(!GetFilePathDialog(hOwnerEditor,ExeFilePathForDll,ExeFileFilter,"デバッグ用の実行可能ファイルを指定してください。",1)) return;
412 }
413 }
414
415
416 //"中断"
417 SetDlgItemText(hMainDlg,IDOK,STRING_STOP);
418
419 SendMessage(hOwnerEditor,WM_SETDEBUGGERBASE,0,0);
420
421 //カレントディレクトリを設定
422 extern char BasicCurDir[MAX_PATH];
423 SetCurrentDirectory(BasicCurDir);
424
425 SendDlgItemMessage(hMainDlg,IDC_SHOWERROR,BM_SETCHECK,BST_UNCHECKED,0);
426 SendDlgItemMessage(hMainDlg,IDC_SHOWDEBUG,BM_SETCHECK,BST_CHECKED,0);
427 SendMessage(hMainDlg,WM_COMMAND,IDC_SHOWDEBUG,0);
428
429 //ブレークポイントを生成
430 pobj_DBBreakPoint=new BreakPointManager;
431
432
433 // デバッグをスタート
434 debugger.DebugStart();
435
436
437 if( program.IsAttach() )
438 {
439 ////プロセスIDを元にハンドルを取得
440 //HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,0, program.GetAttachProcessId() );
441 //if(!hProcess)
442 //{
443 // DebugMessage("アタッチに失敗しました。");
444 // return;
445 //}
446
447 ////そのプロセスにおける実行モジュールのインスタンスハンドルを取得
448 //HINSTANCE hModule;
449 //DWORD cbReturned;
450 //if(!EnumProcessModules( hProcess, &hModule, sizeof(HINSTANCE), &cbReturned ))
451 //{
452 // DebugMessage("アタッチに失敗しました。");
453 // return;
454 //}
455
456 //実行ファイル名を取得
457 auto tempOutputFilePath = ActiveBasic::Common::GetExecutableModulePath(program.GetAttachProcessId());
458 program.SetOutputFilePath( tempOutputFilePath.string().c_str() );
459
460 //CloseHandle(hProcess);
461
462/*
463 //デバッグ用の拡張情報を取得
464 pobj_DebugSection->load(program.GetOutputFilePath().c_str());*/
465
466 if(!DebugActiveProcess( program.GetAttachProcessId() ))
467 {
468 DebugMessage("アタッチに失敗しました。");
469 return;
470 }
471 }
472 else{
473 /*if(!pobj_DebugSection->load(program.GetOutputFilePath().c_str())){
474 extern BOOL bDebugCompile;
475 bDebugCompile=1;
476 Build();
477 pobj_DebugSection->load(program.GetOutputFilePath().c_str());
478 }*/
479
480 //スレッドを生成
481 extern char szDebugCmdLine[1024];
482 STARTUPINFO si;
483 PROCESS_INFORMATION pi;
484 memset(&si,0,sizeof(STARTUPINFO));
485 si.cb=sizeof(STARTUPINFO);
486 if( !compiler.IsDll() ){
487 //EXEファイルをデバッグ
488 CreateProcess(program.GetOutputFilePath().c_str(),szDebugCmdLine,NULL,NULL,0,NORMAL_PRIORITY_CLASS|DEBUG_ONLY_THIS_PROCESS|CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi);
489 }
490 else{
491 //DLLファイルをデバッグ
492 CreateProcess(ExeFilePathForDll,szDebugCmdLine,NULL,NULL,0,NORMAL_PRIORITY_CLASS|DEBUG_ONLY_THIS_PROCESS|CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi);
493 }
494
495 CloseHandle(pi.hProcess);
496 CloseHandle(pi.hThread);
497 }
498
499
500 //デバッグスレッド情報(プロシージャの階層構造を管理)を生成
501 pobj_dti=new CDebugThreadInfo();
502
503 UserProc *pUserProc;
504
505 extern DWORD dwStepRun;
506 BOOL bFirstBreak=1;
507 CONTEXT Context;
508 HANDLE hMainThread;
509 ULONG_PTR lpAccBytes;
510
511 DEBUG_EVENT de;
512 memset(&de,0,sizeof(DEBUG_EVENT));
513
514 while(WaitForDebugEvent(&de,INFINITE)){
515 if(de.dwDebugEventCode==LOAD_DLL_DEBUG_EVENT){
516 WCHAR wcBuf[MAX_PATH];
517 LONG_PTR lpData;
518
519 wcBuf[0]=0;
520 temporary[0]=0;
521
522 if(de.u.LoadDll.lpImageName){
523 if(!ReadProcessMemory(hDebugProcess,de.u.LoadDll.lpImageName,&lpData,sizeof(LONG_PTR),&lpAccBytes)){
524 sprintf(temporary,"ロードされたDLLの名前取得(アドレス:&H%08x)に失敗しました。\r\n",(ULONG_PTR)de.u.LoadDll.lpImageName);
525 DebugMessage(temporary);
526 goto NextContinue;
527 }
528 if(!lpData) goto Attach_DllLoad;
529
530 if(!ReadProcessMemory(hDebugProcess,(void *)lpData,wcBuf,sizeof(WCHAR)*MAX_PATH,&lpAccBytes)){
531 sprintf(temporary,"ロードされたDLLの名前取得(アドレス:&H%08x)に失敗しました。\r\n",lpData);
532 DebugMessage(temporary);
533 goto NextContinue;
534 }
535
536 if(de.dwThreadId,de.u.LoadDll.fUnicode)
537 WideCharToMultiByte(CP_ACP,0,wcBuf,-1,temporary,255,NULL,NULL);
538 else lstrcpy(temporary,(char *)wcBuf);
539 }
540 else{
541Attach_DllLoad:
542 {
543 //アタッチした場合
544 auto path = ActiveBasic::Common::GetModuleFilePath(hDebugProcess, reinterpret_cast<HINSTANCE>(de.u.LoadDll.lpBaseOfDll));
545 strncpy_s(temporary, path.string().c_str(), _TRUNCATE);
546 }
547 }
548
549 char temp2[1024];
550 sprintf(temp2,"\"%s\" をロードしました。\r\n",temporary);
551 DebugMessage(temp2);
552
553
554 //可能であればデバッグ情報を読みとる
555 if(debugSectionCollection.add((HMODULE)de.u.LoadDll.lpBaseOfDll)){
556 debugSectionCollection.choice(0);
557 Set_DebugSys_dwThreadID();
558 }
559
560
561 /*if(lstrcmpi(temporary, program.GetOutputFilePath().c_str())==0){
562 ImageBase=(DWORD)de.u.LoadDll.lpBaseOfDll;
563
564 AddThread(de.dwThreadId,hMainThread);
565 }*/
566 }
567 else if(de.dwDebugEventCode==UNLOAD_DLL_DEBUG_EVENT){
568 //DLLのアンロード
569
570 debugSectionCollection.del((HMODULE)de.u.UnloadDll.lpBaseOfDll);
571 }
572 else if(de.dwDebugEventCode==CREATE_PROCESS_DEBUG_EVENT){
573 hDebugProcess=de.u.CreateProcessInfo.hProcess;
574 hMainThread=de.u.CreateProcessInfo.hThread;
575 processIdDebug = de.dwProcessId;
576
577 if(debugSectionCollection.add((HMODULE)de.u.CreateProcessInfo.lpBaseOfImage)){
578 debugSectionCollection.choice(0);
579 }
580
581 AddThread(de.dwThreadId,de.u.CreateProcessInfo.hThread);
582 }
583 else if(de.dwDebugEventCode==CREATE_THREAD_DEBUG_EVENT){
584 AddThread(de.dwThreadId,de.u.CreateThread.hThread);
585 }
586 else if(de.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT){
587 //デバッグダイアログを終了
588 SendMessage(hMainDlg,WM_CLOSE_DEBUGGER,0,0);
589
590 DeleteThread(de.dwThreadId);
591
592 //"スレッド(&H%X)はコード &H%X で終了しました。\r\n"
593 sprintf(temporary,STRING_DEBUG_THREADFINISH,de.dwThreadId,de.u.ExitProcess.dwExitCode);
594 DebugMessage(temporary);
595
596 //"プログラムはコード &H%X で終了しました。\r\n"
597 sprintf(temporary,STRING_DEBUG_PROCESSFINISH,de.u.ExitProcess.dwExitCode);
598 DebugMessage(temporary);
599 break;
600 }
601 else if(de.dwDebugEventCode==EXIT_THREAD_DEBUG_EVENT){
602 //"スレッド(&H%X)はコード &H%X で終了しました。\r\n"
603 sprintf(temporary,STRING_DEBUG_THREADFINISH,de.dwThreadId,de.u.ExitThread.dwExitCode);
604 DebugMessage(temporary);
605
606 //以前にシングルステップ実行をした場合
607 //ステップ実行を解除
608 if(dwStepRun){
609 extern HWND hDebugWnd;
610 if(hDebugWnd) SendMessage(hDebugWnd,WM_VARLIST_CLOSE,0,0);
611
612 for(i4=0;i4<MAX_DEBUG_THREAD;i4++){
613 if(de.dwThreadId==_DebugSys_dwThreadID[i4]) break;
614 }
615 Context.ContextFlags=CONTEXT_CONTROL;
616 GetThreadContext(array_hDebugThread[i4],&Context);
617
618 ReleaseSingleStep(dwStepRun,array_hDebugThread[i4],&Context);
619 }
620
621 DeleteThread(de.dwThreadId);
622 }
623 else if(de.dwDebugEventCode==OUTPUT_DEBUG_STRING_EVENT){
624 ReadProcessMemory(hDebugProcess,(void *)de.u.DebugString.lpDebugStringData,temporary,de.u.DebugString.nDebugStringLength,&lpAccBytes);
625 DebugMessage(temporary);
626 }
627 else if(de.dwDebugEventCode==EXCEPTION_DEBUG_EVENT){
628
629 //////////////////////////////////////
630 // モジュールを再確認
631 // ※DLLへのデバッグ分岐を可能にする
632 //////////////////////////////////////
633
634
635 //初回例外は無視
636 if(bFirstBreak){
637 bFirstBreak=0;
638 goto NextContinue;
639 }
640
641 for(i2=0;;i2++){
642 if(_DebugSys_dwThreadID[i2]==de.dwThreadId) break;
643 }
644
645 //スレッド情報をリフレッシュ
646 if(!pobj_dti->Reflesh(i2)){
647 MessageBox(hOwnerEditor,"デバッグ情報が壊れています。ターゲットファイルを再コンパイルしてください。","ActiveBasic",MB_OK|MB_ICONEXCLAMATION);
648
649 break;
650 }
651
652 if(de.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_ACCESS_VIOLATION){
653
654 //"スレッド(&H%X)でアクセス違反がありました(EIP=&H%08X)。\r\n"
655 sprintf(temporary,
656 STRING_DEBUG_THREAD_ACCESSVIOLATION,
657 de.dwThreadId,
658 (ULONG_PTR)de.u.Exception.ExceptionRecord.ExceptionAddress,
659#ifdef _AMD64_
660 (ULONG_PTR)Context.Rsp
661#else
662 (ULONG_PTR)Context.Esp
663#endif
664 );
665 DebugMessage(temporary);
666
667 MessageBeep(MB_ICONEXCLAMATION);
668 ShowVarList(&de,1);
669 break;
670 }
671 else if(de.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT||
672 de.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_SINGLE_STEP){
673 /////////////////////////
674 // ブレークポイント
675 /////////////////////////
676
677 if(de.u.Exception.ExceptionRecord.ExceptionCode==EXCEPTION_SINGLE_STEP){
678 //CPU機構のシングルステップによるブレークポイント
679 //※シングルステップを解除
680 ReleaseCPUSingleStep();
681 }
682
683 i3=dwStepRun;
684
685 for(i4=0;i4<MAX_DEBUG_THREAD;i4++){
686 if(de.dwThreadId==_DebugSys_dwThreadID[i4]) break;
687 }
688 Context.ContextFlags=CONTEXT_CONTROL | CONTEXT_INTEGER;
689 GetThreadContext(array_hDebugThread[i4],&Context);
690
691 if(i3==0||
692 i3&&(!(ImageBase+MemPos_CodeSection<=EIP_RIP(Context)&&EIP_RIP(Context)<ImageBase+MemPos_CodeSection+FileSize_CodeSection))
693 ){
694 //"スレッド(&H%X)のブレーク ポイント(EIP=&H%08X)。\r\n"
695 sprintf(temporary,
696 STRING_DEBUG_BREAKPOINT,
697 de.dwThreadId,
698 (ULONG_PTR)de.u.Exception.ExceptionRecord.ExceptionAddress,
699#ifdef _AMD64_
700 (ULONG_PTR)Context.Rsp
701#else
702 (ULONG_PTR)Context.Esp
703#endif
704 );
705 DebugMessage(temporary);
706 }
707
708 ShowVarList(&de,0);
709
710 //ステップ実行を解除
711 ReleaseSingleStep(i3,array_hDebugThread[i4],&Context);
712
713 if(dwStepRun){
714 //新たにシングルステップを行う場合
715
716 if(i4!=NextStepThreadNum){
717 //次回のステップ対象が別スレッドの場合
718 Context.ContextFlags=CONTEXT_CONTROL;
719 GetThreadContext(array_hDebugThread[NextStepThreadNum],&Context);
720 }
721
722 if(ImageBase+MemPos_CodeSection <= EIP_RIP(Context) &&
723 EIP_RIP(Context) < ImageBase+MemPos_CodeSection+FileSize_CodeSection){
724 //Debug命令語が続く場合はシングルステップは不要になるので、無効にする
725 //(オリジナルコード内のみ)
726 if(OpBuffer[EIP_RIP(Context)-ImageBase-MemPos_CodeSection]==(char)0xCC)
727 dwStepRun=0;
728 }
729 if(dwStepRun==1){
730 //ステップイン
731StepIn:
732 //シングルステップON
733 WriteProcessMemory(hDebugProcess,(void *)(ULONG_PTR)(ImageBase+MemPos_CodeSection),
734 debugSectionCollection.GetCurrent().SingleStepCodeBuffer,
735 FileSize_CodeSection,&lpAccBytes);
736
737 //次の命令語のブレーク命令は解除しておく(シングルステップ実行後のみ)
738 //(オリジナルコード内のみ)
739 if(i3&&ImageBase+MemPos_CodeSection<=EIP_RIP(Context)&&EIP_RIP(Context)<ImageBase+MemPos_CodeSection+FileSize_CodeSection)
740 WriteProcessMemory(hDebugProcess,(void *)EIP_RIP(Context),&OpBuffer[EIP_RIP(Context)-ImageBase-MemPos_CodeSection],1,&lpAccBytes);
741
742 //他のスレッドを一時中断
743 for(i4=0;i4<MAX_DEBUG_THREAD;i4++){
744 if(_DebugSys_dwThreadID[i4] && NextStepThreadNum!=i4)
745 SuspendThread(array_hDebugThread[i4]);
746 }
747 }
748 else if(dwStepRun==2){
749 //ステップオーバー
750
751 BOOL bRet;
752 bRet=ReadProcessMemory(hDebugProcess,
753 (void *)EIP_RIP(Context),
754 temporary,
755 5,
756 &lpAccBytes);
757 if(!bRet) MessageBox(hMainDlg,"プロセスメモリーの読み込みに失敗","error",MB_OK);
758
759 extern const UserProc *pSub_DebugSys_EndProc;
760 if((BYTE)temporary[0]==0xE8&&
761 *((long *)(temporary+1))+5==(long)rva_to_real(pSub_DebugSys_EndProc->GetBeginOpAddress())-(long)EIP_RIP(Context)){
762 //プロシージャの終端位置の場合はステップインを行う
763 goto StepIn;
764 }
765
766 extern int GlobalOpBufferSize;
767 if(ImageBase+MemPos_CodeSection<=pobj_dti->lplpObp[pobj_dti->iProcLevel]&&
768 pobj_dti->lplpObp[pobj_dti->iProcLevel]<ImageBase+MemPos_CodeSection+GlobalOpBufferSize){
769 //シングルステップON
770 WriteProcessMemory(hDebugProcess,
771 (void *)(ULONG_PTR)(ImageBase+MemPos_CodeSection),
772 debugSectionCollection.GetCurrent().SingleStepCodeBuffer,
773 GlobalOpBufferSize,
774 &lpAccBytes);
775 }
776 else{
777 //プロシージャを識別
778 pUserProc=GetSubFromObp(pobj_dti->lplpObp[pobj_dti->iProcLevel]);
779
780 //シングルステップON
781 WriteProcessMemory(hDebugProcess,
782 (void *)rva_to_real(pUserProc->GetBeginOpAddress()),
783 debugSectionCollection.GetCurrent().SingleStepCodeBuffer+pUserProc->GetBeginOpAddress(),
784 pUserProc->GetEndOpAddress()-pUserProc->GetBeginOpAddress(),
785 &lpAccBytes);
786 }
787
788 //次の命令語のブレーク命令は解除しておく(シングルステップ実行後のみ)
789 //(オリジナルコード内のみ)
790 if(i3&&ImageBase+MemPos_CodeSection<=EIP_RIP(Context)&&EIP_RIP(Context)<ImageBase+MemPos_CodeSection+FileSize_CodeSection)
791 WriteProcessMemory(hDebugProcess,(void *)EIP_RIP(Context),&OpBuffer[EIP_RIP(Context)-ImageBase-MemPos_CodeSection],1,&lpAccBytes);
792
793 //他のスレッドを一時中断
794 for(i4=0;i4<MAX_DEBUG_THREAD;i4++){
795 if(_DebugSys_dwThreadID[i4] && NextStepThreadNum!=i4)
796 SuspendThread(array_hDebugThread[i4]);
797 }
798 }
799 }
800 }
801 else if(de.u.Exception.ExceptionRecord.ExceptionCode==STATUS_INTEGER_DIVIDE_BY_ZERO){
802 //"0による除算が行われました。スレッド(&H%X) ブレーク ポイント(EIP=&H%08X)。\r\n"
803 sprintf(temporary,STRING_DEBUG_DIVIDE_BY_ZERO,de.dwThreadId,(ULONG_PTR)de.u.Exception.ExceptionRecord.ExceptionAddress);
804 DebugMessage(temporary);
805
806 ShowVarList(&de,1);
807 break;
808 }
809 else if(de.u.Exception.ExceptionRecord.ExceptionCode==STATUS_NO_MEMORY){
810 //"メモリ不足、またはヒープが壊れていることが原因で、メモリの割り当てに失敗しました。スレッド(&H%X) ブレーク ポイント(EIP=&H%08X)。\r\n"
811 sprintf(temporary,STRING_DEBUG_DIVIDE_NO_MEMORY,de.dwThreadId,(ULONG_PTR)de.u.Exception.ExceptionRecord.ExceptionAddress);
812 DebugMessage(temporary);
813
814 ShowVarList(&de,1);
815 break;
816 }
817 else{
818 //"例外処理\ncode:%X"
819 sprintf(temporary,STRING_DEBUG_ERROR,de.u.Exception.ExceptionRecord.ExceptionCode);
820 DebugMessage(temporary);
821 }
822 }
823NextContinue:
824 ContinueDebugEvent(de.dwProcessId,de.dwThreadId,DBG_CONTINUE);
825 }
826
827 extern HWND hDebugWnd;
828 if(hDebugWnd) SendMessage(hDebugWnd,WM_COMMAND,IDCANCEL,0);
829
830 //デバッグスレッド情報を解放
831 delete pobj_dti;
832
833 //ブレークポイントを解放
834 delete pobj_DBBreakPoint;
835
836 //"閉じる"
837 SetDlgItemText(hMainDlg,IDOK,STRING_CLOSE);
838
839 debugger.FinishDebug();
840
841 SendMessage(hOwnerEditor,WM_DESTROYDEBUGGERBASE,0,0);
842}
Note: See TracBrowser for help on using the repository browser.