root/trunk/ElephantDebugApi/debugger_concrete.h

Revision 5, 8.7 kB (checked in by qbert, 3 years ago)

Initial ( and last :( ) commit

Line 
1 #ifndef DEBUGER_CONTRETE_H
2 #define DEBUGER_CONTRETE_H
3 #include <windows.h>
4
5 #include "edbgfunctions.h"
6 #include "helper_functions.h"
7 #include "debugger_interfaces.h"
8
9
10 // VERY IMPORTANT!!!
11 // you must run this as a thread, or the pause and resume will pause your program , see bottom
12
13 class Win32Debugger : IWin32Debugger {
14 private:
15     IDebugDispatcher * dispatch;
16     bool firstChanceException;
17     string path;
18     CONTEXT context; // machine specific data, whats in the registers etc
19     DEBUG_EVENT dbg; // debug structure
20     STARTUPINFOA startup; // proccess info, used in CreateProccess
21     PROCESS_INFORMATION output;     //proccess information
22     bool paused;
23     bool stop;
24
25 public:
26
27     Win32Debugger (IDebugDispatcher * disp ) : dispatch(disp) {
28         firstChanceException = true;
29     }
30
31     ~Win32Debugger ( ) {
32         delete dispatch;
33     }
34
35     virtual bool Run( ) {
36         paused = false;
37         stop = false;
38         startup.cb=sizeof(startup);
39         ZeroMemory(&startup, sizeof(startup) );
40         char* lpszPath = strdup(path.c_str() );
41         int result = CreateProcess  (lpszPath, NULL , NULL, NULL, false,  DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &startup, &output);
42        
43         if ( result == 0 ) {
44             //PrintError();
45             return false;
46         }
47         MainLoop();
48         return true;
49    
50     }
51     virtual bool Load(const string& _path ) {
52         path = _path;
53         return false;
54     }
55
56
57     virtual void MainLoop () {
58         uint continueStatus = DBG_CONTINUE;
59        
60         bool firstRun = true;
61
62         while ( true )
63         {
64             while ( paused ) Sleep(1);
65             if ( stop ) return;
66
67             WaitForDebugEvent(&dbg, INFINITE);
68             switch ( dbg.dwDebugEventCode )
69             {
70
71             case EXCEPTION_DEBUG_EVENT  :
72             {
73                 dispatch->OnOutput(get_exception_name(dbg.u.Exception.ExceptionRecord.ExceptionCode));
74                 if ( !HandleDebugException(dbg.u.Exception.ExceptionRecord.ExceptionCode) )
75                 {
76
77                     if ( firstChanceException )
78                     {
79                         firstChanceException  =false;
80 /*
81                     }
82                     else
83                     {
84 */
85 //                      CV4FileListing listing = GetListingForException(dbg.u.Exception.ExceptionRecord,output.hProcess,(char*)path.substr(0,path.find_last_of("\\") ) .c_str());
86
87                         //::MessageBox(0,listing.filePath.c_str() ,0,0);
88                         vector<BackTraceItem> bt;
89
90                         BackTrace(bt);
91                         dispatch->OnException(ExceptionData(get_exception_name(dbg.u.Exception.ExceptionRecord.ExceptionCode), "FilePath" ,-1, bt ));
92
93                         continueStatus = DBG_EXCEPTION_NOT_HANDLED;
94
95                     }
96                 }
97
98                 else
99                 {
100
101
102                     if (firstRun && dbg.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
103                     {
104                         firstRun = false;
105                     }
106                     else
107                     {
108 //                      AfxMessageBox("here");
109                         vector<BackTraceItem> bt;
110                         BackTrace(bt);
111 //                          sendData(get_exception_name(dbg.u.Exception.ExceptionRecord.ExceptionCode) );
112                         for ( int i = 0; i < bt.size();i++) { ::MessageBox(0,bt[i].symName.c_str() ,"HERESS",0 ); }
113                         RegisterDumpData r = DumpRegisters();
114                         ThreadData t; //TODO needed?
115                         string filePath = "Unkown";
116                         int lineNumber = -1;
117                         if ( bt.size() > 1 ) {
118                             filePath = bt[1].fileName;
119                             lineNumber = bt[1].lineNumber;
120                         }
121
122                         ExceptionData e(get_exception_name(dbg.u.Exception.ExceptionRecord. ExceptionCode), filePath, lineNumber,bt  );
123                         ProcessData p; //TODO needed?
124                         dispatch->OnBreakPoint(BreakData(e, t, r, p) );                     
125
126                     }
127                        
128                 }
129
130                 break;
131             }
132
133             case CREATE_THREAD_DEBUG_EVENT  :
134             {
135                 dispatch->OnOutput(get_event_name(dbg.dwDebugEventCode ) );
136 //                  sendData(get_event_name(dbg.dwDebugEventCode ) );
137 //                  onCreateThread.notify(ThreadData.create());
138                 break;
139             }
140
141             case CREATE_PROCESS_DEBUG_EVENT :
142             {
143
144                 dispatch->OnOutput(get_event_name(dbg.dwDebugEventCode ) );
145 //                  sendData(get_event_name(dbg.dwDebugEventCode ) );
146 //                  onCreateProccess.notify(ProcessData.create());
147                 break;
148             }
149
150             case EXIT_THREAD_DEBUG_EVENT    :
151             {
152                 dispatch->OnOutput(get_event_name(dbg.dwDebugEventCode ) );
153
154 //                  sendData("\n" ~ get_event_name(dbg.dwDebugEventCode ) );
155 //                  ci.sendDirect("Exiting");
156 //                  onExitThread.notify();
157 //                  running = false;
158 //                  paused = false;
159                 vector<BackTraceItem> bt;
160                 BackTrace(bt);
161 //                          sendData(get_exception_name(dbg.u.Exception.ExceptionRecord.ExceptionCode) );
162                 RegisterDumpData r = DumpRegisters();
163                 ThreadData t; //TODO needed?
164                 string filePath = "Unkown";
165                 int lineNumber = -1;
166                 if ( bt.size() > 1 ) {
167                     filePath = bt[1].fileName;
168                     lineNumber = bt[1].lineNumber;
169                 }
170
171                 ExceptionData e(get_exception_name(dbg.u.Exception.ExceptionRecord. ExceptionCode), filePath, lineNumber,bt  );
172                 ProcessData p; //TODO needed?
173                 dispatch->OnEnd(BreakData(e, t, r, p) );                       
174
175                 return ;
176
177                 break;
178             }
179
180             case EXIT_PROCESS_DEBUG_EVENT   : {
181
182                
183                 dispatch->OnOutput(get_event_name(dbg.dwDebugEventCode ) );
184                 vector<BackTraceItem> bt;
185                 BackTrace(bt);
186 //                          sendData(get_exception_name(dbg.u.Exception.ExceptionRecord.ExceptionCode) );
187                 RegisterDumpData r = DumpRegisters();
188                 ThreadData t; //TODO needed?
189                 string filePath = "Unkown";
190                 int lineNumber = -1;
191                 if ( bt.size() > 1 ) {
192                     filePath = bt[1].fileName;
193                     lineNumber = bt[1].lineNumber;
194                 }
195
196                 ExceptionData e(get_exception_name(dbg.u.Exception.ExceptionRecord. ExceptionCode), filePath, lineNumber,bt  );
197                 ProcessData p; //TODO needed?
198                 dispatch->OnEnd(BreakData(e, t, r, p) );                       
199
200                
201                 return ;
202                 break;
203             }
204
205             case LOAD_DLL_DEBUG_EVENT   :
206             {
207                 dispatch->OnOutput(get_event_name(dbg.dwDebugEventCode ) );
208                 dispatch->OnDllLoad(DLLData(dbg.u.LoadDll, GetDLLName(output.hProcess, dbg))) ;
209                 break;
210             }
211
212             case UNLOAD_DLL_DEBUG_EVENT :
213             {
214                 dispatch->OnOutput(get_event_name(dbg.dwDebugEventCode ) );
215 //                  unloadDLL(findDLL(dbg.u.UnloadDll.lpBaseOfDll));
216                 break;
217             }
218
219             case OUTPUT_DEBUG_STRING_EVENT  :
220             {
221
222                 dispatch->OnOutput(get_event_name(dbg.dwDebugEventCode ) );
223                 char * read_str = new char[dbg.u.DebugString.nDebugStringLength];
224                 ReadDebugString( output.hProcess, dbg.u.DebugString ,read_str ) ;
225                 string  str (read_str);
226                 delete read_str;
227                 dispatch->OnTrace(str);
228                 break;
229             }
230
231             case RIP_EVENT:
232             {
233                 dispatch->OnOutput(get_event_name(dbg.dwDebugEventCode ) );
234 //                  sendData(get_event_name(dbg.dwDebugEventCode ) );
235 //                  onEnd.notify(get_event_name(dbg.dwDebugEventCode ));
236                 break;
237             }
238
239             default :
240
241 //              dispatch->OnEnd(DumpRegisters() );
242 //              paused = false;
243 //              running = false;
244                 return ;
245             }
246        
247
248             ContinueDebugEvent(output.dwProcessId, output.dwThreadId, continueStatus);
249
250         }
251
252 //      paused = false;
253 //      running = false;
254        
255
256        
257
258     }
259     virtual bool End () { return true; }
260    
261     void Pause() { paused = true; }
262
263     void Resume() { paused = false; }
264
265     void Stop() { stop = true; }
266
267
268     string GetDLLName(HANDLE process, DEBUG_EVENT de )
269     {
270
271         char *buffer = new char [MAX_PATH+1];
272         GetModuleFileNameFromHeader(
273             process,
274             de.u.LoadDll.hFile,
275             (DWORD) de.u.LoadDll.lpBaseOfDll,
276             buffer, MAX_PATH+1);
277         string ret(buffer);
278         delete buffer;
279         return ret;
280     }
281
282
283
284     bool HandleDebugException(uint code)
285     {
286         switch ( code )
287         {
288
289         case EXCEPTION_BREAKPOINT :
290             return true;
291
292         default :
293             return false;
294         }
295
296         return false;
297     }
298
299    
300
301     RegisterDumpData DumpRegisters()
302     {
303         SuspendThread(output.hThread );
304         context.ContextFlags = CONTEXT_FULL |
305             CONTEXT_FLOATING_POINT |
306             CONTEXT_DEBUG_REGISTERS;
307         GetThreadContext(output.hThread, &context);
308         RegisterDumpData d(context) ;
309         ResumeThread(output.hThread );
310         return d;
311
312     }
313
314     void BackTrace(vector<BackTraceItem>  & bt)
315     {
316         SuspendThread(output.hThread );
317         context.ContextFlags = CONTEXT_FULL |
318             CONTEXT_FLOATING_POINT |
319             CONTEXT_DEBUG_REGISTERS;
320         GetThreadContext(output.hThread, &context);
321 //      StackBackTrace(output.hProcess, output.hThread, &context,bt);
322 //      ::MessageBox(0,ITOA(bt.size()).c_str(),0,0 );
323
324         ResumeThread(output.hThread );
325
326
327     }
328
329 };
330
331 #endif
332
333
334 // #ifndef DEBUG_THREAD_H
335 // #define DEBUG_THREAD_H
336
337 // class Win32Debugger;
338
339 // struct DebugThreadData {
340 //  Win32Debugger* debugger;
341 //  string path;
342
343 //  ~DebugThreadData() {
344 //      delete debugger;
345 //  }
346 // };
347
348 // UINT StartDebuggerThread(LPVOID);
349
350 // #endif
351
352
353 // #include "stdafx.h"
354 // #include "d2debugger.h"
355 // #include "debugging_threads.h"
356 // #include "debugger_concrete.h"
357
358 // UINT StartDebuggerThread(LPVOID x) {
359 //  DebugThreadData* data = (DebugThreadData*)x;
360 //  theApp.m_pMainFrame->debugHandle = GetCurrentThread();
361 //  Win32Debugger *debug = (Win32Debugger*)data->debugger;
362 //  debug->Load(data->path);
363 //  debug->Run();
364 //  delete data;
365 //  theApp.m_pMainFrame->debugger = NULL;
366 //  return 0;
367 // }
Note: See TracBrowser for help on using the browser.