// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <objbase.h>

#include <algorithm>
#include <cassert>
#include <cstdio>

#include "common/windows/string_utils-inl.h"

#include "client/windows/common/ipc_protocol.h"
#include "client/windows/handler/exception_handler.h"
#include "common/windows/guid_string.h"

namespace google_breakpad {

static const int kWaitForHandlerThreadMs = 60000;
static const int kExceptionHandlerThreadInitialStackSize = 64 * 1024;

// As documented on MSDN, on failure SuspendThread returns (DWORD) -1
static const DWORD kFailedToSuspendThread = static_cast<DWORD>(-1);

// This is passed as the context to the MinidumpWriteDump callback.
typedef struct {
  AppMemoryList::const_iterator iter;
  AppMemoryList::const_iterator end;
} MinidumpCallbackContext;

vector<ExceptionHandler*>* ExceptionHandler::handler_stack_ = NULL;
LONG ExceptionHandler::handler_stack_index_ = 0;
CRITICAL_SECTION ExceptionHandler::handler_stack_critical_section_;
volatile LONG ExceptionHandler::instance_count_ = 0;

ExceptionHandler::ExceptionHandler(const wstring& dump_path,
                                   FilterCallback filter,
                                   MinidumpCallback callback,
                                   void* callback_context,
                                   int handler_types,
                                   MINIDUMP_TYPE dump_type,
                                   const wchar_t* pipe_name,
                                   const CustomClientInfo* custom_info) {
  Initialize(dump_path,
             filter,
             callback,
             callback_context,
             handler_types,
             dump_type,
             pipe_name,
             NULL,  // pipe_handle
             NULL,  // crash_generation_client
             custom_info);
}

ExceptionHandler::ExceptionHandler(const wstring& dump_path,
                                   FilterCallback filter,
                                   MinidumpCallback callback,
                                   void* callback_context,
                                   int handler_types,
                                   MINIDUMP_TYPE dump_type,
                                   HANDLE pipe_handle,
                                   const CustomClientInfo* custom_info) {
  Initialize(dump_path,
             filter,
             callback,
             callback_context,
             handler_types,
             dump_type,
             NULL,  // pipe_name
             pipe_handle,
             NULL,  // crash_generation_client
             custom_info);
}

ExceptionHandler::ExceptionHandler(
    const wstring& dump_path,
    FilterCallback filter,
    MinidumpCallback callback,
    void* callback_context,
    int handler_types,
    CrashGenerationClient* crash_generation_client) {
  // The dump_type, pipe_name and custom_info that are passed in to Initialize()
  // are not used.  The ones set in crash_generation_client are used instead.
  Initialize(dump_path,
             filter,
             callback,
             callback_context,
             handler_types,
             MiniDumpNormal,           // dump_type - not used
             NULL,                     // pipe_name - not used
             NULL,                     // pipe_handle
             crash_generation_client,
             NULL);                    // custom_info - not used
}

ExceptionHandler::ExceptionHandler(const wstring &dump_path,
                                   FilterCallback filter,
                                   MinidumpCallback callback,
                                   void* callback_context,
                                   int handler_types) {
  Initialize(dump_path,
             filter,
             callback,
             callback_context,
             handler_types,
             MiniDumpNormal,
             NULL,   // pipe_name
             NULL,   // pipe_handle
             NULL,   // crash_generation_client
             NULL);  // custom_info
}

void ExceptionHandler::Initialize(
    const wstring& dump_path,
    FilterCallback filter,
    MinidumpCallback callback,
    void* callback_context,
    int handler_types,
    MINIDUMP_TYPE dump_type,
    const wchar_t* pipe_name,
    HANDLE pipe_handle,
    CrashGenerationClient* crash_generation_client,
    const CustomClientInfo* custom_info) {
  LONG instance_count = InterlockedIncrement(&instance_count_);
  filter_ = filter;
  callback_ = callback;
  callback_context_ = callback_context;
  dump_path_c_ = NULL;
  next_minidump_id_c_ = NULL;
  next_minidump_path_c_ = NULL;
  dbghelp_module_ = NULL;
  minidump_write_dump_ = NULL;
  dump_type_ = dump_type;
  rpcrt4_module_ = NULL;
  uuid_create_ = NULL;
  handler_types_ = handler_types;
  previous_filter_ = NULL;
#if _MSC_VER >= 1400  // MSVC 2005/8
  previous_iph_ = NULL;
#endif  // _MSC_VER >= 1400
  previous_pch_ = NULL;
  handler_thread_ = NULL;
  is_shutdown_ = false;
  handler_start_semaphore_ = NULL;
  handler_finish_semaphore_ = NULL;
  requesting_thread_id_ = 0;
  exception_info_ = NULL;
  assertion_ = NULL;
  handler_return_value_ = false;
  handle_debug_exceptions_ = false;
  consume_invalid_handle_exceptions_ = false;

  // Attempt to use out-of-process if user has specified a pipe or a
  // crash generation client.
  scoped_ptr<CrashGenerationClient> client;
  if (crash_generation_client) {
    client.reset(crash_generation_client);
  } else if (pipe_name) {
    client.reset(
      new CrashGenerationClient(pipe_name, dump_type_, custom_info));
  } else if (pipe_handle) {
    client.reset(
      new CrashGenerationClient(pipe_handle, dump_type_, custom_info));
  }

  if (client.get() != NULL) {
    // If successful in registering with the monitoring process,
    // there is no need to setup in-process crash generation.
    if (client->Register()) {
      crash_generation_client_.reset(client.release());
    }
  }

  if (!IsOutOfProcess()) {
    // Either client did not ask for out-of-process crash generation
    // or registration with the server process failed. In either case,
    // setup to do in-process crash generation.

    // Set synchronization primitives and the handler thread.  Each
    // ExceptionHandler object gets its own handler thread because that's the
    // only way to reliably guarantee sufficient stack space in an exception,
    // and it allows an easy way to get a snapshot of the requesting thread's
    // context outside of an exception.
    InitializeCriticalSection(&handler_critical_section_);
    handler_start_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL);
    assert(handler_start_semaphore_ != NULL);

    handler_finish_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL);
    assert(handler_finish_semaphore_ != NULL);

    // Don't attempt to create the thread if we could not create the semaphores.
    if (handler_finish_semaphore_ != NULL && handler_start_semaphore_ != NULL) {
      DWORD thread_id;
      handler_thread_ = CreateThread(NULL,         // lpThreadAttributes
                                     kExceptionHandlerThreadInitialStackSize,
                                     ExceptionHandlerThreadMain,
                                     this,         // lpParameter
                                     0,            // dwCreationFlags
                                     &thread_id);
      assert(handler_thread_ != NULL);
    }

    dbghelp_module_ = LoadLibrary(L"dbghelp.dll");
    if (dbghelp_module_) {
      minidump_write_dump_ = reinterpret_cast<MiniDumpWriteDump_type>(
          GetProcAddress(dbghelp_module_, "MiniDumpWriteDump"));
    }

    // Load this library dynamically to not affect existing projects.  Most
    // projects don't link against this directly, it's usually dynamically
    // loaded by dependent code.
    rpcrt4_module_ = LoadLibrary(L"rpcrt4.dll");
    if (rpcrt4_module_) {
      uuid_create_ = reinterpret_cast<UuidCreate_type>(
          GetProcAddress(rpcrt4_module_, "UuidCreate"));
    }

    // set_dump_path calls UpdateNextID.  This sets up all of the path and id
    // strings, and their equivalent c_str pointers.
    set_dump_path(dump_path);
  }

  // Reserve one element for the instruction memory
  AppMemory instruction_memory;
  instruction_memory.ptr = NULL;
  instruction_memory.length = 0;
  app_memory_info_.push_back(instruction_memory);

  // There is a race condition here. If the first instance has not yet
  // initialized the critical section, the second (and later) instances may
  // try to use uninitialized critical section object. The feature of multiple
  // instances in one module is not used much, so leave it as is for now.
  // One way to solve this in the current design (that is, keeping the static
  // handler stack) is to use spin locks with volatile bools to synchronize
  // the handler stack. This works only if the compiler guarantees to generate
  // cache coherent code for volatile.
  // TODO(munjal): Fix this in a better way by changing the design if possible.

  // Lazy initialization of the handler_stack_critical_section_
  if (instance_count == 1) {
    InitializeCriticalSection(&handler_stack_critical_section_);
  }

  if (handler_types != HANDLER_NONE) {
    EnterCriticalSection(&handler_stack_critical_section_);

    // The first time an ExceptionHandler that installs a handler is
    // created, set up the handler stack.
    if (!handler_stack_) {
      handler_stack_ = new vector<ExceptionHandler*>();
    }
    handler_stack_->push_back(this);

    if (handler_types & HANDLER_EXCEPTION)
      previous_filter_ = SetUnhandledExceptionFilter(HandleException);

#if _MSC_VER >= 1400  // MSVC 2005/8
    if (handler_types & HANDLER_INVALID_PARAMETER)
      previous_iph_ = _set_invalid_parameter_handler(HandleInvalidParameter);
#endif  // _MSC_VER >= 1400

    if (handler_types & HANDLER_PURECALL)
      previous_pch_ = _set_purecall_handler(HandlePureVirtualCall);

    LeaveCriticalSection(&handler_stack_critical_section_);
  }
}

ExceptionHandler::~ExceptionHandler() {
  if (dbghelp_module_) {
    FreeLibrary(dbghelp_module_);
  }

  if (rpcrt4_module_) {
    FreeLibrary(rpcrt4_module_);
  }

  if (handler_types_ != HANDLER_NONE) {
    EnterCriticalSection(&handler_stack_critical_section_);

    if (handler_types_ & HANDLER_EXCEPTION)
      SetUnhandledExceptionFilter(previous_filter_);

#if _MSC_VER >= 1400  // MSVC 2005/8
    if (handler_types_ & HANDLER_INVALID_PARAMETER)
      _set_invalid_parameter_handler(previous_iph_);
#endif  // _MSC_VER >= 1400

    if (handler_types_ & HANDLER_PURECALL)
      _set_purecall_handler(previous_pch_);

    if (handler_stack_->back() == this) {
      handler_stack_->pop_back();
    } else {
      // TODO(mmentovai): use advapi32!ReportEvent to log the warning to the
      // system's application event log.
      fprintf(stderr, "warning: removing Breakpad handler out of order\n");
      vector<ExceptionHandler*>::iterator iterator = handler_stack_->begin();
      while (iterator != handler_stack_->end()) {
        if (*iterator == this) {
          iterator = handler_stack_->erase(iterator);
        } else {
          ++iterator;
        }
      }
    }

    if (handler_stack_->empty()) {
      // When destroying the last ExceptionHandler that installed a handler,
      // clean up the handler stack.
      delete handler_stack_;
      handler_stack_ = NULL;
    }

    LeaveCriticalSection(&handler_stack_critical_section_);
  }

  // Some of the objects were only initialized if out of process
  // registration was not done.
  if (!IsOutOfProcess()) {
#ifdef BREAKPAD_NO_TERMINATE_THREAD
    // Clean up the handler thread and synchronization primitives. The handler
    // thread is either waiting on the semaphore to handle a crash or it is
    // handling a crash. Coming out of the wait is fast but wait more in the
    // eventuality a crash is handled.  This compilation option results in a
    // deadlock if the exception handler is destroyed while executing code
    // inside DllMain.
    is_shutdown_ = true;
    ReleaseSemaphore(handler_start_semaphore_, 1, NULL);
    WaitForSingleObject(handler_thread_, kWaitForHandlerThreadMs);
#else
    TerminateThread(handler_thread_, 1);
#endif  // BREAKPAD_NO_TERMINATE_THREAD

    CloseHandle(handler_thread_);
    handler_thread_ = NULL;
    DeleteCriticalSection(&handler_critical_section_);
    CloseHandle(handler_start_semaphore_);
    CloseHandle(handler_finish_semaphore_);
  }

  // There is a race condition in the code below: if this instance is
  // deleting the static critical section and a new instance of the class
  // is created, then there is a possibility that the critical section be
  // initialized while the same critical section is being deleted. Given the
  // usage pattern for the code, this race condition is unlikely to hit, but it
  // is a race condition nonetheless.
  if (InterlockedDecrement(&instance_count_) == 0) {
    DeleteCriticalSection(&handler_stack_critical_section_);
  }
}

bool ExceptionHandler::RequestUpload(DWORD crash_id) {
  return crash_generation_client_->RequestUpload(crash_id);
}

// static
DWORD ExceptionHandler::ExceptionHandlerThreadMain(void* lpParameter) {
  ExceptionHandler* self = reinterpret_cast<ExceptionHandler *>(lpParameter);
  assert(self);
  assert(self->handler_start_semaphore_ != NULL);
  assert(self->handler_finish_semaphore_ != NULL);

  while (true) {
    if (WaitForSingleObject(self->handler_start_semaphore_, INFINITE) ==
        WAIT_OBJECT_0) {
      // Perform the requested action.
      if (self->is_shutdown_) {
        // The instance of the exception handler is being destroyed.
        break;
      } else {
        self->handler_return_value_ =
            self->WriteMinidumpWithException(self->requesting_thread_id_,
                                             self->exception_info_,
                                             self->assertion_);
      }

      // Allow the requesting thread to proceed.
      ReleaseSemaphore(self->handler_finish_semaphore_, 1, NULL);
    }
  }

  // This statement is not reached when the thread is unconditionally
  // terminated by the ExceptionHandler destructor.
  return 0;
}

// HandleException and HandleInvalidParameter must create an
// AutoExceptionHandler object to maintain static state and to determine which
// ExceptionHandler instance to use.  The constructor locates the correct
// instance, and makes it available through get_handler().  The destructor
// restores the state in effect prior to allocating the AutoExceptionHandler.
class AutoExceptionHandler {
 public:
  AutoExceptionHandler() {
    // Increment handler_stack_index_ so that if another Breakpad handler is
    // registered using this same HandleException function, and it needs to be
    // called while this handler is running (either because this handler
    // declines to handle the exception, or an exception occurs during
    // handling), HandleException will find the appropriate ExceptionHandler
    // object in handler_stack_ to deliver the exception to.
    //
    // Because handler_stack_ is addressed in reverse (as |size - index|),
    // preincrementing handler_stack_index_ avoids needing to subtract 1 from
    // the argument to |at|.
    //
    // The index is maintained instead of popping elements off of the handler
    // stack and pushing them at the end of this method.  This avoids ruining
    // the order of elements in the stack in the event that some other thread
    // decides to manipulate the handler stack (such as creating a new
    // ExceptionHandler object) while an exception is being handled.
    EnterCriticalSection(&ExceptionHandler::handler_stack_critical_section_);
    handler_ = ExceptionHandler::handler_stack_->at(
        ExceptionHandler::handler_stack_->size() -
        ++ExceptionHandler::handler_stack_index_);

    // In case another exception occurs while this handler is doing its thing,
    // it should be delivered to the previous filter.
    SetUnhandledExceptionFilter(handler_->previous_filter_);
#if _MSC_VER >= 1400  // MSVC 2005/8
    _set_invalid_parameter_handler(handler_->previous_iph_);
#endif  // _MSC_VER >= 1400
    _set_purecall_handler(handler_->previous_pch_);
  }

  ~AutoExceptionHandler() {
    // Put things back the way they were before entering this handler.
    SetUnhandledExceptionFilter(ExceptionHandler::HandleException);
#if _MSC_VER >= 1400  // MSVC 2005/8
    _set_invalid_parameter_handler(ExceptionHandler::HandleInvalidParameter);
#endif  // _MSC_VER >= 1400
    _set_purecall_handler(ExceptionHandler::HandlePureVirtualCall);

    --ExceptionHandler::handler_stack_index_;
    LeaveCriticalSection(&ExceptionHandler::handler_stack_critical_section_);
  }

  ExceptionHandler* get_handler() const { return handler_; }

 private:
  ExceptionHandler* handler_;
};

// static
LONG ExceptionHandler::HandleException(EXCEPTION_POINTERS* exinfo) {
  AutoExceptionHandler auto_exception_handler;
  ExceptionHandler* current_handler = auto_exception_handler.get_handler();

  // Ignore EXCEPTION_BREAKPOINT and EXCEPTION_SINGLE_STEP exceptions.  This
  // logic will short-circuit before calling WriteMinidumpOnHandlerThread,
  // allowing something else to handle the breakpoint without incurring the
  // overhead transitioning to and from the handler thread.  This behavior
  // can be overridden by calling ExceptionHandler::set_handle_debug_exceptions.
  DWORD code = exinfo->ExceptionRecord->ExceptionCode;
  LONG action;
  bool is_debug_exception = (code == EXCEPTION_BREAKPOINT) ||
                            (code == EXCEPTION_SINGLE_STEP);

  if (code == EXCEPTION_INVALID_HANDLE &&
      current_handler->consume_invalid_handle_exceptions_) {
    return EXCEPTION_CONTINUE_EXECUTION;
  }

  bool success = false;

  if (!is_debug_exception ||
      current_handler->get_handle_debug_exceptions()) {
    // If out-of-proc crash handler client is available, we have to use that
    // to generate dump and we cannot fall back on in-proc dump generation
    // because we never prepared for an in-proc dump generation

    // In case of out-of-process dump generation, directly call
    // WriteMinidumpWithException since there is no separate thread running.
    if (current_handler->IsOutOfProcess()) {
      success = current_handler->WriteMinidumpWithException(
          GetCurrentThreadId(),
          exinfo,
          NULL);
    } else {
      success = current_handler->WriteMinidumpOnHandlerThread(exinfo, NULL);
    }
  }

  // The handler fully handled the exception.  Returning
  // EXCEPTION_EXECUTE_HANDLER indicates this to the system, and usually
  // results in the application being terminated.
  //
  // Note: If the application was launched from within the Cygwin
  // environment, returning EXCEPTION_EXECUTE_HANDLER seems to cause the
  // application to be restarted.
  if (success) {
    action = EXCEPTION_EXECUTE_HANDLER;
  } else {
    // There was an exception, it was a breakpoint or something else ignored
    // above, or it was passed to the handler, which decided not to handle it.
    // This could be because the filter callback didn't want it, because
    // minidump writing failed for some reason, or because the post-minidump
    // callback function indicated failure.  Give the previous handler a
    // chance to do something with the exception.  If there is no previous
    // handler, return EXCEPTION_CONTINUE_SEARCH, which will allow a debugger
    // or native "crashed" dialog to handle the exception.
    if (current_handler->previous_filter_) {
      action = current_handler->previous_filter_(exinfo);
    } else {
      action = EXCEPTION_CONTINUE_SEARCH;
    }
  }

  return action;
}

#if _MSC_VER >= 1400  // MSVC 2005/8
// static
void ExceptionHandler::HandleInvalidParameter(const wchar_t* expression,
                                              const wchar_t* function,
                                              const wchar_t* file,
                                              unsigned int line,
                                              uintptr_t reserved) {
  // This is an invalid parameter, not an exception.  It's safe to play with
  // sprintf here.
  AutoExceptionHandler auto_exception_handler;
  ExceptionHandler* current_handler = auto_exception_handler.get_handler();

  MDRawAssertionInfo assertion;
  memset(&assertion, 0, sizeof(assertion));
  _snwprintf_s(reinterpret_cast<wchar_t*>(assertion.expression),
               sizeof(assertion.expression) / sizeof(assertion.expression[0]),
               _TRUNCATE, L"%s", expression);
  _snwprintf_s(reinterpret_cast<wchar_t*>(assertion.function),
               sizeof(assertion.function) / sizeof(assertion.function[0]),
               _TRUNCATE, L"%s", function);
  _snwprintf_s(reinterpret_cast<wchar_t*>(assertion.file),
               sizeof(assertion.file) / sizeof(assertion.file[0]),
               _TRUNCATE, L"%s", file);
  assertion.line = line;
  assertion.type = MD_ASSERTION_INFO_TYPE_INVALID_PARAMETER;

  // Make up an exception record for the current thread and CPU context
  // to make it possible for the crash processor to classify these
  // as do regular crashes, and to make it humane for developers to
  // analyze them.
  EXCEPTION_RECORD exception_record = {};
  CONTEXT exception_context = {};
  EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };

  ::RtlCaptureContext(&exception_context);

  exception_record.ExceptionCode = STATUS_INVALID_PARAMETER;

  // We store pointers to the the expression and function strings,
  // and the line as exception parameters to make them easy to
  // access by the developer on the far side.
  exception_record.NumberParameters = 3;
  exception_record.ExceptionInformation[0] =
      reinterpret_cast<ULONG_PTR>(&assertion.expression);
  exception_record.ExceptionInformation[1] =
      reinterpret_cast<ULONG_PTR>(&assertion.file);
  exception_record.ExceptionInformation[2] = assertion.line;

  bool success = false;
  // In case of out-of-process dump generation, directly call
  // WriteMinidumpWithException since there is no separate thread running.
  if (current_handler->IsOutOfProcess()) {
    success = current_handler->WriteMinidumpWithException(
        GetCurrentThreadId(),
        &exception_ptrs,
        &assertion);
  } else {
    success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs,
                                                            &assertion);
  }

  if (!success) {
    if (current_handler->previous_iph_) {
      // The handler didn't fully handle the exception.  Give it to the
      // previous invalid parameter handler.
      current_handler->previous_iph_(expression,
                                     function,
                                     file,
                                     line,
                                     reserved);
    } else {
      // If there's no previous handler, pass the exception back in to the
      // invalid parameter handler's core.  That's the routine that called this
      // function, but now, since this function is no longer registered (and in
      // fact, no function at all is registered), this will result in the
      // default code path being taken: _CRT_DEBUGGER_HOOK and _invoke_watson.
      // Use _invalid_parameter where it exists (in _DEBUG builds) as it passes
      // more information through.  In non-debug builds, it is not available,
      // so fall back to using _invalid_parameter_noinfo.  See invarg.c in the
      // CRT source.
#ifdef _DEBUG
      _invalid_parameter(expression, function, file, line, reserved);
#else  // _DEBUG
      _invalid_parameter_noinfo();
#endif  // _DEBUG
    }
  }

  // The handler either took care of the invalid parameter problem itself,
  // or passed it on to another handler.  "Swallow" it by exiting, paralleling
  // the behavior of "swallowing" exceptions.
  exit(0);
}
#endif  // _MSC_VER >= 1400

// static
void ExceptionHandler::HandlePureVirtualCall() {
  // This is an pure virtual function call, not an exception.  It's safe to
  // play with sprintf here.
  AutoExceptionHandler auto_exception_handler;
  ExceptionHandler* current_handler = auto_exception_handler.get_handler();

  MDRawAssertionInfo assertion;
  memset(&assertion, 0, sizeof(assertion));
  assertion.type = MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL;

  // Make up an exception record for the current thread and CPU context
  // to make it possible for the crash processor to classify these
  // as do regular crashes, and to make it humane for developers to
  // analyze them.
  EXCEPTION_RECORD exception_record = {};
  CONTEXT exception_context = {};
  EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };

  ::RtlCaptureContext(&exception_context);

  exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;

  // We store pointers to the the expression and function strings,
  // and the line as exception parameters to make them easy to
  // access by the developer on the far side.
  exception_record.NumberParameters = 3;
  exception_record.ExceptionInformation[0] =
      reinterpret_cast<ULONG_PTR>(&assertion.expression);
  exception_record.ExceptionInformation[1] =
      reinterpret_cast<ULONG_PTR>(&assertion.file);
  exception_record.ExceptionInformation[2] = assertion.line;

  bool success = false;
  // In case of out-of-process dump generation, directly call
  // WriteMinidumpWithException since there is no separate thread running.

  if (current_handler->IsOutOfProcess()) {
    success = current_handler->WriteMinidumpWithException(
        GetCurrentThreadId(),
        &exception_ptrs,
        &assertion);
  } else {
    success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs,
                                                            &assertion);
  }

  if (!success) {
    if (current_handler->previous_pch_) {
      // The handler didn't fully handle the exception.  Give it to the
      // previous purecall handler.
      current_handler->previous_pch_();
    } else {
      // If there's no previous handler, return and let _purecall handle it.
      // This will just put up an assertion dialog.
      return;
    }
  }

  // The handler either took care of the invalid parameter problem itself,
  // or passed it on to another handler.  "Swallow" it by exiting, paralleling
  // the behavior of "swallowing" exceptions.
  exit(0);
}

bool ExceptionHandler::WriteMinidumpOnHandlerThread(
    EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion) {
  EnterCriticalSection(&handler_critical_section_);

  // There isn't much we can do if the handler thread
  // was not successfully created.
  if (handler_thread_ == NULL) {
    LeaveCriticalSection(&handler_critical_section_);
    return false;
  }

  // The handler thread should only be created when the semaphores are valid.
  assert(handler_start_semaphore_ != NULL);
  assert(handler_finish_semaphore_ != NULL);

  // Set up data to be passed in to the handler thread.
  requesting_thread_id_ = GetCurrentThreadId();
  exception_info_ = exinfo;
  assertion_ = assertion;

  // This causes the handler thread to call WriteMinidumpWithException.
  ReleaseSemaphore(handler_start_semaphore_, 1, NULL);

  // Wait until WriteMinidumpWithException is done and collect its return value.
  WaitForSingleObject(handler_finish_semaphore_, INFINITE);
  bool status = handler_return_value_;

  // Clean up.
  requesting_thread_id_ = 0;
  exception_info_ = NULL;
  assertion_ = NULL;

  LeaveCriticalSection(&handler_critical_section_);

  return status;
}

bool ExceptionHandler::WriteMinidump() {
  // Make up an exception record for the current thread and CPU context
  // to make it possible for the crash processor to classify these
  // as do regular crashes, and to make it humane for developers to
  // analyze them.
  EXCEPTION_RECORD exception_record = {};
  CONTEXT exception_context = {};
  EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };

  ::RtlCaptureContext(&exception_context);
  exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;

  return WriteMinidumpForException(&exception_ptrs);
}

bool ExceptionHandler::WriteMinidumpForException(EXCEPTION_POINTERS* exinfo) {
  // In case of out-of-process dump generation, directly call
  // WriteMinidumpWithException since there is no separate thread running.
  if (IsOutOfProcess()) {
    return WriteMinidumpWithException(GetCurrentThreadId(),
                                      exinfo,
                                      NULL);
  }

  bool success = WriteMinidumpOnHandlerThread(exinfo, NULL);
  UpdateNextID();
  return success;
}

// static
bool ExceptionHandler::WriteMinidump(const wstring &dump_path,
                                     MinidumpCallback callback,
                                     void* callback_context) {
  ExceptionHandler handler(dump_path, NULL, callback, callback_context,
                           HANDLER_NONE);
  return handler.WriteMinidump();
}

// static
bool ExceptionHandler::WriteMinidumpForChild(HANDLE child,
                                             DWORD child_blamed_thread,
                                             const wstring& dump_path,
                                             MinidumpCallback callback,
                                             void* callback_context) {
  EXCEPTION_RECORD ex;
  CONTEXT ctx;
  EXCEPTION_POINTERS exinfo = { NULL, NULL };
  DWORD last_suspend_count = kFailedToSuspendThread;
  HANDLE child_thread_handle = OpenThread(THREAD_GET_CONTEXT |
                                          THREAD_QUERY_INFORMATION |
                                          THREAD_SUSPEND_RESUME,
                                          FALSE,
                                          child_blamed_thread);
  // This thread may have died already, so not opening the handle is a
  // non-fatal error.
  if (child_thread_handle != NULL) {
    last_suspend_count = SuspendThread(child_thread_handle);
    if (last_suspend_count != kFailedToSuspendThread) {
      ctx.ContextFlags = CONTEXT_ALL;
      if (GetThreadContext(child_thread_handle, &ctx)) {
        memset(&ex, 0, sizeof(ex));
        ex.ExceptionCode = EXCEPTION_BREAKPOINT;
#if defined(_M_IX86)
        ex.ExceptionAddress = reinterpret_cast<PVOID>(ctx.Eip);
#elif defined(_M_X64)
        ex.ExceptionAddress = reinterpret_cast<PVOID>(ctx.Rip);
#endif
        exinfo.ExceptionRecord = &ex;
        exinfo.ContextRecord = &ctx;
      }
    }
  }

  ExceptionHandler handler(dump_path, NULL, callback, callback_context,
                           HANDLER_NONE);
  bool success = handler.WriteMinidumpWithExceptionForProcess(
      child_blamed_thread,
      exinfo.ExceptionRecord ? &exinfo : NULL,
      NULL, child, false);

  if (last_suspend_count != kFailedToSuspendThread) {
    ResumeThread(child_thread_handle);
  }

  CloseHandle(child_thread_handle);

  if (callback) {
    success = callback(handler.dump_path_c_, handler.next_minidump_id_c_,
                       callback_context, NULL, NULL, success);
  }

  return success;
}

bool ExceptionHandler::WriteMinidumpWithException(
    DWORD requesting_thread_id,
    EXCEPTION_POINTERS* exinfo,
    MDRawAssertionInfo* assertion) {
  // Give user code a chance to approve or prevent writing a minidump.  If the
  // filter returns false, don't handle the exception at all.  If this method
  // was called as a result of an exception, returning false will cause
  // HandleException to call any previous handler or return
  // EXCEPTION_CONTINUE_SEARCH on the exception thread, allowing it to appear
  // as though this handler were not present at all.
  if (filter_ && !filter_(callback_context_, exinfo, assertion)) {
    return false;
  }

  bool success = false;
  if (IsOutOfProcess()) {
    success = crash_generation_client_->RequestDump(exinfo, assertion);
  } else {
    success = WriteMinidumpWithExceptionForProcess(requesting_thread_id,
                                                   exinfo,
                                                   assertion,
                                                   GetCurrentProcess(),
                                                   true);
  }

  if (callback_) {
    // TODO(munjal): In case of out-of-process dump generation, both
    // dump_path_c_ and next_minidump_id_ will be NULL. For out-of-process
    // scenario, the server process ends up creating the dump path and dump
    // id so they are not known to the client.
    success = callback_(dump_path_c_, next_minidump_id_c_, callback_context_,
                        exinfo, assertion, success);
  }

  return success;
}

// static
BOOL CALLBACK ExceptionHandler::MinidumpWriteDumpCallback(
    PVOID context,
    const PMINIDUMP_CALLBACK_INPUT callback_input,
    PMINIDUMP_CALLBACK_OUTPUT callback_output) {
  switch (callback_input->CallbackType) {
  case MemoryCallback: {
    MinidumpCallbackContext* callback_context =
        reinterpret_cast<MinidumpCallbackContext*>(context);
    if (callback_context->iter == callback_context->end)
      return FALSE;

    // Include the specified memory region.
    callback_output->MemoryBase = callback_context->iter->ptr;
    callback_output->MemorySize = callback_context->iter->length;
    callback_context->iter++;
    return TRUE;
  }

    // Include all modules.
  case IncludeModuleCallback:
  case ModuleCallback:
    return TRUE;

    // Include all threads.
  case IncludeThreadCallback:
  case ThreadCallback:
    return TRUE;

    // Stop receiving cancel callbacks.
  case CancelCallback:
    callback_output->CheckCancel = FALSE;
    callback_output->Cancel = FALSE;
    return TRUE;
  }
  // Ignore other callback types.
  return FALSE;
}

bool ExceptionHandler::WriteMinidumpWithExceptionForProcess(
    DWORD requesting_thread_id,
    EXCEPTION_POINTERS* exinfo,
    MDRawAssertionInfo* assertion,
    HANDLE process,
    bool write_requester_stream) {
  bool success = false;
  if (minidump_write_dump_) {
    HANDLE dump_file = CreateFile(next_minidump_path_c_,
                                  GENERIC_WRITE,
                                  0,  // no sharing
                                  NULL,
                                  CREATE_NEW,  // fail if exists
                                  FILE_ATTRIBUTE_NORMAL,
                                  NULL);
    if (dump_file != INVALID_HANDLE_VALUE) {
      MINIDUMP_EXCEPTION_INFORMATION except_info;
      except_info.ThreadId = requesting_thread_id;
      except_info.ExceptionPointers = exinfo;
      except_info.ClientPointers = FALSE;

      // Leave room in user_stream_array for possible breakpad and
      // assertion info streams.
      MINIDUMP_USER_STREAM user_stream_array[2];
      MINIDUMP_USER_STREAM_INFORMATION user_streams;
      user_streams.UserStreamCount = 0;
      user_streams.UserStreamArray = user_stream_array;

      if (write_requester_stream) {
        // Add an MDRawBreakpadInfo stream to the minidump, to provide
        // additional information about the exception handler to the Breakpad
        // processor. The information will help the processor determine which
        // threads are relevant.  The Breakpad processor does not require this
        // information but can function better with Breakpad-generated dumps
        // when it is present. The native debugger is not harmed by the
        // presence of this information.
        MDRawBreakpadInfo breakpad_info;
        breakpad_info.validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID |
                                 MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID;
        breakpad_info.dump_thread_id = GetCurrentThreadId();
        breakpad_info.requesting_thread_id = requesting_thread_id;

        int index = user_streams.UserStreamCount;
        user_stream_array[index].Type = MD_BREAKPAD_INFO_STREAM;
        user_stream_array[index].BufferSize = sizeof(breakpad_info);
        user_stream_array[index].Buffer = &breakpad_info;
        ++user_streams.UserStreamCount;
      }

      if (assertion) {
        int index = user_streams.UserStreamCount;
        user_stream_array[index].Type = MD_ASSERTION_INFO_STREAM;
        user_stream_array[index].BufferSize = sizeof(MDRawAssertionInfo);
        user_stream_array[index].Buffer = assertion;
        ++user_streams.UserStreamCount;
      }

      // Older versions of DbgHelp.dll don't correctly put the memory around
      // the faulting instruction pointer into the minidump. This
      // callback will ensure that it gets included.
      if (exinfo) {
        // Find a memory region of 256 bytes centered on the
        // faulting instruction pointer.
        const ULONG64 instruction_pointer =
#if defined(_M_IX86)
          exinfo->ContextRecord->Eip;
#elif defined(_M_AMD64)
        exinfo->ContextRecord->Rip;
#else
#error Unsupported platform
#endif

        MEMORY_BASIC_INFORMATION info;
        if (VirtualQueryEx(process,
                           reinterpret_cast<LPCVOID>(instruction_pointer),
                           &info,
                           sizeof(MEMORY_BASIC_INFORMATION)) != 0 &&
            info.State == MEM_COMMIT) {
          // Attempt to get 128 bytes before and after the instruction
          // pointer, but settle for whatever's available up to the
          // boundaries of the memory region.
          const ULONG64 kIPMemorySize = 256;
          ULONG64 base =
            (std::max)(reinterpret_cast<ULONG64>(info.BaseAddress),
                       instruction_pointer - (kIPMemorySize / 2));
          ULONG64 end_of_range =
            (std::min)(instruction_pointer + (kIPMemorySize / 2),
                       reinterpret_cast<ULONG64>(info.BaseAddress)
                       + info.RegionSize);
          ULONG size = static_cast<ULONG>(end_of_range - base);

          AppMemory& elt = app_memory_info_.front();
          elt.ptr = base;
          elt.length = size;
        }
      }

      MinidumpCallbackContext context;
      context.iter = app_memory_info_.begin();
      context.end = app_memory_info_.end();

      // Skip the reserved element if there was no instruction memory
      if (context.iter->ptr == 0) {
        context.iter++;
      }

      MINIDUMP_CALLBACK_INFORMATION callback;
      callback.CallbackRoutine = MinidumpWriteDumpCallback;
      callback.CallbackParam = reinterpret_cast<void*>(&context);

      // The explicit comparison to TRUE avoids a warning (C4800).
      success = (minidump_write_dump_(process,
                                      GetProcessId(process),
                                      dump_file,
                                      dump_type_,
                                      exinfo ? &except_info : NULL,
                                      &user_streams,
                                      &callback) == TRUE);

      CloseHandle(dump_file);
    }
  }

  return success;
}

void ExceptionHandler::UpdateNextID() {
  assert(uuid_create_);
  UUID id = {0};
  if (uuid_create_) {
    uuid_create_(&id);
  }
  next_minidump_id_ = GUIDString::GUIDToWString(&id);
  next_minidump_id_c_ = next_minidump_id_.c_str();

  wchar_t minidump_path[MAX_PATH];
  swprintf(minidump_path, MAX_PATH, L"%s\\%s.dmp",
           dump_path_c_, next_minidump_id_c_);

  // remove when VC++7.1 is no longer supported
  minidump_path[MAX_PATH - 1] = L'\0';

  next_minidump_path_ = minidump_path;
  next_minidump_path_c_ = next_minidump_path_.c_str();
}

void ExceptionHandler::RegisterAppMemory(void* ptr, size_t length) {
  AppMemoryList::iterator iter =
    std::find(app_memory_info_.begin(), app_memory_info_.end(), ptr);
  if (iter != app_memory_info_.end()) {
    // Don't allow registering the same pointer twice.
    return;
  }

  AppMemory app_memory;
  app_memory.ptr = reinterpret_cast<ULONG64>(ptr);
  app_memory.length = static_cast<ULONG>(length);
  app_memory_info_.push_back(app_memory);
}

void ExceptionHandler::UnregisterAppMemory(void* ptr) {
  AppMemoryList::iterator iter =
    std::find(app_memory_info_.begin(), app_memory_info_.end(), ptr);
  if (iter != app_memory_info_.end()) {
    app_memory_info_.erase(iter);
  }
}

}  // namespace google_breakpad
