xref: /aosp_15_r20/external/llvm/utils/KillTheDoctor/KillTheDoctor.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- KillTheDoctor - Prevent Dr. Watson from stopping tests ---*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This program provides an extremely hacky way to stop Dr. Watson from starting
11*9880d681SAndroid Build Coastguard Worker // due to unhandled exceptions in child processes.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker // This simply starts the program named in the first positional argument with
14*9880d681SAndroid Build Coastguard Worker // the arguments following it under a debugger. All this debugger does is catch
15*9880d681SAndroid Build Coastguard Worker // any unhandled exceptions thrown in the child process and close the program
16*9880d681SAndroid Build Coastguard Worker // (and hopefully tells someone about it).
17*9880d681SAndroid Build Coastguard Worker //
18*9880d681SAndroid Build Coastguard Worker // This also provides another really hacky method to prevent assert dialog boxes
19*9880d681SAndroid Build Coastguard Worker // from popping up. When --no-user32 is passed, if any process loads user32.dll,
20*9880d681SAndroid Build Coastguard Worker // we assume it is trying to call MessageBoxEx and terminate it. The proper way
21*9880d681SAndroid Build Coastguard Worker // to do this would be to actually set a break point, but there's quite a bit
22*9880d681SAndroid Build Coastguard Worker // of code involved to get the address of MessageBoxEx in the remote process's
23*9880d681SAndroid Build Coastguard Worker // address space due to Address space layout randomization (ASLR). This can be
24*9880d681SAndroid Build Coastguard Worker // added if it's ever actually needed.
25*9880d681SAndroid Build Coastguard Worker //
26*9880d681SAndroid Build Coastguard Worker // If the subprocess exits for any reason other than successful termination, -1
27*9880d681SAndroid Build Coastguard Worker // is returned. If the process exits normally the value it returned is returned.
28*9880d681SAndroid Build Coastguard Worker //
29*9880d681SAndroid Build Coastguard Worker // I hate Windows.
30*9880d681SAndroid Build Coastguard Worker //
31*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
32*9880d681SAndroid Build Coastguard Worker 
33*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallString.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringExtras.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringRef.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Twine.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ManagedStatic.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Path.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/PrettyStackTrace.h"
43*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Signals.h"
44*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/WindowsError.h"
45*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
46*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/type_traits.h"
47*9880d681SAndroid Build Coastguard Worker #include <algorithm>
48*9880d681SAndroid Build Coastguard Worker #include <cerrno>
49*9880d681SAndroid Build Coastguard Worker #include <cstdlib>
50*9880d681SAndroid Build Coastguard Worker #include <map>
51*9880d681SAndroid Build Coastguard Worker #include <string>
52*9880d681SAndroid Build Coastguard Worker #include <system_error>
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker // These includes must be last.
55*9880d681SAndroid Build Coastguard Worker #include <Windows.h>
56*9880d681SAndroid Build Coastguard Worker #include <WinError.h>
57*9880d681SAndroid Build Coastguard Worker #include <Dbghelp.h>
58*9880d681SAndroid Build Coastguard Worker #include <psapi.h>
59*9880d681SAndroid Build Coastguard Worker 
60*9880d681SAndroid Build Coastguard Worker using namespace llvm;
61*9880d681SAndroid Build Coastguard Worker 
62*9880d681SAndroid Build Coastguard Worker #undef max
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker namespace {
65*9880d681SAndroid Build Coastguard Worker   cl::opt<std::string> ProgramToRun(cl::Positional,
66*9880d681SAndroid Build Coastguard Worker     cl::desc("<program to run>"));
67*9880d681SAndroid Build Coastguard Worker   cl::list<std::string>  Argv(cl::ConsumeAfter,
68*9880d681SAndroid Build Coastguard Worker     cl::desc("<program arguments>..."));
69*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> TraceExecution("x",
70*9880d681SAndroid Build Coastguard Worker     cl::desc("Print detailed output about what is being run to stderr."));
71*9880d681SAndroid Build Coastguard Worker   cl::opt<unsigned> Timeout("t", cl::init(0),
72*9880d681SAndroid Build Coastguard Worker     cl::desc("Set maximum runtime in seconds. Defaults to infinite."));
73*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> NoUser32("no-user32",
74*9880d681SAndroid Build Coastguard Worker     cl::desc("Terminate process if it loads user32.dll."));
75*9880d681SAndroid Build Coastguard Worker 
76*9880d681SAndroid Build Coastguard Worker   StringRef ToolName;
77*9880d681SAndroid Build Coastguard Worker 
78*9880d681SAndroid Build Coastguard Worker   template <typename HandleType>
79*9880d681SAndroid Build Coastguard Worker   class ScopedHandle {
80*9880d681SAndroid Build Coastguard Worker     typedef typename HandleType::handle_type handle_type;
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker     handle_type Handle;
83*9880d681SAndroid Build Coastguard Worker 
84*9880d681SAndroid Build Coastguard Worker   public:
ScopedHandle()85*9880d681SAndroid Build Coastguard Worker     ScopedHandle()
86*9880d681SAndroid Build Coastguard Worker       : Handle(HandleType::GetInvalidHandle()) {}
87*9880d681SAndroid Build Coastguard Worker 
ScopedHandle(handle_type handle)88*9880d681SAndroid Build Coastguard Worker     explicit ScopedHandle(handle_type handle)
89*9880d681SAndroid Build Coastguard Worker       : Handle(handle) {}
90*9880d681SAndroid Build Coastguard Worker 
~ScopedHandle()91*9880d681SAndroid Build Coastguard Worker     ~ScopedHandle() {
92*9880d681SAndroid Build Coastguard Worker       HandleType::Destruct(Handle);
93*9880d681SAndroid Build Coastguard Worker     }
94*9880d681SAndroid Build Coastguard Worker 
operator =(handle_type handle)95*9880d681SAndroid Build Coastguard Worker     ScopedHandle& operator=(handle_type handle) {
96*9880d681SAndroid Build Coastguard Worker       // Cleanup current handle.
97*9880d681SAndroid Build Coastguard Worker       if (!HandleType::isValid(Handle))
98*9880d681SAndroid Build Coastguard Worker         HandleType::Destruct(Handle);
99*9880d681SAndroid Build Coastguard Worker       Handle = handle;
100*9880d681SAndroid Build Coastguard Worker       return *this;
101*9880d681SAndroid Build Coastguard Worker     }
102*9880d681SAndroid Build Coastguard Worker 
operator bool() const103*9880d681SAndroid Build Coastguard Worker     operator bool() const {
104*9880d681SAndroid Build Coastguard Worker       return HandleType::isValid(Handle);
105*9880d681SAndroid Build Coastguard Worker     }
106*9880d681SAndroid Build Coastguard Worker 
operator handle_type()107*9880d681SAndroid Build Coastguard Worker     operator handle_type() {
108*9880d681SAndroid Build Coastguard Worker       return Handle;
109*9880d681SAndroid Build Coastguard Worker     }
110*9880d681SAndroid Build Coastguard Worker   };
111*9880d681SAndroid Build Coastguard Worker 
112*9880d681SAndroid Build Coastguard Worker   // This implements the most common handle in the Windows API.
113*9880d681SAndroid Build Coastguard Worker   struct CommonHandle {
114*9880d681SAndroid Build Coastguard Worker     typedef HANDLE handle_type;
115*9880d681SAndroid Build Coastguard Worker 
GetInvalidHandle__anon88ebdf810111::CommonHandle116*9880d681SAndroid Build Coastguard Worker     static handle_type GetInvalidHandle() {
117*9880d681SAndroid Build Coastguard Worker       return INVALID_HANDLE_VALUE;
118*9880d681SAndroid Build Coastguard Worker     }
119*9880d681SAndroid Build Coastguard Worker 
Destruct__anon88ebdf810111::CommonHandle120*9880d681SAndroid Build Coastguard Worker     static void Destruct(handle_type Handle) {
121*9880d681SAndroid Build Coastguard Worker       ::CloseHandle(Handle);
122*9880d681SAndroid Build Coastguard Worker     }
123*9880d681SAndroid Build Coastguard Worker 
isValid__anon88ebdf810111::CommonHandle124*9880d681SAndroid Build Coastguard Worker     static bool isValid(handle_type Handle) {
125*9880d681SAndroid Build Coastguard Worker       return Handle != GetInvalidHandle();
126*9880d681SAndroid Build Coastguard Worker     }
127*9880d681SAndroid Build Coastguard Worker   };
128*9880d681SAndroid Build Coastguard Worker 
129*9880d681SAndroid Build Coastguard Worker   struct FileMappingHandle {
130*9880d681SAndroid Build Coastguard Worker     typedef HANDLE handle_type;
131*9880d681SAndroid Build Coastguard Worker 
GetInvalidHandle__anon88ebdf810111::FileMappingHandle132*9880d681SAndroid Build Coastguard Worker     static handle_type GetInvalidHandle() {
133*9880d681SAndroid Build Coastguard Worker       return NULL;
134*9880d681SAndroid Build Coastguard Worker     }
135*9880d681SAndroid Build Coastguard Worker 
Destruct__anon88ebdf810111::FileMappingHandle136*9880d681SAndroid Build Coastguard Worker     static void Destruct(handle_type Handle) {
137*9880d681SAndroid Build Coastguard Worker       ::CloseHandle(Handle);
138*9880d681SAndroid Build Coastguard Worker     }
139*9880d681SAndroid Build Coastguard Worker 
isValid__anon88ebdf810111::FileMappingHandle140*9880d681SAndroid Build Coastguard Worker     static bool isValid(handle_type Handle) {
141*9880d681SAndroid Build Coastguard Worker       return Handle != GetInvalidHandle();
142*9880d681SAndroid Build Coastguard Worker     }
143*9880d681SAndroid Build Coastguard Worker   };
144*9880d681SAndroid Build Coastguard Worker 
145*9880d681SAndroid Build Coastguard Worker   struct MappedViewOfFileHandle {
146*9880d681SAndroid Build Coastguard Worker     typedef LPVOID handle_type;
147*9880d681SAndroid Build Coastguard Worker 
GetInvalidHandle__anon88ebdf810111::MappedViewOfFileHandle148*9880d681SAndroid Build Coastguard Worker     static handle_type GetInvalidHandle() {
149*9880d681SAndroid Build Coastguard Worker       return NULL;
150*9880d681SAndroid Build Coastguard Worker     }
151*9880d681SAndroid Build Coastguard Worker 
Destruct__anon88ebdf810111::MappedViewOfFileHandle152*9880d681SAndroid Build Coastguard Worker     static void Destruct(handle_type Handle) {
153*9880d681SAndroid Build Coastguard Worker       ::UnmapViewOfFile(Handle);
154*9880d681SAndroid Build Coastguard Worker     }
155*9880d681SAndroid Build Coastguard Worker 
isValid__anon88ebdf810111::MappedViewOfFileHandle156*9880d681SAndroid Build Coastguard Worker     static bool isValid(handle_type Handle) {
157*9880d681SAndroid Build Coastguard Worker       return Handle != GetInvalidHandle();
158*9880d681SAndroid Build Coastguard Worker     }
159*9880d681SAndroid Build Coastguard Worker   };
160*9880d681SAndroid Build Coastguard Worker 
161*9880d681SAndroid Build Coastguard Worker   struct ProcessHandle : CommonHandle {};
162*9880d681SAndroid Build Coastguard Worker   struct ThreadHandle  : CommonHandle {};
163*9880d681SAndroid Build Coastguard Worker   struct TokenHandle   : CommonHandle {};
164*9880d681SAndroid Build Coastguard Worker   struct FileHandle    : CommonHandle {};
165*9880d681SAndroid Build Coastguard Worker 
166*9880d681SAndroid Build Coastguard Worker   typedef ScopedHandle<FileMappingHandle>       FileMappingScopedHandle;
167*9880d681SAndroid Build Coastguard Worker   typedef ScopedHandle<MappedViewOfFileHandle>  MappedViewOfFileScopedHandle;
168*9880d681SAndroid Build Coastguard Worker   typedef ScopedHandle<ProcessHandle>           ProcessScopedHandle;
169*9880d681SAndroid Build Coastguard Worker   typedef ScopedHandle<ThreadHandle>            ThreadScopedHandle;
170*9880d681SAndroid Build Coastguard Worker   typedef ScopedHandle<TokenHandle>             TokenScopedHandle;
171*9880d681SAndroid Build Coastguard Worker   typedef ScopedHandle<FileHandle>              FileScopedHandle;
172*9880d681SAndroid Build Coastguard Worker }
173*9880d681SAndroid Build Coastguard Worker 
windows_error(DWORD E)174*9880d681SAndroid Build Coastguard Worker static std::error_code windows_error(DWORD E) { return mapWindowsError(E); }
175*9880d681SAndroid Build Coastguard Worker 
GetFileNameFromHandle(HANDLE FileHandle,std::string & Name)176*9880d681SAndroid Build Coastguard Worker static std::error_code GetFileNameFromHandle(HANDLE FileHandle,
177*9880d681SAndroid Build Coastguard Worker                                              std::string &Name) {
178*9880d681SAndroid Build Coastguard Worker   char Filename[MAX_PATH+1];
179*9880d681SAndroid Build Coastguard Worker   bool Success = false;
180*9880d681SAndroid Build Coastguard Worker   Name.clear();
181*9880d681SAndroid Build Coastguard Worker 
182*9880d681SAndroid Build Coastguard Worker   // Get the file size.
183*9880d681SAndroid Build Coastguard Worker   LARGE_INTEGER FileSize;
184*9880d681SAndroid Build Coastguard Worker   Success = ::GetFileSizeEx(FileHandle, &FileSize);
185*9880d681SAndroid Build Coastguard Worker 
186*9880d681SAndroid Build Coastguard Worker   if (!Success)
187*9880d681SAndroid Build Coastguard Worker     return windows_error(::GetLastError());
188*9880d681SAndroid Build Coastguard Worker 
189*9880d681SAndroid Build Coastguard Worker   // Create a file mapping object.
190*9880d681SAndroid Build Coastguard Worker   FileMappingScopedHandle FileMapping(
191*9880d681SAndroid Build Coastguard Worker     ::CreateFileMappingA(FileHandle,
192*9880d681SAndroid Build Coastguard Worker                          NULL,
193*9880d681SAndroid Build Coastguard Worker                          PAGE_READONLY,
194*9880d681SAndroid Build Coastguard Worker                          0,
195*9880d681SAndroid Build Coastguard Worker                          1,
196*9880d681SAndroid Build Coastguard Worker                          NULL));
197*9880d681SAndroid Build Coastguard Worker 
198*9880d681SAndroid Build Coastguard Worker   if (!FileMapping)
199*9880d681SAndroid Build Coastguard Worker     return windows_error(::GetLastError());
200*9880d681SAndroid Build Coastguard Worker 
201*9880d681SAndroid Build Coastguard Worker   // Create a file mapping to get the file name.
202*9880d681SAndroid Build Coastguard Worker   MappedViewOfFileScopedHandle MappedFile(
203*9880d681SAndroid Build Coastguard Worker     ::MapViewOfFile(FileMapping, FILE_MAP_READ, 0, 0, 1));
204*9880d681SAndroid Build Coastguard Worker 
205*9880d681SAndroid Build Coastguard Worker   if (!MappedFile)
206*9880d681SAndroid Build Coastguard Worker     return windows_error(::GetLastError());
207*9880d681SAndroid Build Coastguard Worker 
208*9880d681SAndroid Build Coastguard Worker   Success = ::GetMappedFileNameA(::GetCurrentProcess(),
209*9880d681SAndroid Build Coastguard Worker                                 MappedFile,
210*9880d681SAndroid Build Coastguard Worker                                 Filename,
211*9880d681SAndroid Build Coastguard Worker                                 array_lengthof(Filename) - 1);
212*9880d681SAndroid Build Coastguard Worker 
213*9880d681SAndroid Build Coastguard Worker   if (!Success)
214*9880d681SAndroid Build Coastguard Worker     return windows_error(::GetLastError());
215*9880d681SAndroid Build Coastguard Worker   else {
216*9880d681SAndroid Build Coastguard Worker     Name = Filename;
217*9880d681SAndroid Build Coastguard Worker     return std::error_code();
218*9880d681SAndroid Build Coastguard Worker   }
219*9880d681SAndroid Build Coastguard Worker }
220*9880d681SAndroid Build Coastguard Worker 
221*9880d681SAndroid Build Coastguard Worker /// @brief Find program using shell lookup rules.
222*9880d681SAndroid Build Coastguard Worker /// @param Program This is either an absolute path, relative path, or simple a
223*9880d681SAndroid Build Coastguard Worker ///        program name. Look in PATH for any programs that match. If no
224*9880d681SAndroid Build Coastguard Worker ///        extension is present, try all extensions in PATHEXT.
225*9880d681SAndroid Build Coastguard Worker /// @return If ec == errc::success, The absolute path to the program. Otherwise
226*9880d681SAndroid Build Coastguard Worker ///         the return value is undefined.
FindProgram(const std::string & Program,std::error_code & ec)227*9880d681SAndroid Build Coastguard Worker static std::string FindProgram(const std::string &Program,
228*9880d681SAndroid Build Coastguard Worker                                std::error_code &ec) {
229*9880d681SAndroid Build Coastguard Worker   char PathName[MAX_PATH + 1];
230*9880d681SAndroid Build Coastguard Worker   typedef SmallVector<StringRef, 12> pathext_t;
231*9880d681SAndroid Build Coastguard Worker   pathext_t pathext;
232*9880d681SAndroid Build Coastguard Worker   // Check for the program without an extension (in case it already has one).
233*9880d681SAndroid Build Coastguard Worker   pathext.push_back("");
234*9880d681SAndroid Build Coastguard Worker   SplitString(std::getenv("PATHEXT"), pathext, ";");
235*9880d681SAndroid Build Coastguard Worker 
236*9880d681SAndroid Build Coastguard Worker   for (pathext_t::iterator i = pathext.begin(), e = pathext.end(); i != e; ++i){
237*9880d681SAndroid Build Coastguard Worker     SmallString<5> ext;
238*9880d681SAndroid Build Coastguard Worker     for (std::size_t ii = 0, e = i->size(); ii != e; ++ii)
239*9880d681SAndroid Build Coastguard Worker       ext.push_back(::tolower((*i)[ii]));
240*9880d681SAndroid Build Coastguard Worker     LPCSTR Extension = NULL;
241*9880d681SAndroid Build Coastguard Worker     if (ext.size() && ext[0] == '.')
242*9880d681SAndroid Build Coastguard Worker       Extension = ext.c_str();
243*9880d681SAndroid Build Coastguard Worker     DWORD length = ::SearchPathA(NULL,
244*9880d681SAndroid Build Coastguard Worker                                  Program.c_str(),
245*9880d681SAndroid Build Coastguard Worker                                  Extension,
246*9880d681SAndroid Build Coastguard Worker                                  array_lengthof(PathName),
247*9880d681SAndroid Build Coastguard Worker                                  PathName,
248*9880d681SAndroid Build Coastguard Worker                                  NULL);
249*9880d681SAndroid Build Coastguard Worker     if (length == 0)
250*9880d681SAndroid Build Coastguard Worker       ec = windows_error(::GetLastError());
251*9880d681SAndroid Build Coastguard Worker     else if (length > array_lengthof(PathName)) {
252*9880d681SAndroid Build Coastguard Worker       // This may have been the file, return with error.
253*9880d681SAndroid Build Coastguard Worker       ec = windows_error(ERROR_BUFFER_OVERFLOW);
254*9880d681SAndroid Build Coastguard Worker       break;
255*9880d681SAndroid Build Coastguard Worker     } else {
256*9880d681SAndroid Build Coastguard Worker       // We found the path! Return it.
257*9880d681SAndroid Build Coastguard Worker       ec = std::error_code();
258*9880d681SAndroid Build Coastguard Worker       break;
259*9880d681SAndroid Build Coastguard Worker     }
260*9880d681SAndroid Build Coastguard Worker   }
261*9880d681SAndroid Build Coastguard Worker 
262*9880d681SAndroid Build Coastguard Worker   // Make sure PathName is valid.
263*9880d681SAndroid Build Coastguard Worker   PathName[MAX_PATH] = 0;
264*9880d681SAndroid Build Coastguard Worker   return PathName;
265*9880d681SAndroid Build Coastguard Worker }
266*9880d681SAndroid Build Coastguard Worker 
ExceptionCodeToString(DWORD ExceptionCode)267*9880d681SAndroid Build Coastguard Worker static StringRef ExceptionCodeToString(DWORD ExceptionCode) {
268*9880d681SAndroid Build Coastguard Worker   switch(ExceptionCode) {
269*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_ACCESS_VIOLATION: return "EXCEPTION_ACCESS_VIOLATION";
270*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
271*9880d681SAndroid Build Coastguard Worker     return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
272*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_BREAKPOINT: return "EXCEPTION_BREAKPOINT";
273*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_DATATYPE_MISALIGNMENT:
274*9880d681SAndroid Build Coastguard Worker     return "EXCEPTION_DATATYPE_MISALIGNMENT";
275*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_FLT_DENORMAL_OPERAND: return "EXCEPTION_FLT_DENORMAL_OPERAND";
276*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "EXCEPTION_FLT_DIVIDE_BY_ZERO";
277*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_FLT_INEXACT_RESULT: return "EXCEPTION_FLT_INEXACT_RESULT";
278*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_FLT_INVALID_OPERATION:
279*9880d681SAndroid Build Coastguard Worker     return "EXCEPTION_FLT_INVALID_OPERATION";
280*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_FLT_OVERFLOW: return "EXCEPTION_FLT_OVERFLOW";
281*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_FLT_STACK_CHECK: return "EXCEPTION_FLT_STACK_CHECK";
282*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_FLT_UNDERFLOW: return "EXCEPTION_FLT_UNDERFLOW";
283*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_ILLEGAL_INSTRUCTION: return "EXCEPTION_ILLEGAL_INSTRUCTION";
284*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_IN_PAGE_ERROR: return "EXCEPTION_IN_PAGE_ERROR";
285*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_INT_DIVIDE_BY_ZERO: return "EXCEPTION_INT_DIVIDE_BY_ZERO";
286*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_INT_OVERFLOW: return "EXCEPTION_INT_OVERFLOW";
287*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_INVALID_DISPOSITION: return "EXCEPTION_INVALID_DISPOSITION";
288*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_NONCONTINUABLE_EXCEPTION:
289*9880d681SAndroid Build Coastguard Worker     return "EXCEPTION_NONCONTINUABLE_EXCEPTION";
290*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_PRIV_INSTRUCTION: return "EXCEPTION_PRIV_INSTRUCTION";
291*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_SINGLE_STEP: return "EXCEPTION_SINGLE_STEP";
292*9880d681SAndroid Build Coastguard Worker   case EXCEPTION_STACK_OVERFLOW: return "EXCEPTION_STACK_OVERFLOW";
293*9880d681SAndroid Build Coastguard Worker   default: return "<unknown>";
294*9880d681SAndroid Build Coastguard Worker   }
295*9880d681SAndroid Build Coastguard Worker }
296*9880d681SAndroid Build Coastguard Worker 
main(int argc,char ** argv)297*9880d681SAndroid Build Coastguard Worker int main(int argc, char **argv) {
298*9880d681SAndroid Build Coastguard Worker   // Print a stack trace if we signal out.
299*9880d681SAndroid Build Coastguard Worker   sys::PrintStackTraceOnErrorSignal(argv[0]);
300*9880d681SAndroid Build Coastguard Worker   PrettyStackTraceProgram X(argc, argv);
301*9880d681SAndroid Build Coastguard Worker   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
302*9880d681SAndroid Build Coastguard Worker 
303*9880d681SAndroid Build Coastguard Worker   ToolName = argv[0];
304*9880d681SAndroid Build Coastguard Worker 
305*9880d681SAndroid Build Coastguard Worker   cl::ParseCommandLineOptions(argc, argv, "Dr. Watson Assassin.\n");
306*9880d681SAndroid Build Coastguard Worker   if (ProgramToRun.size() == 0) {
307*9880d681SAndroid Build Coastguard Worker     cl::PrintHelpMessage();
308*9880d681SAndroid Build Coastguard Worker     return -1;
309*9880d681SAndroid Build Coastguard Worker   }
310*9880d681SAndroid Build Coastguard Worker 
311*9880d681SAndroid Build Coastguard Worker   if (Timeout > std::numeric_limits<uint32_t>::max() / 1000) {
312*9880d681SAndroid Build Coastguard Worker     errs() << ToolName << ": Timeout value too large, must be less than: "
313*9880d681SAndroid Build Coastguard Worker                        << std::numeric_limits<uint32_t>::max() / 1000
314*9880d681SAndroid Build Coastguard Worker                        << '\n';
315*9880d681SAndroid Build Coastguard Worker     return -1;
316*9880d681SAndroid Build Coastguard Worker   }
317*9880d681SAndroid Build Coastguard Worker 
318*9880d681SAndroid Build Coastguard Worker   std::string CommandLine(ProgramToRun);
319*9880d681SAndroid Build Coastguard Worker 
320*9880d681SAndroid Build Coastguard Worker   std::error_code ec;
321*9880d681SAndroid Build Coastguard Worker   ProgramToRun = FindProgram(ProgramToRun, ec);
322*9880d681SAndroid Build Coastguard Worker   if (ec) {
323*9880d681SAndroid Build Coastguard Worker     errs() << ToolName << ": Failed to find program: '" << CommandLine
324*9880d681SAndroid Build Coastguard Worker            << "': " << ec.message() << '\n';
325*9880d681SAndroid Build Coastguard Worker     return -1;
326*9880d681SAndroid Build Coastguard Worker   }
327*9880d681SAndroid Build Coastguard Worker 
328*9880d681SAndroid Build Coastguard Worker   if (TraceExecution)
329*9880d681SAndroid Build Coastguard Worker     errs() << ToolName << ": Found Program: " << ProgramToRun << '\n';
330*9880d681SAndroid Build Coastguard Worker 
331*9880d681SAndroid Build Coastguard Worker   for (const std::string &Arg : Argv) {
332*9880d681SAndroid Build Coastguard Worker     CommandLine.push_back(' ');
333*9880d681SAndroid Build Coastguard Worker     CommandLine.append(Arg);
334*9880d681SAndroid Build Coastguard Worker   }
335*9880d681SAndroid Build Coastguard Worker 
336*9880d681SAndroid Build Coastguard Worker   if (TraceExecution)
337*9880d681SAndroid Build Coastguard Worker     errs() << ToolName << ": Program Image Path: " << ProgramToRun << '\n'
338*9880d681SAndroid Build Coastguard Worker            << ToolName << ": Command Line: " << CommandLine << '\n';
339*9880d681SAndroid Build Coastguard Worker 
340*9880d681SAndroid Build Coastguard Worker   STARTUPINFOA StartupInfo;
341*9880d681SAndroid Build Coastguard Worker   PROCESS_INFORMATION ProcessInfo;
342*9880d681SAndroid Build Coastguard Worker   std::memset(&StartupInfo, 0, sizeof(StartupInfo));
343*9880d681SAndroid Build Coastguard Worker   StartupInfo.cb = sizeof(StartupInfo);
344*9880d681SAndroid Build Coastguard Worker   std::memset(&ProcessInfo, 0, sizeof(ProcessInfo));
345*9880d681SAndroid Build Coastguard Worker 
346*9880d681SAndroid Build Coastguard Worker   // Set error mode to not display any message boxes. The child process inherits
347*9880d681SAndroid Build Coastguard Worker   // this.
348*9880d681SAndroid Build Coastguard Worker   ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
349*9880d681SAndroid Build Coastguard Worker   ::_set_error_mode(_OUT_TO_STDERR);
350*9880d681SAndroid Build Coastguard Worker 
351*9880d681SAndroid Build Coastguard Worker   BOOL success = ::CreateProcessA(ProgramToRun.c_str(),
352*9880d681SAndroid Build Coastguard Worker                             LPSTR(CommandLine.c_str()),
353*9880d681SAndroid Build Coastguard Worker                                   NULL,
354*9880d681SAndroid Build Coastguard Worker                                   NULL,
355*9880d681SAndroid Build Coastguard Worker                                   FALSE,
356*9880d681SAndroid Build Coastguard Worker                                   DEBUG_PROCESS,
357*9880d681SAndroid Build Coastguard Worker                                   NULL,
358*9880d681SAndroid Build Coastguard Worker                                   NULL,
359*9880d681SAndroid Build Coastguard Worker                                   &StartupInfo,
360*9880d681SAndroid Build Coastguard Worker                                   &ProcessInfo);
361*9880d681SAndroid Build Coastguard Worker   if (!success) {
362*9880d681SAndroid Build Coastguard Worker     errs() << ToolName << ": Failed to run program: '" << ProgramToRun << "': "
363*9880d681SAndroid Build Coastguard Worker            << std::error_code(windows_error(::GetLastError())).message()
364*9880d681SAndroid Build Coastguard Worker            << '\n';
365*9880d681SAndroid Build Coastguard Worker     return -1;
366*9880d681SAndroid Build Coastguard Worker   }
367*9880d681SAndroid Build Coastguard Worker 
368*9880d681SAndroid Build Coastguard Worker   // Make sure ::CloseHandle is called on exit.
369*9880d681SAndroid Build Coastguard Worker   std::map<DWORD, HANDLE> ProcessIDToHandle;
370*9880d681SAndroid Build Coastguard Worker 
371*9880d681SAndroid Build Coastguard Worker   DEBUG_EVENT DebugEvent;
372*9880d681SAndroid Build Coastguard Worker   std::memset(&DebugEvent, 0, sizeof(DebugEvent));
373*9880d681SAndroid Build Coastguard Worker   DWORD dwContinueStatus = DBG_CONTINUE;
374*9880d681SAndroid Build Coastguard Worker 
375*9880d681SAndroid Build Coastguard Worker   // Run the program under the debugger until either it exits, or throws an
376*9880d681SAndroid Build Coastguard Worker   // exception.
377*9880d681SAndroid Build Coastguard Worker   if (TraceExecution)
378*9880d681SAndroid Build Coastguard Worker     errs() << ToolName << ": Debugging...\n";
379*9880d681SAndroid Build Coastguard Worker 
380*9880d681SAndroid Build Coastguard Worker   while(true) {
381*9880d681SAndroid Build Coastguard Worker     DWORD TimeLeft = INFINITE;
382*9880d681SAndroid Build Coastguard Worker     if (Timeout > 0) {
383*9880d681SAndroid Build Coastguard Worker       FILETIME CreationTime, ExitTime, KernelTime, UserTime;
384*9880d681SAndroid Build Coastguard Worker       ULARGE_INTEGER a, b;
385*9880d681SAndroid Build Coastguard Worker       success = ::GetProcessTimes(ProcessInfo.hProcess,
386*9880d681SAndroid Build Coastguard Worker                                   &CreationTime,
387*9880d681SAndroid Build Coastguard Worker                                   &ExitTime,
388*9880d681SAndroid Build Coastguard Worker                                   &KernelTime,
389*9880d681SAndroid Build Coastguard Worker                                   &UserTime);
390*9880d681SAndroid Build Coastguard Worker       if (!success) {
391*9880d681SAndroid Build Coastguard Worker         ec = windows_error(::GetLastError());
392*9880d681SAndroid Build Coastguard Worker 
393*9880d681SAndroid Build Coastguard Worker         errs() << ToolName << ": Failed to get process times: "
394*9880d681SAndroid Build Coastguard Worker                << ec.message() << '\n';
395*9880d681SAndroid Build Coastguard Worker         return -1;
396*9880d681SAndroid Build Coastguard Worker       }
397*9880d681SAndroid Build Coastguard Worker       a.LowPart = KernelTime.dwLowDateTime;
398*9880d681SAndroid Build Coastguard Worker       a.HighPart = KernelTime.dwHighDateTime;
399*9880d681SAndroid Build Coastguard Worker       b.LowPart = UserTime.dwLowDateTime;
400*9880d681SAndroid Build Coastguard Worker       b.HighPart = UserTime.dwHighDateTime;
401*9880d681SAndroid Build Coastguard Worker       // Convert 100-nanosecond units to milliseconds.
402*9880d681SAndroid Build Coastguard Worker       uint64_t TotalTimeMiliseconds = (a.QuadPart + b.QuadPart) / 10000;
403*9880d681SAndroid Build Coastguard Worker       // Handle the case where the process has been running for more than 49
404*9880d681SAndroid Build Coastguard Worker       // days.
405*9880d681SAndroid Build Coastguard Worker       if (TotalTimeMiliseconds > std::numeric_limits<uint32_t>::max()) {
406*9880d681SAndroid Build Coastguard Worker         errs() << ToolName << ": Timeout Failed: Process has been running for"
407*9880d681SAndroid Build Coastguard Worker                               "more than 49 days.\n";
408*9880d681SAndroid Build Coastguard Worker         return -1;
409*9880d681SAndroid Build Coastguard Worker       }
410*9880d681SAndroid Build Coastguard Worker 
411*9880d681SAndroid Build Coastguard Worker       // We check with > instead of using Timeleft because if
412*9880d681SAndroid Build Coastguard Worker       // TotalTimeMiliseconds is greater than Timeout * 1000, TimeLeft would
413*9880d681SAndroid Build Coastguard Worker       // underflow.
414*9880d681SAndroid Build Coastguard Worker       if (TotalTimeMiliseconds > (Timeout * 1000)) {
415*9880d681SAndroid Build Coastguard Worker         errs() << ToolName << ": Process timed out.\n";
416*9880d681SAndroid Build Coastguard Worker         ::TerminateProcess(ProcessInfo.hProcess, -1);
417*9880d681SAndroid Build Coastguard Worker         // Otherwise other stuff starts failing...
418*9880d681SAndroid Build Coastguard Worker         return -1;
419*9880d681SAndroid Build Coastguard Worker       }
420*9880d681SAndroid Build Coastguard Worker 
421*9880d681SAndroid Build Coastguard Worker       TimeLeft = (Timeout * 1000) - static_cast<uint32_t>(TotalTimeMiliseconds);
422*9880d681SAndroid Build Coastguard Worker     }
423*9880d681SAndroid Build Coastguard Worker     success = WaitForDebugEvent(&DebugEvent, TimeLeft);
424*9880d681SAndroid Build Coastguard Worker 
425*9880d681SAndroid Build Coastguard Worker     if (!success) {
426*9880d681SAndroid Build Coastguard Worker       DWORD LastError = ::GetLastError();
427*9880d681SAndroid Build Coastguard Worker       ec = windows_error(LastError);
428*9880d681SAndroid Build Coastguard Worker 
429*9880d681SAndroid Build Coastguard Worker       if (LastError == ERROR_SEM_TIMEOUT || LastError == WSAETIMEDOUT) {
430*9880d681SAndroid Build Coastguard Worker         errs() << ToolName << ": Process timed out.\n";
431*9880d681SAndroid Build Coastguard Worker         ::TerminateProcess(ProcessInfo.hProcess, -1);
432*9880d681SAndroid Build Coastguard Worker         // Otherwise other stuff starts failing...
433*9880d681SAndroid Build Coastguard Worker         return -1;
434*9880d681SAndroid Build Coastguard Worker       }
435*9880d681SAndroid Build Coastguard Worker 
436*9880d681SAndroid Build Coastguard Worker       errs() << ToolName << ": Failed to wait for debug event in program: '"
437*9880d681SAndroid Build Coastguard Worker              << ProgramToRun << "': " << ec.message() << '\n';
438*9880d681SAndroid Build Coastguard Worker       return -1;
439*9880d681SAndroid Build Coastguard Worker     }
440*9880d681SAndroid Build Coastguard Worker 
441*9880d681SAndroid Build Coastguard Worker     switch(DebugEvent.dwDebugEventCode) {
442*9880d681SAndroid Build Coastguard Worker     case CREATE_PROCESS_DEBUG_EVENT:
443*9880d681SAndroid Build Coastguard Worker       // Make sure we remove the handle on exit.
444*9880d681SAndroid Build Coastguard Worker       if (TraceExecution)
445*9880d681SAndroid Build Coastguard Worker         errs() << ToolName << ": Debug Event: CREATE_PROCESS_DEBUG_EVENT\n";
446*9880d681SAndroid Build Coastguard Worker       ProcessIDToHandle[DebugEvent.dwProcessId] =
447*9880d681SAndroid Build Coastguard Worker         DebugEvent.u.CreateProcessInfo.hProcess;
448*9880d681SAndroid Build Coastguard Worker       ::CloseHandle(DebugEvent.u.CreateProcessInfo.hFile);
449*9880d681SAndroid Build Coastguard Worker       break;
450*9880d681SAndroid Build Coastguard Worker     case EXIT_PROCESS_DEBUG_EVENT: {
451*9880d681SAndroid Build Coastguard Worker         if (TraceExecution)
452*9880d681SAndroid Build Coastguard Worker           errs() << ToolName << ": Debug Event: EXIT_PROCESS_DEBUG_EVENT\n";
453*9880d681SAndroid Build Coastguard Worker 
454*9880d681SAndroid Build Coastguard Worker         // If this is the process we originally created, exit with its exit
455*9880d681SAndroid Build Coastguard Worker         // code.
456*9880d681SAndroid Build Coastguard Worker         if (DebugEvent.dwProcessId == ProcessInfo.dwProcessId)
457*9880d681SAndroid Build Coastguard Worker           return DebugEvent.u.ExitProcess.dwExitCode;
458*9880d681SAndroid Build Coastguard Worker 
459*9880d681SAndroid Build Coastguard Worker         // Otherwise cleanup any resources we have for it.
460*9880d681SAndroid Build Coastguard Worker         std::map<DWORD, HANDLE>::iterator ExitingProcess =
461*9880d681SAndroid Build Coastguard Worker           ProcessIDToHandle.find(DebugEvent.dwProcessId);
462*9880d681SAndroid Build Coastguard Worker         if (ExitingProcess == ProcessIDToHandle.end()) {
463*9880d681SAndroid Build Coastguard Worker           errs() << ToolName << ": Got unknown process id!\n";
464*9880d681SAndroid Build Coastguard Worker           return -1;
465*9880d681SAndroid Build Coastguard Worker         }
466*9880d681SAndroid Build Coastguard Worker         ::CloseHandle(ExitingProcess->second);
467*9880d681SAndroid Build Coastguard Worker         ProcessIDToHandle.erase(ExitingProcess);
468*9880d681SAndroid Build Coastguard Worker       }
469*9880d681SAndroid Build Coastguard Worker       break;
470*9880d681SAndroid Build Coastguard Worker     case CREATE_THREAD_DEBUG_EVENT:
471*9880d681SAndroid Build Coastguard Worker       ::CloseHandle(DebugEvent.u.CreateThread.hThread);
472*9880d681SAndroid Build Coastguard Worker       break;
473*9880d681SAndroid Build Coastguard Worker     case LOAD_DLL_DEBUG_EVENT: {
474*9880d681SAndroid Build Coastguard Worker         // Cleanup the file handle.
475*9880d681SAndroid Build Coastguard Worker         FileScopedHandle DLLFile(DebugEvent.u.LoadDll.hFile);
476*9880d681SAndroid Build Coastguard Worker         std::string DLLName;
477*9880d681SAndroid Build Coastguard Worker         ec = GetFileNameFromHandle(DLLFile, DLLName);
478*9880d681SAndroid Build Coastguard Worker         if (ec) {
479*9880d681SAndroid Build Coastguard Worker           DLLName = "<failed to get file name from file handle> : ";
480*9880d681SAndroid Build Coastguard Worker           DLLName += ec.message();
481*9880d681SAndroid Build Coastguard Worker         }
482*9880d681SAndroid Build Coastguard Worker         if (TraceExecution) {
483*9880d681SAndroid Build Coastguard Worker           errs() << ToolName << ": Debug Event: LOAD_DLL_DEBUG_EVENT\n";
484*9880d681SAndroid Build Coastguard Worker           errs().indent(ToolName.size()) << ": DLL Name : " << DLLName << '\n';
485*9880d681SAndroid Build Coastguard Worker         }
486*9880d681SAndroid Build Coastguard Worker 
487*9880d681SAndroid Build Coastguard Worker         if (NoUser32 && sys::path::stem(DLLName) == "user32") {
488*9880d681SAndroid Build Coastguard Worker           // Program is loading user32.dll, in the applications we are testing,
489*9880d681SAndroid Build Coastguard Worker           // this only happens if an assert has fired. By now the message has
490*9880d681SAndroid Build Coastguard Worker           // already been printed, so simply close the program.
491*9880d681SAndroid Build Coastguard Worker           errs() << ToolName << ": user32.dll loaded!\n";
492*9880d681SAndroid Build Coastguard Worker           errs().indent(ToolName.size())
493*9880d681SAndroid Build Coastguard Worker                  << ": This probably means that assert was called. Closing "
494*9880d681SAndroid Build Coastguard Worker                     "program to prevent message box from popping up.\n";
495*9880d681SAndroid Build Coastguard Worker           dwContinueStatus = DBG_CONTINUE;
496*9880d681SAndroid Build Coastguard Worker           ::TerminateProcess(ProcessIDToHandle[DebugEvent.dwProcessId], -1);
497*9880d681SAndroid Build Coastguard Worker           return -1;
498*9880d681SAndroid Build Coastguard Worker         }
499*9880d681SAndroid Build Coastguard Worker       }
500*9880d681SAndroid Build Coastguard Worker       break;
501*9880d681SAndroid Build Coastguard Worker     case EXCEPTION_DEBUG_EVENT: {
502*9880d681SAndroid Build Coastguard Worker         // Close the application if this exception will not be handled by the
503*9880d681SAndroid Build Coastguard Worker         // child application.
504*9880d681SAndroid Build Coastguard Worker         if (TraceExecution)
505*9880d681SAndroid Build Coastguard Worker           errs() << ToolName << ": Debug Event: EXCEPTION_DEBUG_EVENT\n";
506*9880d681SAndroid Build Coastguard Worker 
507*9880d681SAndroid Build Coastguard Worker         EXCEPTION_DEBUG_INFO  &Exception = DebugEvent.u.Exception;
508*9880d681SAndroid Build Coastguard Worker         if (Exception.dwFirstChance > 0) {
509*9880d681SAndroid Build Coastguard Worker           if (TraceExecution) {
510*9880d681SAndroid Build Coastguard Worker             errs().indent(ToolName.size()) << ": Debug Info : ";
511*9880d681SAndroid Build Coastguard Worker             errs() << "First chance exception at "
512*9880d681SAndroid Build Coastguard Worker                    << Exception.ExceptionRecord.ExceptionAddress
513*9880d681SAndroid Build Coastguard Worker                    << ", exception code: "
514*9880d681SAndroid Build Coastguard Worker                    << ExceptionCodeToString(
515*9880d681SAndroid Build Coastguard Worker                         Exception.ExceptionRecord.ExceptionCode)
516*9880d681SAndroid Build Coastguard Worker                    << " (" << Exception.ExceptionRecord.ExceptionCode << ")\n";
517*9880d681SAndroid Build Coastguard Worker           }
518*9880d681SAndroid Build Coastguard Worker           dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
519*9880d681SAndroid Build Coastguard Worker         } else {
520*9880d681SAndroid Build Coastguard Worker           errs() << ToolName << ": Unhandled exception in: " << ProgramToRun
521*9880d681SAndroid Build Coastguard Worker                  << "!\n";
522*9880d681SAndroid Build Coastguard Worker                  errs().indent(ToolName.size()) << ": location: ";
523*9880d681SAndroid Build Coastguard Worker                  errs() << Exception.ExceptionRecord.ExceptionAddress
524*9880d681SAndroid Build Coastguard Worker                         << ", exception code: "
525*9880d681SAndroid Build Coastguard Worker                         << ExceptionCodeToString(
526*9880d681SAndroid Build Coastguard Worker                             Exception.ExceptionRecord.ExceptionCode)
527*9880d681SAndroid Build Coastguard Worker                         << " (" << Exception.ExceptionRecord.ExceptionCode
528*9880d681SAndroid Build Coastguard Worker                         << ")\n";
529*9880d681SAndroid Build Coastguard Worker           dwContinueStatus = DBG_CONTINUE;
530*9880d681SAndroid Build Coastguard Worker           ::TerminateProcess(ProcessIDToHandle[DebugEvent.dwProcessId], -1);
531*9880d681SAndroid Build Coastguard Worker           return -1;
532*9880d681SAndroid Build Coastguard Worker         }
533*9880d681SAndroid Build Coastguard Worker       }
534*9880d681SAndroid Build Coastguard Worker       break;
535*9880d681SAndroid Build Coastguard Worker     default:
536*9880d681SAndroid Build Coastguard Worker       // Do nothing.
537*9880d681SAndroid Build Coastguard Worker       if (TraceExecution)
538*9880d681SAndroid Build Coastguard Worker         errs() << ToolName << ": Debug Event: <unknown>\n";
539*9880d681SAndroid Build Coastguard Worker       break;
540*9880d681SAndroid Build Coastguard Worker     }
541*9880d681SAndroid Build Coastguard Worker 
542*9880d681SAndroid Build Coastguard Worker     success = ContinueDebugEvent(DebugEvent.dwProcessId,
543*9880d681SAndroid Build Coastguard Worker                                  DebugEvent.dwThreadId,
544*9880d681SAndroid Build Coastguard Worker                                  dwContinueStatus);
545*9880d681SAndroid Build Coastguard Worker     if (!success) {
546*9880d681SAndroid Build Coastguard Worker       ec = windows_error(::GetLastError());
547*9880d681SAndroid Build Coastguard Worker       errs() << ToolName << ": Failed to continue debugging program: '"
548*9880d681SAndroid Build Coastguard Worker              << ProgramToRun << "': " << ec.message() << '\n';
549*9880d681SAndroid Build Coastguard Worker       return -1;
550*9880d681SAndroid Build Coastguard Worker     }
551*9880d681SAndroid Build Coastguard Worker 
552*9880d681SAndroid Build Coastguard Worker     dwContinueStatus = DBG_CONTINUE;
553*9880d681SAndroid Build Coastguard Worker   }
554*9880d681SAndroid Build Coastguard Worker 
555*9880d681SAndroid Build Coastguard Worker   assert(0 && "Fell out of debug loop. This shouldn't be possible!");
556*9880d681SAndroid Build Coastguard Worker   return -1;
557*9880d681SAndroid Build Coastguard Worker }
558