aboutsummaryrefslogtreecommitdiff
path: root/src/client/windows/crash_generation/client_info.cc
diff options
context:
space:
mode:
authorcdn@chromium.org <cdn@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2012-07-10 18:52:07 +0000
committercdn@chromium.org <cdn@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2012-07-10 18:52:07 +0000
commite05aab7b6bbf2e5ddb80c2f5a1192b97be6f4047 (patch)
treea99cab04e3b4463d50e11eea4a4c2a7cbc70544d /src/client/windows/crash_generation/client_info.cc
parentAdd Android NDK module definition + sample application (diff)
downloadbreakpad-e05aab7b6bbf2e5ddb80c2f5a1192b97be6f4047.tar.xz
Add the capability to include an arbitrary data stream within minidumps
This is supplied via a custom field "custom-data-stream" Review URL: https://breakpad.appspot.com/408002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@984 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client/windows/crash_generation/client_info.cc')
-rw-r--r--src/client/windows/crash_generation/client_info.cc45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/client/windows/crash_generation/client_info.cc b/src/client/windows/crash_generation/client_info.cc
index 60bbac82..294096f3 100644
--- a/src/client/windows/crash_generation/client_info.cc
+++ b/src/client/windows/crash_generation/client_info.cc
@@ -31,6 +31,8 @@
#include "client/windows/common/ipc_protocol.h"
static const wchar_t kCustomInfoProcessUptimeName[] = L"ptime";
+static const wchar_t kCustomDataStreamCustomFieldName[] = L"custom-data-stream";
+static const size_t kMaxCustomDataStreamSize = 100 * 1024 * 1024;
static const size_t kMaxCustomInfoEntries = 4096;
namespace google_breakpad {
@@ -48,6 +50,7 @@ ClientInfo::ClientInfo(CrashGenerationServer* crash_server,
ex_info_(ex_info),
assert_info_(assert_info),
custom_client_info_(custom_client_info),
+ custom_data_stream_(NULL),
thread_id_(thread_id),
process_handle_(NULL),
dump_requested_handle_(NULL),
@@ -86,6 +89,11 @@ bool ClientInfo::Initialize() {
}
ClientInfo::~ClientInfo() {
+ if (custom_data_stream_) {
+ delete custom_data_stream_;
+ custom_data_stream_ = NULL;
+ }
+
if (dump_request_wait_handle_) {
// Wait for callbacks that might already be running to finish.
UnregisterWaitEx(dump_request_wait_handle_, INVALID_HANDLE_VALUE);
@@ -199,6 +207,43 @@ bool ClientInfo::PopulateCustomInfo() {
return (bytes_count != read_count);
}
+bool ClientInfo::PopulateCustomDataStream() {
+ for (SIZE_T i = 0; i < custom_client_info_.count; ++i) {
+ if (_wcsicmp(kCustomDataStreamCustomFieldName,
+ custom_client_info_.entries[i].name) != 0) {
+ continue;
+ }
+ wchar_t address_str[CustomInfoEntry::kValueMaxLength];
+ memcpy(address_str, custom_client_info_.entries[i].value,
+ CustomInfoEntry::kValueMaxLength);
+ wchar_t* size_str = wcschr(address_str, ':');
+ if (!size_str)
+ return false;
+
+ size_str[0] = 0;
+ ++size_str;
+ void* address = reinterpret_cast<void*>(_wcstoi64(address_str, NULL, 16));
+ long size = wcstol(size_str, NULL, 16);
+ if (size <= 0 || size > kMaxCustomDataStreamSize)
+ return false;
+
+ custom_data_stream_ = reinterpret_cast<CustomDataStream*>(
+ new u_int8_t[sizeof(CustomDataStream) + size - 1]);
+
+ SIZE_T bytes_count = 0;
+ if (!ReadProcessMemory(process_handle_, address,
+ custom_data_stream_->stream, size, &bytes_count)) {
+ delete custom_data_stream_;
+ custom_data_stream_ = NULL;
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
CustomClientInfo ClientInfo::GetCustomInfo() const {
CustomClientInfo custom_info;
custom_info.entries = custom_info_entries_.get();