2 * PROJECT: Dr. Watson crash reporter
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
5 * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
11 #define MS_VC_EXCEPTION_THREAD_NAME 0x406d1388
13 ModuleData::ModuleData(void* addr
)
20 void ModuleData::Update(HANDLE hProcess
)
23 GetModuleInformation(hProcess
, (HMODULE
)BaseAddress
, &mi
, sizeof(mi
));
24 assert(BaseAddress
== mi
.lpBaseOfDll
);
25 Size
= mi
.SizeOfImage
;
27 ModuleName
.resize(MAX_PATH
);
28 DWORD dwLen
= GetModuleFileNameExA(hProcess
, (HMODULE
)BaseAddress
, &ModuleName
[0], ModuleName
.size());
29 ModuleName
.resize(dwLen
);
33 ThreadData::ThreadData(HANDLE handle
)
36 memset(&Context
, 0, sizeof(Context
));
39 void ThreadData::Update()
41 Context
.ContextFlags
= CONTEXT_INTEGER
| CONTEXT_CONTROL
| CONTEXT_DEBUG_REGISTERS
;
42 GetThreadContext(Handle
, &Context
);
52 memset(&ExceptionInfo
, 0, sizeof(ExceptionInfo
));
56 bool UpdateFromEvent(DEBUG_EVENT
& evt
, DumpData
& data
)
58 switch(evt
.dwDebugEventCode
)
60 case CREATE_PROCESS_DEBUG_EVENT
:
62 data
.ProcessPath
.resize(MAX_PATH
);
63 DWORD len
= GetModuleFileNameExA(evt
.u
.CreateProcessInfo
.hProcess
, NULL
, &data
.ProcessPath
[0], data
.ProcessPath
.size());
66 data
.ProcessPath
.resize(len
);
67 std::string::size_type pos
= data
.ProcessPath
.find_last_of("\\/");
68 if (pos
!= std::string::npos
)
69 data
.ProcessName
= data
.ProcessPath
.substr(pos
+1);
73 data
.ProcessPath
= "??";
75 if (data
.ProcessName
.empty())
76 data
.ProcessName
= data
.ProcessPath
;
78 CloseHandle(evt
.u
.CreateProcessInfo
.hFile
);
79 data
.ProcessID
= evt
.dwProcessId
;
80 data
.ProcessHandle
= evt
.u
.CreateProcessInfo
.hProcess
;
81 data
.Threads
[evt
.dwThreadId
] = ThreadData(evt
.u
.CreateProcessInfo
.hThread
);
84 case CREATE_THREAD_DEBUG_EVENT
:
85 data
.Threads
[evt
.dwThreadId
] = ThreadData(evt
.u
.CreateThread
.hThread
);
87 case EXIT_THREAD_DEBUG_EVENT
:
89 ThreadMap::iterator it
= data
.Threads
.find(evt
.dwThreadId
);
90 if (it
!= data
.Threads
.end())
92 data
.Threads
.erase(it
);
96 case LOAD_DLL_DEBUG_EVENT
:
97 CloseHandle(evt
.u
.LoadDll
.hFile
);
98 for (size_t n
= 0; n
< data
.Modules
.size(); ++n
)
100 if (data
.Modules
[n
].BaseAddress
== evt
.u
.LoadDll
.lpBaseOfDll
)
102 data
.Modules
[n
].Unloaded
= false;
106 data
.Modules
.push_back(ModuleData(evt
.u
.LoadDll
.lpBaseOfDll
));
108 case UNLOAD_DLL_DEBUG_EVENT
:
109 for (size_t n
= 0; n
< data
.Modules
.size(); ++n
)
111 if (data
.Modules
[n
].BaseAddress
== evt
.u
.UnloadDll
.lpBaseOfDll
)
112 data
.Modules
[n
].Unloaded
= true;
115 case OUTPUT_DEBUG_STRING_EVENT
: // ignore
117 case EXCEPTION_DEBUG_EVENT
:
118 if (evt
.u
.Exception
.dwFirstChance
)
120 switch(evt
.u
.Exception
.ExceptionRecord
.ExceptionCode
)
122 case EXCEPTION_BREAKPOINT
:
123 if (!data
.FirstBPHit
)
125 data
.FirstBPHit
= true;
129 SetEvent(data
.Event
);
130 CloseHandle(data
.Event
);
136 case MS_VC_EXCEPTION_THREAD_NAME
:
140 case DBG_CONTROL_BREAK
:
144 data
.ExceptionInfo
= evt
.u
.Exception
;
145 data
.ThreadID
= evt
.dwThreadId
;
147 case EXIT_PROCESS_DEBUG_EVENT
: