diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc index 8406ffe4..91610c03 100644 --- a/src/client/linux/minidump_writer/minidump_writer.cc +++ b/src/client/linux/minidump_writer/minidump_writer.cc @@ -75,6 +75,7 @@ #include "client/linux/minidump_writer/proc_cpuinfo_reader.h" #include "client/minidump_file_writer.h" #include "common/linux/linux_libc_support.h" +#include "common/minidump_type_helper.h" #include "google_breakpad/common/minidump_format.h" #include "third_party/lss/linux_syscall_support.h" @@ -86,6 +87,7 @@ using google_breakpad::CpuSet; using google_breakpad::LineReader; using google_breakpad::LinuxDumper; using google_breakpad::LinuxPtraceDumper; +using google_breakpad::MDTypeHelper; using google_breakpad::MappingEntry; using google_breakpad::MappingInfo; using google_breakpad::MappingList; @@ -100,6 +102,8 @@ using google_breakpad::UContextReader; using google_breakpad::UntypedMDRVA; using google_breakpad::wasteful_vector; +typedef MDTypeHelper::MDRawDebug MDRawDebug; +typedef MDTypeHelper::MDRawLinkMap MDRawLinkMap; class MinidumpWriter { public: @@ -733,8 +737,8 @@ class MinidumpWriter { return false; MDRawLinkMap entry; entry.name = location.rva; - entry.addr = reinterpret_cast(map.l_addr); - entry.ld = reinterpret_cast(map.l_ld); + entry.addr = map.l_addr; + entry.ld = reinterpret_cast(map.l_ld); linkmap.CopyIndex(idx++, &entry); } } @@ -750,9 +754,9 @@ class MinidumpWriter { debug.get()->version = debug_entry.r_version; debug.get()->map = linkmap_rva; debug.get()->dso_count = dso_count; - debug.get()->brk = reinterpret_cast(debug_entry.r_brk); - debug.get()->ldbase = reinterpret_cast(debug_entry.r_ldbase); - debug.get()->dynamic = dynamic; + debug.get()->brk = debug_entry.r_brk; + debug.get()->ldbase = debug_entry.r_ldbase; + debug.get()->dynamic = reinterpret_cast(dynamic); wasteful_vector dso_debug_data(dumper_->allocator(), dynamic_length); // The passed-in size to the constructor (above) is only a hint. diff --git a/src/common/minidump_type_helper.h b/src/common/minidump_type_helper.h new file mode 100644 index 00000000..5a7d5a6a --- /dev/null +++ b/src/common/minidump_type_helper.h @@ -0,0 +1,56 @@ +// Copyright (c) 2014, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_TYPE_HELPER_H_ +#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_TYPE_HELPER_H_ + +#include + +#include "google_breakpad/common/minidump_format.h" + +namespace google_breakpad { + +template +struct MDTypeHelper; + +template <> +struct MDTypeHelper { + typedef MDRawDebug32 MDRawDebug; + typedef MDRawLinkMap32 MDRawLinkMap; +}; + +template <> +struct MDTypeHelper { + typedef MDRawDebug64 MDRawDebug; + typedef MDRawLinkMap64 MDRawLinkMap; +}; + +} // namespace google_breakpad + +#endif // GOOGLE_BREAKPAD_COMMON_MINIDUMP_TYPE_HELPER_H_ diff --git a/src/google_breakpad/common/minidump_format.h b/src/google_breakpad/common/minidump_format.h index 109c72e6..17a5abba 100644 --- a/src/google_breakpad/common/minidump_format.h +++ b/src/google_breakpad/common/minidump_format.h @@ -342,7 +342,7 @@ typedef enum { MD_LINUX_ENVIRON = 0x47670007, /* /proc/$x/environ */ MD_LINUX_AUXV = 0x47670008, /* /proc/$x/auxv */ MD_LINUX_MAPS = 0x47670009, /* /proc/$x/maps */ - MD_LINUX_DSO_DEBUG = 0x4767000A /* MDRawDebug */ + MD_LINUX_DSO_DEBUG = 0x4767000A /* MDRawDebug{32,64} */ } MDStreamType; /* MINIDUMP_STREAM_TYPE */ @@ -930,21 +930,39 @@ typedef enum { } MDAssertionInfoData; /* These structs are used to store the DSO debug data in Linux minidumps, - * which is necessary for converting minidumps to usable coredumps. */ + * which is necessary for converting minidumps to usable coredumps. + * Because of a historical accident, several fields are variably encoded + * according to client word size, so tools potentially need to support both. */ + typedef struct { - void* addr; + uint32_t addr; MDRVA name; - void* ld; -} MDRawLinkMap; + uint32_t ld; +} MDRawLinkMap32; typedef struct { uint32_t version; - MDRVA map; + MDRVA map; /* array of MDRawLinkMap32 */ uint32_t dso_count; - void* brk; - void* ldbase; - void* dynamic; -} MDRawDebug; + uint32_t brk; + uint32_t ldbase; + uint32_t dynamic; +} MDRawDebug32; + +typedef struct { + uint64_t addr; + MDRVA name; + uint64_t ld; +} MDRawLinkMap64; + +typedef struct { + uint32_t version; + MDRVA map; /* array of MDRawLinkMap64 */ + uint32_t dso_count; + uint64_t brk; + uint64_t ldbase; + uint64_t dynamic; +} MDRawDebug64; #if defined(_MSC_VER) #pragma warning(pop) diff --git a/src/tools/linux/md2core/minidump-2-core.cc b/src/tools/linux/md2core/minidump-2-core.cc index 815e6e75..82007604 100644 --- a/src/tools/linux/md2core/minidump-2-core.cc +++ b/src/tools/linux/md2core/minidump-2-core.cc @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -47,6 +48,7 @@ #include #include "common/linux/memory_mapped_file.h" +#include "common/minidump_type_helper.h" #include "common/scoped_ptr.h" #include "google_breakpad/common/minidump_format.h" #include "third_party/lss/linux_syscall_support.h" @@ -81,9 +83,13 @@ typedef user_regs user_regs_struct; #endif +using google_breakpad::MDTypeHelper; using google_breakpad::MemoryMappedFile; using google_breakpad::MinidumpMemoryRange; +typedef MDTypeHelper::MDRawDebug MDRawDebug; +typedef MDTypeHelper::MDRawLinkMap MDRawLinkMap; + static const MDRVA kInvalidMDRVA = static_cast(-1); static bool verbose; static std::string g_custom_so_basedir; @@ -691,14 +697,14 @@ ParseDSODebugInfo(CrashedProcess* crashinfo, const MinidumpMemoryRange& range, "MD_LINUX_DSO_DEBUG:\n" "Version: %d\n" "Number of DSOs: %d\n" - "Brk handler: %p\n" - "Dynamic loader at: %p\n" - "_DYNAMIC: %p\n", + "Brk handler: 0x%" PRIx64 "\n" + "Dynamic loader at: 0x%" PRIx64 "\n" + "_DYNAMIC: 0x%" PRIx64 "\n", debug->version, debug->dso_count, - debug->brk, - debug->ldbase, - debug->dynamic); + static_cast(debug->brk), + static_cast(debug->ldbase), + static_cast(debug->dynamic)); } crashinfo->debug = *debug; if (range.length() > sizeof(MDRawDebug)) { @@ -713,8 +719,9 @@ ParseDSODebugInfo(CrashedProcess* crashinfo, const MinidumpMemoryRange& range, if (link_map) { if (verbose) { fprintf(stderr, - "#%03d: %p, %p, \"%s\"\n", - i, link_map->addr, link_map->ld, + "#%03d: %" PRIx64 ", %" PRIx64 ", \"%s\"\n", + i, static_cast(link_map->addr), + static_cast(link_map->ld), full_file.GetAsciiMDString(link_map->name).c_str()); } crashinfo->link_map.push_back(*link_map);