From 2f56276fbfe519913845565f178cfa385da93657 Mon Sep 17 00:00:00 2001 From: "ted.mielczarek" Date: Thu, 19 Jul 2012 22:03:39 +0000 Subject: Allow adding extra memory regions to minidump on linux/windows A=Bill McCloskey 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 --- src/client/linux/handler/exception_handler.cc | 18 +++++++++- src/client/linux/handler/exception_handler.h | 11 ++++++ .../linux/handler/exception_handler_unittest.cc | 39 ++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) (limited to 'src/client/linux/handler') 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//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(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; +} -- cgit v1.2.1