diff options
author | cdn@chromium.org <cdn@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2012-07-10 18:52:07 +0000 |
---|---|---|
committer | cdn@chromium.org <cdn@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2012-07-10 18:52:07 +0000 |
commit | e05aab7b6bbf2e5ddb80c2f5a1192b97be6f4047 (patch) | |
tree | a99cab04e3b4463d50e11eea4a4c2a7cbc70544d /src/client/windows/crash_generation/client_info.cc | |
parent | Add Android NDK module definition + sample application (diff) | |
download | breakpad-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.cc | 45 |
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(); |