-------------------------------------------------------------------------
| 69 | |
| 70 | //------------------------------------------------------------------------- |
| 71 | int Debugger::Debug( |
| 72 | const StartInfo& startInfo, |
| 73 | IDebugEventsHandler& debugEventsHandler) |
| 74 | { |
| 75 | Process process(startInfo); |
| 76 | process.Start((coverChildren_) ? DEBUG_PROCESS: DEBUG_ONLY_THIS_PROCESS); |
| 77 | |
| 78 | DEBUG_EVENT debugEvent; |
| 79 | boost::optional<int> exitCode; |
| 80 | |
| 81 | processHandles_.clear(); |
| 82 | threadHandles_.clear(); |
| 83 | rootProcessId_ = boost::none; |
| 84 | |
| 85 | while (!exitCode || !processHandles_.empty()) |
| 86 | { |
| 87 | if (!WaitForDebugEvent(&debugEvent, INFINITE)) |
| 88 | THROW_LAST_ERROR(L"Error WaitForDebugEvent:", GetLastError()); |
| 89 | |
| 90 | ProcessStatus processStatus = HandleDebugEvent(debugEvent, debugEventsHandler); |
| 91 | |
| 92 | // Get the exit code of the root process |
| 93 | // Set once as we do not want EXCEPTION_BREAKPOINT to be override |
| 94 | if (processStatus.exitCode_ && rootProcessId_ == debugEvent.dwProcessId && !exitCode) |
| 95 | exitCode = processStatus.exitCode_; |
| 96 | |
| 97 | auto continueStatus = boost::get_optional_value_or(processStatus.continueStatus_, DBG_CONTINUE); |
| 98 | |
| 99 | if (!ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, continueStatus)) |
| 100 | THROW_LAST_ERROR("Error in ContinueDebugEvent:", GetLastError()); |
| 101 | } |
| 102 | |
| 103 | return *exitCode; |
| 104 | } |
| 105 | |
| 106 | //------------------------------------------------------------------------- |
| 107 | Debugger::ProcessStatus Debugger::HandleDebugEvent( |