diff options
author | ted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2012-07-19 22:03:39 +0000 |
---|---|---|
committer | ted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2012-07-19 22:03:39 +0000 |
commit | 2f56276fbfe519913845565f178cfa385da93657 (patch) | |
tree | f031e25d09fd0ec8bdb7fc8837979ae4f2bf1982 /src/client/windows/handler | |
parent | Add some more DWARF ARM register numbers to the DWARF CFI register maps (diff) | |
download | breakpad-2f56276fbfe519913845565f178cfa385da93657.tar.xz |
Allow adding extra memory regions to minidump on linux/windows
A=Bill McCloskey <wmccloskey@mozilla.com> R=ted at https://bugzilla.mozilla.org/show_bug.cgi?id=662646
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@989 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client/windows/handler')
-rwxr-xr-x[-rw-r--r--] | src/client/windows/handler/exception_handler.cc | 60 | ||||
-rw-r--r-- | src/client/windows/handler/exception_handler.h | 20 |
2 files changed, 62 insertions, 18 deletions
diff --git a/src/client/windows/handler/exception_handler.cc b/src/client/windows/handler/exception_handler.cc index 6e5b724a..9ede97f0 100644..100755 --- a/src/client/windows/handler/exception_handler.cc +++ b/src/client/windows/handler/exception_handler.cc @@ -46,9 +46,7 @@ static const int kExceptionHandlerThreadInitialStackSize = 64 * 1024; // This is passed as the context to the MinidumpWriteDump callback. typedef struct { - ULONG64 memory_base; - ULONG memory_size; - bool finished; + AppMemoryList::const_iterator iter, end; } MinidumpCallbackContext; vector<ExceptionHandler*>* ExceptionHandler::handler_stack_ = NULL; @@ -220,6 +218,9 @@ void ExceptionHandler::Initialize(const wstring& dump_path, set_dump_path(dump_path); } + // Reserve one element for the instruction memory + app_memory_info_.push_back(AppMemory(0, 0)); + // 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 @@ -795,9 +796,6 @@ bool ExceptionHandler::WriteMinidumpWithException( ++user_streams.UserStreamCount; } - MINIDUMP_CALLBACK_INFORMATION callback; - MinidumpCallbackContext context; - MINIDUMP_CALLBACK_INFORMATION* callback_pointer = NULL; // 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. @@ -822,23 +820,33 @@ bool ExceptionHandler::WriteMinidumpWithException( // pointer, but settle for whatever's available up to the // boundaries of the memory region. const ULONG64 kIPMemorySize = 256; - context.memory_base = + 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); - context.memory_size = - static_cast<ULONG>(end_of_range - context.memory_base); + ULONG size = static_cast<ULONG>(end_of_range - base); - context.finished = false; - callback.CallbackRoutine = MinidumpWriteDumpCallback; - callback.CallbackParam = reinterpret_cast<void*>(&context); - callback_pointer = &callback; + 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_(GetCurrentProcess(), GetCurrentProcessId(), @@ -846,7 +854,7 @@ bool ExceptionHandler::WriteMinidumpWithException( dump_type_, exinfo ? &except_info : NULL, &user_streams, - callback_pointer) == TRUE); + &callback) == TRUE); CloseHandle(dump_file); } @@ -874,13 +882,13 @@ BOOL CALLBACK ExceptionHandler::MinidumpWriteDumpCallback( case MemoryCallback: { MinidumpCallbackContext* callback_context = reinterpret_cast<MinidumpCallbackContext*>(context); - if (callback_context->finished) + if (callback_context->iter == callback_context->end) return FALSE; // Include the specified memory region. - callback_output->MemoryBase = callback_context->memory_base; - callback_output->MemorySize = callback_context->memory_size; - callback_context->finished = true; + callback_output->MemoryBase = callback_context->iter->ptr; + callback_output->MemorySize = callback_context->iter->length; + callback_context->iter++; return TRUE; } @@ -924,4 +932,20 @@ void ExceptionHandler::UpdateNextID() { next_minidump_path_c_ = next_minidump_path_.c_str(); } +void ExceptionHandler::RegisterAppMemory(void *ptr, size_t length) { + app_memory_info_.push_back(AppMemory(reinterpret_cast<ULONG64>(ptr), + static_cast<ULONG>(length))); +} + +void ExceptionHandler::UnregisterAppMemory(void *ptr) { + for (AppMemoryList::iterator iter = app_memory_info_.begin(); + iter != app_memory_info_.end(); + ++iter) { + if (iter->ptr == reinterpret_cast<ULONG64>(ptr)) { + app_memory_info_.erase(iter); + return; + } + } +} + } // namespace google_breakpad diff --git a/src/client/windows/handler/exception_handler.h b/src/client/windows/handler/exception_handler.h index 09f5177c..38c2c3ca 100644 --- a/src/client/windows/handler/exception_handler.h +++ b/src/client/windows/handler/exception_handler.h @@ -67,6 +67,7 @@ #include <string> #include <vector> +#include <list> #include "client/windows/common/ipc_protocol.h" #include "client/windows/crash_generation/crash_generation_client.h" @@ -78,6 +79,16 @@ 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 { + AppMemory(ULONG64 ptr, ULONG length) : ptr(ptr), length(length) {} + + ULONG64 ptr; + ULONG length; +}; +typedef std::list<AppMemory> AppMemoryList; + class ExceptionHandler { public: // A callback function to run before Breakpad performs any substantial @@ -219,6 +230,11 @@ class ExceptionHandler { // 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; @@ -404,6 +420,10 @@ class ExceptionHandler { // to not interfere with debuggers. bool handle_debug_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 |