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

// ExceptionHandler can write a minidump file when an exception occurs,
// or when WriteMinidump() is called explicitly by your program.
//
// To have the exception handler write minidumps when an uncaught exception
// (crash) occurs, you should create an instance early in the execution
// of your program, and keep it around for the entire time you want to
// have crash handling active (typically, until shutdown).
//
// If you want to write minidumps without installing the exception handler,
// you can create an ExceptionHandler with install_handler set to false,
// then call WriteMinidump.  You can also use this technique if you want to
// use different minidump callbacks for different call sites.
//
// In either case, a callback function is called when a minidump is written,
// which receives the unqiue id of the minidump.  The caller can use this
// id to collect and write additional application state, and to launch an
// external crash-reporting application.
//
// It is important that creation and destruction of ExceptionHandler objects
// be nested cleanly, when using install_handler = true.
// Avoid the following pattern:
//   ExceptionHandler *e = new ExceptionHandler(...);
//   ExceptionHandler *f = new ExceptionHandler(...);
//   delete e;
// This will put the exception filter stack into an inconsistent state.

#ifndef CLIENT_WINDOWS_HANDLER_EXCEPTION_HANDLER_H__
#define CLIENT_WINDOWS_HANDLER_EXCEPTION_HANDLER_H__

#include <stdlib.h>
#include <windows.h>
#include <dbghelp.h>
#include <rpc.h>

#pragma warning(push)
// Disable exception handler warnings.
#pragma warning(disable:4530)

#include <list>
#include <string>
#include <vector>

#include "client/windows/common/ipc_protocol.h"
#include "client/windows/crash_generation/crash_generation_client.h"
#include "common/scoped_ptr.h"
#include "google_breakpad/common/minidump_format.h"

namespace google_breakpad {

using std::vector;
using std::wstring;

// These entries store a list of memory regions that the client wants included
// in the minidump.
struct AppMemory {
  ULONG64 ptr;
  ULONG length;

  bool operator==(const struct AppMemory& other) const {
    return ptr == other.ptr;
  }

  bool operator==(const void* other) const {
    return ptr == reinterpret_cast<ULONG64>(other);
  }
};
typedef std::list<AppMemory> AppMemoryList;

class ExceptionHandler {
 public:
  // A callback function to run before Breakpad performs any substantial
  // processing of an exception.  A FilterCallback is called before writing
  // a minidump.  context is the parameter supplied by the user as
  // callback_context when the handler was created.  exinfo points to the
  // exception record, if any; assertion points to assertion information,
  // if any.
  //
  // If a FilterCallback returns true, Breakpad will continue processing,
  // attempting to write a minidump.  If a FilterCallback returns false,
  // Breakpad will immediately report the exception as unhandled without
  // writing a minidump, allowing another handler the opportunity to handle it.
  typedef bool (*FilterCallback)(void* context, EXCEPTION_POINTERS* exinfo,
                                 MDRawAssertionInfo* assertion);

  // A callback function to run after the minidump has been written.
  // minidump_id is a unique id for the dump, so the minidump
  // file is <dump_path>\<minidump_id>.dmp.  context is the parameter supplied
  // by the user as callback_context when the handler was created.  exinfo
  // points to the exception record, or NULL if no exception occurred.
  // succeeded indicates whether a minidump file was successfully written.
  // assertion points to information about an assertion if the handler was
  // invoked by an assertion.
  //
  // If an exception occurred and the callback returns true, Breakpad will treat
  // the exception as fully-handled, suppressing any other handlers from being
  // notified of the exception.  If the callback returns false, Breakpad will
  // treat the exception as unhandled, and allow another handler to handle it.
  // If there are no other handlers, Breakpad will report the exception to the
  // system as unhandled, allowing a debugger or native crash dialog the
  // opportunity to handle the exception.  Most callback implementations
  // should normally return the value of |succeeded|, or when they wish to
  // not report an exception of handled, false.  Callbacks will rarely want to
  // return true directly (unless |succeeded| is true).
  //
  // For out-of-process dump generation, dump path and minidump ID will always
  // be NULL. In case of out-of-process dump generation, the dump path and
  // minidump id are controlled by the server process and are not communicated
  // back to the crashing process.
  typedef bool (*MinidumpCallback)(const wchar_t* dump_path,
                                   const wchar_t* minidump_id,
                                   void* context,
                                   EXCEPTION_POINTERS* exinfo,
                                   MDRawAssertionInfo* assertion,
                                   bool succeeded);

  // HandlerType specifies which types of handlers should be installed, if
  // any.  Use HANDLER_NONE for an ExceptionHandler that remains idle,
  // without catching any failures on its own.  This type of handler may
  // still be triggered by calling WriteMinidump.  Otherwise, use a
  // combination of the other HANDLER_ values, or HANDLER_ALL to install
  // all handlers.
  enum HandlerType {
    HANDLER_NONE = 0,
    HANDLER_EXCEPTION = 1 << 0,          // SetUnhandledExceptionFilter
    HANDLER_INVALID_PARAMETER = 1 << 1,  // _set_invalid_parameter_handler
    HANDLER_PURECALL = 1 << 2,           // _set_purecall_handler
    HANDLER_ALL = HANDLER_EXCEPTION |
                  HANDLER_INVALID_PARAMETER |
                  HANDLER_PURECALL
  };

  // Creates a new ExceptionHandler instance to handle writing minidumps.
  // Before writing a minidump, the optional filter callback will be called.
  // Its return value determines whether or not Breakpad should write a
  // minidump.  Minidump files will be written to dump_path, and the optional
  // callback is called after writing the dump file, as described above.
  // handler_types specifies the types of handlers that should be installed.
  ExceptionHandler(const wstring& dump_path,
                   FilterCallback filter,
                   MinidumpCallback callback,
                   void* callback_context,
                   int handler_types);

  // Creates a new ExceptionHandler instance that can attempt to perform
  // out-of-process dump generation if pipe_name is not NULL. If pipe_name is
  // NULL, or if out-of-process dump generation registration step fails,
  // in-process dump generation will be used. This also allows specifying
  // the dump type to generate.
  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);

  // As above, creates a new ExceptionHandler instance to perform
  // out-of-process dump generation if the given pipe_handle is not NULL.
  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);

  // ExceptionHandler that ENSURES out-of-process dump generation.  Expects a
  // crash generation client that is already registered with a crash generation
  // server.  Takes ownership of the passed-in crash_generation_client.
  //
  // Usage example:
  //   crash_generation_client = new CrashGenerationClient(..);
  //   if (crash_generation_client->Register()) {
  //     // Registration with the crash generation server succeeded.
  //     // Out-of-process dump generation is guaranteed.
  //     g_handler = new ExceptionHandler(.., crash_generation_client, ..);
  //     return true;
  //   }
  ExceptionHandler(const wstring& dump_path,
                   FilterCallback filter,
                   MinidumpCallback callback,
                   void* callback_context,
                   int handler_types,
                   CrashGenerationClient* crash_generation_client);

  ~ExceptionHandler();

  // Get and set the minidump path.
  wstring dump_path() const { return dump_path_; }
  void set_dump_path(const wstring &dump_path) {
    dump_path_ = dump_path;
    dump_path_c_ = dump_path_.c_str();
    UpdateNextID();  // Necessary to put dump_path_ in next_minidump_path_.
  }

  // Requests that a previously reported crash be uploaded.
  bool RequestUpload(DWORD crash_id);

  // Writes a minidump immediately.  This can be used to capture the
  // execution state independently of a crash.  Returns true on success.
  bool WriteMinidump();

  // Writes a minidump immediately, with the user-supplied exception
  // information.
  bool WriteMinidumpForException(EXCEPTION_POINTERS* exinfo);

  // Convenience form of WriteMinidump which does not require an
  // ExceptionHandler instance.
  static bool WriteMinidump(const wstring &dump_path,
                            MinidumpCallback callback, void* callback_context);

  // Write a minidump of |child| immediately.  This can be used to
  // capture the execution state of |child| independently of a crash.
  // Pass a meaningful |child_blamed_thread| to make that thread in
  // the child process the one from which a crash signature is
  // extracted.
  static bool WriteMinidumpForChild(HANDLE child,
                                    DWORD child_blamed_thread,
                                    const wstring& dump_path,
                                    MinidumpCallback callback,
                                    void* callback_context);

  // Get the thread ID of the thread requesting the dump (either the exception
  // thread or any other thread that called WriteMinidump directly).  This
  // may be useful if you want to include additional thread state in your
  // dumps.
  DWORD get_requesting_thread_id() const { return requesting_thread_id_; }

  // Controls behavior of EXCEPTION_BREAKPOINT and EXCEPTION_SINGLE_STEP.
  bool get_handle_debug_exceptions() const { return handle_debug_exceptions_; }
  void set_handle_debug_exceptions(bool handle_debug_exceptions) {
    handle_debug_exceptions_ = handle_debug_exceptions;
  }

  // Controls behavior of EXCEPTION_INVALID_HANDLE.
  bool get_consume_invalid_handle_exceptions() const {
    return consume_invalid_handle_exceptions_;
  }
  void set_consume_invalid_handle_exceptions(
      bool consume_invalid_handle_exceptions) {
    consume_invalid_handle_exceptions_ = consume_invalid_handle_exceptions;
  }

  // Returns whether out-of-process dump generation is used or not.
  bool IsOutOfProcess() const { return crash_generation_client_.get() != NULL; }

  // Calling RegisterAppMemory(p, len) causes len bytes starting
  // at address p to be copied to the minidump when a crash happens.
  void RegisterAppMemory(void* ptr, size_t length);
  void UnregisterAppMemory(void* ptr);

 private:
  friend class AutoExceptionHandler;

  // Initializes the instance with given values.
  void 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);

  // Function pointer type for MiniDumpWriteDump, which is looked up
  // dynamically.
  typedef BOOL (WINAPI *MiniDumpWriteDump_type)(
      HANDLE hProcess,
      DWORD dwPid,
      HANDLE hFile,
      MINIDUMP_TYPE DumpType,
      CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
      CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
      CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);

  // Function pointer type for UuidCreate, which is looked up dynamically.
  typedef RPC_STATUS (RPC_ENTRY *UuidCreate_type)(UUID* Uuid);

  // Runs the main loop for the exception handler thread.
  static DWORD WINAPI ExceptionHandlerThreadMain(void* lpParameter);

  // Called on the exception thread when an unhandled exception occurs.
  // Signals the exception handler thread to handle the exception.
  static LONG WINAPI HandleException(EXCEPTION_POINTERS* exinfo);

#if _MSC_VER >= 1400  // MSVC 2005/8
  // This function will be called by some CRT functions when they detect
  // that they were passed an invalid parameter.  Note that in _DEBUG builds,
  // the CRT may display an assertion dialog before calling this function,
  // and the function will not be called unless the assertion dialog is
  // dismissed by clicking "Ignore."
  static void HandleInvalidParameter(const wchar_t* expression,
                                     const wchar_t* function,
                                     const wchar_t* file,
                                     unsigned int line,
                                     uintptr_t reserved);
#endif  // _MSC_VER >= 1400

  // This function will be called by the CRT when a pure virtual
  // function is called.
  static void HandlePureVirtualCall();

  // This is called on the exception thread or on another thread that
  // the user wishes to produce a dump from.  It calls
  // WriteMinidumpWithException on the handler thread, avoiding stack
  // overflows and inconsistent dumps due to writing the dump from
  // the exception thread.  If the dump is requested as a result of an
  // exception, exinfo contains exception information, otherwise, it
  // is NULL.  If the dump is requested as a result of an assertion
  // (such as an invalid parameter being passed to a CRT function),
  // assertion contains data about the assertion, otherwise, it is NULL.
  bool WriteMinidumpOnHandlerThread(EXCEPTION_POINTERS* exinfo,
                                    MDRawAssertionInfo* assertion);

  // This function is called on the handler thread.  It calls into
  // WriteMinidumpWithExceptionForProcess() with a handle to the
  // current process.  requesting_thread_id is the ID of the thread
  // that requested the dump.  If the dump is requested as a result of
  // an exception, exinfo contains exception information, otherwise,
  // it is NULL.
  bool WriteMinidumpWithException(DWORD requesting_thread_id,
                                  EXCEPTION_POINTERS* exinfo,
                                  MDRawAssertionInfo* assertion);

  // This function is used as a callback when calling MinidumpWriteDump,
  // in order to add additional memory regions to the dump.
  static BOOL CALLBACK MinidumpWriteDumpCallback(
      PVOID context,
      const PMINIDUMP_CALLBACK_INPUT callback_input,
      PMINIDUMP_CALLBACK_OUTPUT callback_output);

  // This function does the actual writing of a minidump.  It is
  // called on the handler thread.  requesting_thread_id is the ID of
  // the thread that requested the dump, if that information is
  // meaningful.  If the dump is requested as a result of an
  // exception, exinfo contains exception information, otherwise, it
  // is NULL.  process is the one that will be dumped.  If
  // requesting_thread_id is meaningful and should be added to the
  // minidump, write_requester_stream is |true|.
  bool WriteMinidumpWithExceptionForProcess(DWORD requesting_thread_id,
                                            EXCEPTION_POINTERS* exinfo,
                                            MDRawAssertionInfo* assertion,
                                            HANDLE process,
                                            bool write_requester_stream);

  // Generates a new ID and stores it in next_minidump_id_, and stores the
  // path of the next minidump to be written in next_minidump_path_.
  void UpdateNextID();

  FilterCallback filter_;
  MinidumpCallback callback_;
  void* callback_context_;

  scoped_ptr<CrashGenerationClient> crash_generation_client_;

  // The directory in which a minidump will be written, set by the dump_path
  // argument to the constructor, or set_dump_path.
  wstring dump_path_;

  // The basename of the next minidump to be written, without the extension.
  wstring next_minidump_id_;

  // The full pathname of the next minidump to be written, including the file
  // extension.
  wstring next_minidump_path_;

  // Pointers to C-string representations of the above.  These are set when
  // the above wstring versions are set in order to avoid calling c_str during
  // an exception, as c_str may attempt to allocate heap memory.  These
  // pointers are not owned by the ExceptionHandler object, but their lifetimes
  // should be equivalent to the lifetimes of the associated wstring, provided
  // that the wstrings are not altered.
  const wchar_t* dump_path_c_;
  const wchar_t* next_minidump_id_c_;
  const wchar_t* next_minidump_path_c_;

  HMODULE dbghelp_module_;
  MiniDumpWriteDump_type minidump_write_dump_;
  MINIDUMP_TYPE dump_type_;

  HMODULE rpcrt4_module_;
  UuidCreate_type uuid_create_;

  // Tracks the handler types that were installed according to the
  // handler_types constructor argument.
  int handler_types_;

  // When installed_handler_ is true, previous_filter_ is the unhandled
  // exception filter that was set prior to installing ExceptionHandler as
  // the unhandled exception filter and pointing it to |this|.  NULL indicates
  // that there is no previous unhandled exception filter.
  LPTOP_LEVEL_EXCEPTION_FILTER previous_filter_;

#if _MSC_VER >= 1400  // MSVC 2005/8
  // Beginning in VC 8, the CRT provides an invalid parameter handler that will
  // be called when some CRT functions are passed invalid parameters.  In
  // earlier CRTs, the same conditions would cause unexpected behavior or
  // crashes.
  _invalid_parameter_handler previous_iph_;
#endif  // _MSC_VER >= 1400

  // The CRT allows you to override the default handler for pure
  // virtual function calls.
  _purecall_handler previous_pch_;

  // The exception handler thread.
  HANDLE handler_thread_;

  // True if the exception handler is being destroyed.
  // Starting with MSVC 2005, Visual C has stronger guarantees on volatile vars.
  // It has release semantics on write and acquire semantics on reads.
  // See the msdn documentation.
  volatile bool is_shutdown_;

  // The critical section enforcing the requirement that only one exception be
  // handled by a handler at a time.
  CRITICAL_SECTION handler_critical_section_;

  // Semaphores used to move exception handling between the exception thread
  // and the handler thread.  handler_start_semaphore_ is signalled by the
  // exception thread to wake up the handler thread when an exception occurs.
  // handler_finish_semaphore_ is signalled by the handler thread to wake up
  // the exception thread when handling is complete.
  HANDLE handler_start_semaphore_;
  HANDLE handler_finish_semaphore_;

  // The next 2 fields contain data passed from the requesting thread to
  // the handler thread.

  // The thread ID of the thread requesting the dump (either the exception
  // thread or any other thread that called WriteMinidump directly).
  DWORD requesting_thread_id_;

  // The exception info passed to the exception handler on the exception
  // thread, if an exception occurred.  NULL for user-requested dumps.
  EXCEPTION_POINTERS* exception_info_;

  // If the handler is invoked due to an assertion, this will contain a
  // pointer to the assertion information.  It is NULL at other times.
  MDRawAssertionInfo* assertion_;

  // The return value of the handler, passed from the handler thread back to
  // the requesting thread.
  bool handler_return_value_;

  // If true, the handler will intercept EXCEPTION_BREAKPOINT and
  // EXCEPTION_SINGLE_STEP exceptions.  Leave this false (the default)
  // to not interfere with debuggers.
  bool handle_debug_exceptions_;

  // If true, the handler will consume any EXCEPTION_INVALID_HANDLE exceptions.
  // Leave this false (the default) to handle these exceptions as normal.
  bool consume_invalid_handle_exceptions_;

  // Callers can request additional memory regions to be included in
  // the dump.
  AppMemoryList app_memory_info_;

  // A stack of ExceptionHandler objects that have installed unhandled
  // exception filters.  This vector is used by HandleException to determine
  // which ExceptionHandler object to route an exception to.  When an
  // ExceptionHandler is created with install_handler true, it will append
  // itself to this list.
  static vector<ExceptionHandler*>* handler_stack_;

  // The index of the ExceptionHandler in handler_stack_ that will handle the
  // next exception.  Note that 0 means the last entry in handler_stack_, 1
  // means the next-to-last entry, and so on.  This is used by HandleException
  // to support multiple stacked Breakpad handlers.
  static LONG handler_stack_index_;

  // handler_stack_critical_section_ guards operations on handler_stack_ and
  // handler_stack_index_. The critical section is initialized by the
  // first instance of the class and destroyed by the last instance of it.
  static CRITICAL_SECTION handler_stack_critical_section_;

  // The number of instances of this class.
  static volatile LONG instance_count_;

  // disallow copy ctor and operator=
  explicit ExceptionHandler(const ExceptionHandler &);
  void operator=(const ExceptionHandler &);
};

}  // namespace google_breakpad

#pragma warning(pop)

#endif  // CLIENT_WINDOWS_HANDLER_EXCEPTION_HANDLER_H__
