aboutsummaryrefslogtreecommitdiff
path: root/src/client/windows/handler/exception_handler.cc
diff options
context:
space:
mode:
authorted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2012-09-18 13:54:58 +0000
committerted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2012-09-18 13:54:58 +0000
commit61d9b9ff9626bf57c68a12c53c6e4804b8ef93d8 (patch)
treec85f99a0216bb237a36c59af6f196ca79e91e418 /src/client/windows/handler/exception_handler.cc
parentChange an always true comparison to another conditional. Since (diff)
downloadbreakpad-61d9b9ff9626bf57c68a12c53c6e4804b8ef93d8.tar.xz
Allow adding extra memory regions to minidump on linux/windows
A=Bill McCloskey <wmccloskey@mozilla.com>, ted, original patch from https://bugzilla.mozilla.org/show_bug.cgi?id=662646 R=mark at https://breakpad.appspot.com/450002/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1041 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client/windows/handler/exception_handler.cc')
-rw-r--r--src/client/windows/handler/exception_handler.cc71
1 files changed, 53 insertions, 18 deletions
diff --git a/src/client/windows/handler/exception_handler.cc b/src/client/windows/handler/exception_handler.cc
index 6e5b724a..4b0c2917 100644
--- a/src/client/windows/handler/exception_handler.cc
+++ b/src/client/windows/handler/exception_handler.cc
@@ -46,9 +46,8 @@ 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;
+ AppMemoryList::const_iterator end;
} MinidumpCallbackContext;
vector<ExceptionHandler*>* ExceptionHandler::handler_stack_ = NULL;
@@ -220,6 +219,12 @@ void ExceptionHandler::Initialize(const wstring& dump_path,
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
@@ -795,9 +800,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 +824,34 @@ 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 +859,7 @@ bool ExceptionHandler::WriteMinidumpWithException(
dump_type_,
exinfo ? &except_info : NULL,
&user_streams,
- callback_pointer) == TRUE);
+ &callback) == TRUE);
CloseHandle(dump_file);
}
@@ -874,13 +887,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 +937,26 @@ void ExceptionHandler::UpdateNextID() {
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