aboutsummaryrefslogtreecommitdiff
path: root/src/client/linux/handler
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/linux/handler')
-rw-r--r--src/client/linux/handler/exception_handler.cc18
-rw-r--r--src/client/linux/handler/exception_handler.h11
-rw-r--r--src/client/linux/handler/exception_handler_unittest.cc39
3 files changed, 67 insertions, 1 deletions
diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
index f505ff33..fffc3e64 100644
--- a/src/client/linux/handler/exception_handler.cc
+++ b/src/client/linux/handler/exception_handler.cc
@@ -465,7 +465,8 @@ bool ExceptionHandler::DoDump(pid_t crashing_process, const void* context,
crashing_process,
context,
context_size,
- mapping_list_);
+ mapping_list_,
+ app_memory_list_);
}
// static
@@ -515,4 +516,19 @@ void ExceptionHandler::AddMappingInfo(const string& name,
mapping_list_.push_back(mapping);
}
+void ExceptionHandler::RegisterAppMemory(void *ptr, size_t length) {
+ app_memory_list_.push_back(AppMemory(ptr, length));
+}
+
+void ExceptionHandler::UnregisterAppMemory(void *ptr) {
+ for (AppMemoryList::iterator iter = app_memory_list_.begin();
+ iter != app_memory_list_.end();
+ ++iter) {
+ if (iter->ptr == ptr) {
+ app_memory_list_.erase(iter);
+ return;
+ }
+ }
+}
+
} // namespace google_breakpad
diff --git a/src/client/linux/handler/exception_handler.h b/src/client/linux/handler/exception_handler.h
index 4bc8ba72..fab74d28 100644
--- a/src/client/linux/handler/exception_handler.h
+++ b/src/client/linux/handler/exception_handler.h
@@ -194,6 +194,13 @@ class ExceptionHandler {
size_t mapping_size,
size_t file_offset);
+ // Register a block of memory of len bytes starting at address p
+ // to be copied to the minidump when a crash happens.
+ void RegisterAppMemory(void *ptr, size_t length);
+
+ // Unregister a block of memory that was registered with RegisterAppMemory.
+ void UnregisterAppMemory(void *ptr);
+
private:
void Init(const string &dump_path,
const int server_fd);
@@ -252,6 +259,10 @@ class ExceptionHandler {
// Callers can add extra info about mappings for cases where the
// dumper code cannot extract enough information from /proc/<pid>/maps.
MappingList mapping_list_;
+
+ // Callers can request additional memory regions to be included in
+ // the dump.
+ AppMemoryList app_memory_list_;
};
} // namespace google_breakpad
diff --git a/src/client/linux/handler/exception_handler_unittest.cc b/src/client/linux/handler/exception_handler_unittest.cc
index f9314729..2bad5fb5 100644
--- a/src/client/linux/handler/exception_handler_unittest.cc
+++ b/src/client/linux/handler/exception_handler_unittest.cc
@@ -785,3 +785,42 @@ TEST(ExceptionHandlerTest, ExternalDumper) {
ASSERT_GT(st.st_size, 0u);
unlink(templ.c_str());
}
+
+// Test that an additional memory region can be added to the minidump.
+TEST(ExceptionHandlerTest, AdditionalMemory) {
+ const u_int32_t kMemorySize = sysconf(_SC_PAGESIZE);
+ // Get some heap memory.
+ u_int8_t* memory = new u_int8_t[kMemorySize];
+ const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory);
+ ASSERT_TRUE(memory);
+ // Stick some data into the memory so the contents can be verified.
+ for (unsigned int i = 0; i < kMemorySize; ++i) {
+ memory[i] = i % 255;
+ }
+
+ string minidump_filename;
+ AutoTempDir temp_dir;
+ ExceptionHandler handler(temp_dir.path(), NULL, SimpleCallback,
+ (void*)&minidump_filename, true);
+ // Add the memory region to the list of memory to be included.
+ handler.RegisterAppMemory(memory, kMemorySize);
+ handler.WriteMinidump();
+
+ // Read the minidump. Ensure that the memory region is present
+ Minidump minidump(minidump_filename);
+ ASSERT_TRUE(minidump.Read());
+
+ MinidumpMemoryList* dump_memory_list = minidump.GetMemoryList();
+ ASSERT_TRUE(dump_memory_list);
+ const MinidumpMemoryRegion* region =
+ dump_memory_list->GetMemoryRegionForAddress(kMemoryAddress);
+ ASSERT_TRUE(region);
+
+ EXPECT_EQ(kMemoryAddress, region->GetBase());
+ EXPECT_EQ(kMemorySize, region->GetSize());
+
+ // Verify memory contents.
+ EXPECT_EQ(0, memcmp(region->GetMemory(), memory, kMemorySize));
+
+ delete[] memory;
+}