//===- KillTheDoctor - Prevent Dr. Watson from stopping tests ---*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This program provides an extremely hacky way to stop Dr. Watson from starting
// due to unhandled exceptions in child processes.
//
// This simply starts the program named in the first positional argument with
// the arguments following it under a debugger. All this debugger does is catch
// any unhandled exceptions thrown in the child process and close the program
// (and hopefully tells someone about it).
//
// This also provides another really hacky method to prevent assert dialog boxes
// from popping up. When --no-user32 is passed, if any process loads user32.dll,
// we assume it is trying to call MessageBoxEx and terminate it. The proper way
// to do this would be to actually set a break point, but there's quite a bit
// of code involved to get the address of MessageBoxEx in the remote process's
// address space due to Address space layout randomization (ASLR). This can be
// added if it's ever actually needed.
//
// If the subprocess exits for any reason other than successful termination, -1
// is returned. If the process exits normally the value it returned is returned.
//
// I hate Windows.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/WindowsError.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cerrno>
#include <cstdlib>
#include <map>
#include <string>
#include <system_error>

// These includes must be last.
#include <Windows.h>
#include <WinError.h>
#include <Dbghelp.h>
#include <psapi.h>

using namespace llvm;

#undef max

namespace {
  cl::opt<std::string> ProgramToRun(cl::Positional,
    cl::desc("<program to run>"));
  cl::list<std::string>  Argv(cl::ConsumeAfter,
    cl::desc("<program arguments>..."));
  cl::opt<bool> TraceExecution("x",
    cl::desc("Print detailed output about what is being run to stderr."));
  cl::opt<unsigned> Timeout("t", cl::init(0),
    cl::desc("Set maximum runtime in seconds. Defaults to infinite."));
  cl::opt<bool> NoUser32("no-user32",
    cl::desc("Terminate process if it loads user32.dll."));

  StringRef ToolName;

  template <typename HandleType>
  class ScopedHandle {
    typedef typename HandleType::handle_type handle_type;

    handle_type Handle;

  public:
    ScopedHandle()
      : Handle(HandleType::GetInvalidHandle()) {}

    explicit ScopedHandle(handle_type handle)
      : Handle(handle) {}

    ~ScopedHandle() {
      HandleType::Destruct(Handle);
    }

    ScopedHandle& operator=(handle_type handle) {
      // Cleanup current handle.
      if (!HandleType::isValid(Handle))
        HandleType::Destruct(Handle);
      Handle = handle;
      return *this;
    }

    operator bool() const {
      return HandleType::isValid(Handle);
    }

    operator handle_type() {
      return Handle;
    }
  };

  // This implements the most common handle in the Windows API.
  struct CommonHandle {
    typedef HANDLE handle_type;

    static handle_type GetInvalidHandle() {
      return INVALID_HANDLE_VALUE;
    }

    static void Destruct(handle_type Handle) {
      ::CloseHandle(Handle);
    }

    static bool isValid(handle_type Handle) {
      return Handle != GetInvalidHandle();
    }
  };

  struct FileMappingHandle {
    typedef HANDLE handle_type;

    static handle_type GetInvalidHandle() {
      return NULL;
    }

    static void Destruct(handle_type Handle) {
      ::CloseHandle(Handle);
    }

    static bool isValid(handle_type Handle) {
      return Handle != GetInvalidHandle();
    }
  };

  struct MappedViewOfFileHandle {
    typedef LPVOID handle_type;

    static handle_type GetInvalidHandle() {
      return NULL;
    }

    static void Destruct(handle_type Handle) {
      ::UnmapViewOfFile(Handle);
    }

    static bool isValid(handle_type Handle) {
      return Handle != GetInvalidHandle();
    }
  };

  struct ProcessHandle : CommonHandle {};
  struct ThreadHandle  : CommonHandle {};
  struct TokenHandle   : CommonHandle {};
  struct FileHandle    : CommonHandle {};

  typedef ScopedHandle<FileMappingHandle>       FileMappingScopedHandle;
  typedef ScopedHandle<MappedViewOfFileHandle>  MappedViewOfFileScopedHandle;
  typedef ScopedHandle<ProcessHandle>           ProcessScopedHandle;
  typedef ScopedHandle<ThreadHandle>            ThreadScopedHandle;
  typedef ScopedHandle<TokenHandle>             TokenScopedHandle;
  typedef ScopedHandle<FileHandle>              FileScopedHandle;
}

static std::error_code windows_error(DWORD E) { return mapWindowsError(E); }

static std::error_code GetFileNameFromHandle(HANDLE FileHandle,
                                             std::string &Name) {
  char Filename[MAX_PATH+1];
  bool Success = false;
  Name.clear();

  // Get the file size.
  LARGE_INTEGER FileSize;
  Success = ::GetFileSizeEx(FileHandle, &FileSize);

  if (!Success)
    return windows_error(::GetLastError());

  // Create a file mapping object.
  FileMappingScopedHandle FileMapping(
    ::CreateFileMappingA(FileHandle,
                         NULL,
                         PAGE_READONLY,
                         0,
                         1,
                         NULL));

  if (!FileMapping)
    return windows_error(::GetLastError());

  // Create a file mapping to get the file name.
  MappedViewOfFileScopedHandle MappedFile(
    ::MapViewOfFile(FileMapping, FILE_MAP_READ, 0, 0, 1));

  if (!MappedFile)
    return windows_error(::GetLastError());

  Success = ::GetMappedFileNameA(::GetCurrentProcess(),
                                MappedFile,
                                Filename,
                                array_lengthof(Filename) - 1);

  if (!Success)
    return windows_error(::GetLastError());
  else {
    Name = Filename;
    return std::error_code();
  }
}

/// @brief Find program using shell lookup rules.
/// @param Program This is either an absolute path, relative path, or simple a
///        program name. Look in PATH for any programs that match. If no
///        extension is present, try all extensions in PATHEXT.
/// @return If ec == errc::success, The absolute path to the program. Otherwise
///         the return value is undefined.
static std::string FindProgram(const std::string &Program,
                               std::error_code &ec) {
  char PathName[MAX_PATH + 1];
  typedef SmallVector<StringRef, 12> pathext_t;
  pathext_t pathext;
  // Check for the program without an extension (in case it already has one).
  pathext.push_back("");
  SplitString(std::getenv("PATHEXT"), pathext, ";");

  for (pathext_t::iterator i = pathext.begin(), e = pathext.end(); i != e; ++i){
    SmallString<5> ext;
    for (std::size_t ii = 0, e = i->size(); ii != e; ++ii)
      ext.push_back(::tolower((*i)[ii]));
    LPCSTR Extension = NULL;
    if (ext.size() && ext[0] == '.')
      Extension = ext.c_str();
    DWORD length = ::SearchPathA(NULL,
                                 Program.c_str(),
                                 Extension,
                                 array_lengthof(PathName),
                                 PathName,
                                 NULL);
    if (length == 0)
      ec = windows_error(::GetLastError());
    else if (length > array_lengthof(PathName)) {
      // This may have been the file, return with error.
      ec = windows_error(ERROR_BUFFER_OVERFLOW);
      break;
    } else {
      // We found the path! Return it.
      ec = std::error_code();
      break;
    }
  }

  // Make sure PathName is valid.
  PathName[MAX_PATH] = 0;
  return PathName;
}

static StringRef ExceptionCodeToString(DWORD ExceptionCode) {
  switch(ExceptionCode) {
  case EXCEPTION_ACCESS_VIOLATION: return "EXCEPTION_ACCESS_VIOLATION";
  case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
    return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
  case EXCEPTION_BREAKPOINT: return "EXCEPTION_BREAKPOINT";
  case EXCEPTION_DATATYPE_MISALIGNMENT:
    return "EXCEPTION_DATATYPE_MISALIGNMENT";
  case EXCEPTION_FLT_DENORMAL_OPERAND: return "EXCEPTION_FLT_DENORMAL_OPERAND";
  case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "EXCEPTION_FLT_DIVIDE_BY_ZERO";
  case EXCEPTION_FLT_INEXACT_RESULT: return "EXCEPTION_FLT_INEXACT_RESULT";
  case EXCEPTION_FLT_INVALID_OPERATION:
    return "EXCEPTION_FLT_INVALID_OPERATION";
  case EXCEPTION_FLT_OVERFLOW: return "EXCEPTION_FLT_OVERFLOW";
  case EXCEPTION_FLT_STACK_CHECK: return "EXCEPTION_FLT_STACK_CHECK";
  case EXCEPTION_FLT_UNDERFLOW: return "EXCEPTION_FLT_UNDERFLOW";
  case EXCEPTION_ILLEGAL_INSTRUCTION: return "EXCEPTION_ILLEGAL_INSTRUCTION";
  case EXCEPTION_IN_PAGE_ERROR: return "EXCEPTION_IN_PAGE_ERROR";
  case EXCEPTION_INT_DIVIDE_BY_ZERO: return "EXCEPTION_INT_DIVIDE_BY_ZERO";
  case EXCEPTION_INT_OVERFLOW: return "EXCEPTION_INT_OVERFLOW";
  case EXCEPTION_INVALID_DISPOSITION: return "EXCEPTION_INVALID_DISPOSITION";
  case EXCEPTION_NONCONTINUABLE_EXCEPTION:
    return "EXCEPTION_NONCONTINUABLE_EXCEPTION";
  case EXCEPTION_PRIV_INSTRUCTION: return "EXCEPTION_PRIV_INSTRUCTION";
  case EXCEPTION_SINGLE_STEP: return "EXCEPTION_SINGLE_STEP";
  case EXCEPTION_STACK_OVERFLOW: return "EXCEPTION_STACK_OVERFLOW";
  default: return "<unknown>";
  }
}

int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  ToolName = argv[0];

  cl::ParseCommandLineOptions(argc, argv, "Dr. Watson Assassin.\n");
  if (ProgramToRun.size() == 0) {
    cl::PrintHelpMessage();
    return -1;
  }

  if (Timeout > std::numeric_limits<uint32_t>::max() / 1000) {
    errs() << ToolName << ": Timeout value too large, must be less than: "
                       << std::numeric_limits<uint32_t>::max() / 1000
                       << '\n';
    return -1;
  }

  std::string CommandLine(ProgramToRun);

  std::error_code ec;
  ProgramToRun = FindProgram(ProgramToRun, ec);
  if (ec) {
    errs() << ToolName << ": Failed to find program: '" << CommandLine
           << "': " << ec.message() << '\n';
    return -1;
  }

  if (TraceExecution)
    errs() << ToolName << ": Found Program: " << ProgramToRun << '\n';

  for (std::vector<std::string>::iterator i = Argv.begin(),
                                          e = Argv.end();
                                          i != e; ++i) {
    CommandLine.push_back(' ');
    CommandLine.append(*i);
  }

  if (TraceExecution)
    errs() << ToolName << ": Program Image Path: " << ProgramToRun << '\n'
           << ToolName << ": Command Line: " << CommandLine << '\n';

  STARTUPINFO StartupInfo;
  PROCESS_INFORMATION ProcessInfo;
  std::memset(&StartupInfo, 0, sizeof(StartupInfo));
  StartupInfo.cb = sizeof(StartupInfo);
  std::memset(&ProcessInfo, 0, sizeof(ProcessInfo));

  // Set error mode to not display any message boxes. The child process inherits
  // this.
  ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
  ::_set_error_mode(_OUT_TO_STDERR);

  BOOL success = ::CreateProcessA(ProgramToRun.c_str(),
                            LPSTR(CommandLine.c_str()),
                                  NULL,
                                  NULL,
                                  FALSE,
                                  DEBUG_PROCESS,
                                  NULL,
                                  NULL,
                                  &StartupInfo,
                                  &ProcessInfo);
  if (!success) {
    errs() << ToolName << ": Failed to run program: '" << ProgramToRun << "': "
           << std::error_code(windows_error(::GetLastError())).message()
           << '\n';
    return -1;
  }

  // Make sure ::CloseHandle is called on exit.
  std::map<DWORD, HANDLE> ProcessIDToHandle;

  DEBUG_EVENT DebugEvent;
  std::memset(&DebugEvent, 0, sizeof(DebugEvent));
  DWORD dwContinueStatus = DBG_CONTINUE;

  // Run the program under the debugger until either it exits, or throws an
  // exception.
  if (TraceExecution)
    errs() << ToolName << ": Debugging...\n";

  while(true) {
    DWORD TimeLeft = INFINITE;
    if (Timeout > 0) {
      FILETIME CreationTime, ExitTime, KernelTime, UserTime;
      ULARGE_INTEGER a, b;
      success = ::GetProcessTimes(ProcessInfo.hProcess,
                                  &CreationTime,
                                  &ExitTime,
                                  &KernelTime,
                                  &UserTime);
      if (!success) {
        ec = windows_error(::GetLastError());

        errs() << ToolName << ": Failed to get process times: "
               << ec.message() << '\n';
        return -1;
      }
      a.LowPart = KernelTime.dwLowDateTime;
      a.HighPart = KernelTime.dwHighDateTime;
      b.LowPart = UserTime.dwLowDateTime;
      b.HighPart = UserTime.dwHighDateTime;
      // Convert 100-nanosecond units to milliseconds.
      uint64_t TotalTimeMiliseconds = (a.QuadPart + b.QuadPart) / 10000;
      // Handle the case where the process has been running for more than 49
      // days.
      if (TotalTimeMiliseconds > std::numeric_limits<uint32_t>::max()) {
        errs() << ToolName << ": Timeout Failed: Process has been running for"
                              "more than 49 days.\n";
        return -1;
      }

      // We check with > instead of using Timeleft because if
      // TotalTimeMiliseconds is greater than Timeout * 1000, TimeLeft would
      // underflow.
      if (TotalTimeMiliseconds > (Timeout * 1000)) {
        errs() << ToolName << ": Process timed out.\n";
        ::TerminateProcess(ProcessInfo.hProcess, -1);
        // Otherwise other stuff starts failing...
        return -1;
      }

      TimeLeft = (Timeout * 1000) - static_cast<uint32_t>(TotalTimeMiliseconds);
    }
    success = WaitForDebugEvent(&DebugEvent, TimeLeft);

    if (!success) {
      DWORD LastError = ::GetLastError();
      ec = windows_error(LastError);

      if (LastError == ERROR_SEM_TIMEOUT || LastError == WSAETIMEDOUT) {
        errs() << ToolName << ": Process timed out.\n";
        ::TerminateProcess(ProcessInfo.hProcess, -1);
        // Otherwise other stuff starts failing...
        return -1;
      }

      errs() << ToolName << ": Failed to wait for debug event in program: '"
             << ProgramToRun << "': " << ec.message() << '\n';
      return -1;
    }

    switch(DebugEvent.dwDebugEventCode) {
    case CREATE_PROCESS_DEBUG_EVENT:
      // Make sure we remove the handle on exit.
      if (TraceExecution)
        errs() << ToolName << ": Debug Event: CREATE_PROCESS_DEBUG_EVENT\n";
      ProcessIDToHandle[DebugEvent.dwProcessId] =
        DebugEvent.u.CreateProcessInfo.hProcess;
      ::CloseHandle(DebugEvent.u.CreateProcessInfo.hFile);
      break;
    case EXIT_PROCESS_DEBUG_EVENT: {
        if (TraceExecution)
          errs() << ToolName << ": Debug Event: EXIT_PROCESS_DEBUG_EVENT\n";

        // If this is the process we originally created, exit with its exit
        // code.
        if (DebugEvent.dwProcessId == ProcessInfo.dwProcessId)
          return DebugEvent.u.ExitProcess.dwExitCode;

        // Otherwise cleanup any resources we have for it.
        std::map<DWORD, HANDLE>::iterator ExitingProcess =
          ProcessIDToHandle.find(DebugEvent.dwProcessId);
        if (ExitingProcess == ProcessIDToHandle.end()) {
          errs() << ToolName << ": Got unknown process id!\n";
          return -1;
        }
        ::CloseHandle(ExitingProcess->second);
        ProcessIDToHandle.erase(ExitingProcess);
      }
      break;
    case CREATE_THREAD_DEBUG_EVENT:
      ::CloseHandle(DebugEvent.u.CreateThread.hThread);
      break;
    case LOAD_DLL_DEBUG_EVENT: {
        // Cleanup the file handle.
        FileScopedHandle DLLFile(DebugEvent.u.LoadDll.hFile);
        std::string DLLName;
        ec = GetFileNameFromHandle(DLLFile, DLLName);
        if (ec) {
          DLLName = "<failed to get file name from file handle> : ";
          DLLName += ec.message();
        }
        if (TraceExecution) {
          errs() << ToolName << ": Debug Event: LOAD_DLL_DEBUG_EVENT\n";
          errs().indent(ToolName.size()) << ": DLL Name : " << DLLName << '\n';
        }

        if (NoUser32 && sys::path::stem(DLLName) == "user32") {
          // Program is loading user32.dll, in the applications we are testing,
          // this only happens if an assert has fired. By now the message has
          // already been printed, so simply close the program.
          errs() << ToolName << ": user32.dll loaded!\n";
          errs().indent(ToolName.size())
                 << ": This probably means that assert was called. Closing "
                    "program to prevent message box from popping up.\n";
          dwContinueStatus = DBG_CONTINUE;
          ::TerminateProcess(ProcessIDToHandle[DebugEvent.dwProcessId], -1);
          return -1;
        }
      }
      break;
    case EXCEPTION_DEBUG_EVENT: {
        // Close the application if this exception will not be handled by the
        // child application.
        if (TraceExecution)
          errs() << ToolName << ": Debug Event: EXCEPTION_DEBUG_EVENT\n";

        EXCEPTION_DEBUG_INFO  &Exception = DebugEvent.u.Exception;
        if (Exception.dwFirstChance > 0) {
          if (TraceExecution) {
            errs().indent(ToolName.size()) << ": Debug Info : ";
            errs() << "First chance exception at "
                   << Exception.ExceptionRecord.ExceptionAddress
                   << ", exception code: "
                   << ExceptionCodeToString(
                        Exception.ExceptionRecord.ExceptionCode)
                   << " (" << Exception.ExceptionRecord.ExceptionCode << ")\n";
          }
          dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
        } else {
          errs() << ToolName << ": Unhandled exception in: " << ProgramToRun
                 << "!\n";
                 errs().indent(ToolName.size()) << ": location: ";
                 errs() << Exception.ExceptionRecord.ExceptionAddress
                        << ", exception code: "
                        << ExceptionCodeToString(
                            Exception.ExceptionRecord.ExceptionCode)
                        << " (" << Exception.ExceptionRecord.ExceptionCode
                        << ")\n";
          dwContinueStatus = DBG_CONTINUE;
          ::TerminateProcess(ProcessIDToHandle[DebugEvent.dwProcessId], -1);
          return -1;
        }
      }
      break;
    default:
      // Do nothing.
      if (TraceExecution)
        errs() << ToolName << ": Debug Event: <unknown>\n";
      break;
    }

    success = ContinueDebugEvent(DebugEvent.dwProcessId,
                                 DebugEvent.dwThreadId,
                                 dwContinueStatus);
    if (!success) {
      ec = windows_error(::GetLastError());
      errs() << ToolName << ": Failed to continue debugging program: '"
             << ProgramToRun << "': " << ec.message() << '\n';
      return -1;
    }

    dwContinueStatus = DBG_CONTINUE;
  }

  assert(0 && "Fell out of debug loop. This shouldn't be possible!");
  return -1;
}
