// 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 {

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

// This define is new to Windows 10.
#ifndef DBG_PRINTEXCEPTION_WIDE_C
#define DBG_PRINTEXCEPTION_WIDE_C ((DWORD)0x4001000A)
#endif

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;
      const int kExceptionHandlerThreadInitialStackSize = 64 * 1024;
      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);
    const int kWaitForHandlerThreadMs = 60000;
    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);

  for (;;) {
    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) ||
                            (code == DBG_PRINTEXCEPTION_C) ||
                            (code == DBG_PRINTEXCEPTION_WIDE_C);

  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,
                                     MINIDUMP_TYPE dump_type) {
  ExceptionHandler handler(dump_path, NULL, callback, callback_context,
                           HANDLER_NONE, dump_type, (HANDLE)NULL, NULL);
  return handler.WriteMinidump();
}

// static
bool ExceptionHandler::WriteMinidumpForChild(HANDLE child,
                                             DWORD child_blamed_thread,
                                             const wstring& dump_path,
                                             MinidumpCallback callback,
                                             void* callback_context,
                                             MINIDUMP_TYPE dump_type) {
  EXCEPTION_RECORD ex;
  CONTEXT ctx;
  EXCEPTION_POINTERS exinfo = { NULL, NULL };
  // As documented on MSDN, on failure SuspendThread returns (DWORD) -1
  const DWORD kFailedToSuspendThread = static_cast<DWORD>(-1);
  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, dump_type, (HANDLE)NULL, NULL);
  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;
#elif defined(_M_ARM64)
          exinfo->ContextRecord->Pc;
#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
