From ef7262d4775bf6de750bc2a26dbf98368d7ec0c3 Mon Sep 17 00:00:00 2001 From: "ted.mielczarek" Date: Mon, 13 Dec 2010 22:10:23 +0000 Subject: allow passing info about known memory mappings to MinidumpWriter and ExceptionHandler r=thestig at http://breakpad.appspot.com/242001/show git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@741 4c0a9323-5329-0410-9bdc-e9ce6186880e --- .../linux/handler/exception_handler_unittest.cc | 86 ++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'src/client/linux/handler/exception_handler_unittest.cc') diff --git a/src/client/linux/handler/exception_handler_unittest.cc b/src/client/linux/handler/exception_handler_unittest.cc index 988de063..67c05f6b 100644 --- a/src/client/linux/handler/exception_handler_unittest.cc +++ b/src/client/linux/handler/exception_handler_unittest.cc @@ -42,6 +42,7 @@ #include "client/linux/handler/exception_handler.h" #include "client/linux/minidump_writer/minidump_writer.h" #include "common/linux/eintr_wrapper.h" +#include "common/linux/file_id.h" #include "common/linux/linux_libc_support.h" #include "third_party/lss/linux_syscall_support.h" #include "google_breakpad/processor/minidump.h" @@ -54,6 +55,10 @@ using namespace google_breakpad; #define TEMPDIR "/data/local/tmp" #endif +// Length of a formatted GUID string = +// sizeof(MDGUID) * 2 + 4 (for dashes) + 1 (null terminator) +const int kGUIDStringSize = 37; + static void sigchld_handler(int signo) { } class ExceptionHandlerTest : public ::testing::Test { @@ -573,6 +578,87 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryNullPointer) { free(filename); } +static bool SimpleCallback(const char* dump_path, + const char* minidump_id, + void* context, + bool succeeded) { + if (!succeeded) + return succeeded; + + string* minidump_file = reinterpret_cast(context); + minidump_file->append(dump_path); + minidump_file->append("/"); + minidump_file->append(minidump_id); + minidump_file->append(".dmp"); + return true; +} + +// Test that anonymous memory maps can be annotated with names and IDs. +TEST(ExceptionHandlerTest, ModuleInfo) { + // These are defined here so the parent can use them to check the + // data from the minidump afterwards. + const u_int32_t kMemorySize = sysconf(_SC_PAGESIZE); + const char* kMemoryName = "a fake module"; + const u_int8_t kModuleGUID[sizeof(MDGUID)] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + }; + char module_identifier_buffer[kGUIDStringSize]; + FileID::ConvertIdentifierToString(kModuleGUID, + module_identifier_buffer, + sizeof(module_identifier_buffer)); + string module_identifier(module_identifier_buffer); + // Strip out dashes + size_t pos; + while ((pos = module_identifier.find('-')) != string::npos) { + module_identifier.erase(pos, 1); + } + // And append a zero, because module IDs include an "age" field + // which is always zero on Linux. + module_identifier += "0"; + + // Get some memory. + char* memory = + reinterpret_cast(mmap(NULL, + kMemorySize, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, + -1, + 0)); + const u_int64_t kMemoryAddress = reinterpret_cast(memory); + ASSERT_TRUE(memory); + + string minidump_filename; + ExceptionHandler handler(TEMPDIR, NULL, SimpleCallback, + (void*)&minidump_filename, true); + // Add info about the anonymous memory mapping. + handler.AddMappingInfo(kMemoryName, + kModuleGUID, + kMemoryAddress, + kMemorySize, + 0); + handler.WriteMinidump(); + + // Read the minidump. Load the module list, and ensure that + // the mmap'ed |memory| is listed with the given module name + // and debug ID. + Minidump minidump(minidump_filename); + ASSERT_TRUE(minidump.Read()); + + MinidumpModuleList* module_list = minidump.GetModuleList(); + ASSERT_TRUE(module_list); + const MinidumpModule* module = + module_list->GetModuleForAddress(kMemoryAddress); + ASSERT_TRUE(module); + + EXPECT_EQ(kMemoryAddress, module->base_address()); + EXPECT_EQ(kMemorySize, module->size()); + EXPECT_EQ(kMemoryName, module->code_file()); + EXPECT_EQ(module_identifier, module->debug_identifier()); + + unlink(minidump_filename.c_str()); +} + static const unsigned kControlMsgSize = CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred)); -- cgit v1.2.1