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

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