From 2e0e2234b9e9d7d82c4c3c20396bdf8f18007e6c Mon Sep 17 00:00:00 2001 From: mmentovai Date: Thu, 31 May 2007 19:44:52 +0000 Subject: [PATCH] Allow building with -pedantic (#186). r=ted.mielczarek http://groups.google.com/group/google-breakpad-dev/browse_thread/thread/6aa39d7f0ffa3c42 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@183 4c0a9323-5329-0410-9bdc-e9ce6186880e --- Makefile.am | 1 + Makefile.in | 1 + src/client/minidump_file_writer-inl.h | 18 +-- src/client/minidump_file_writer.h | 4 +- src/common/linux/guid_creator.cc | 2 +- src/google_breakpad/common/minidump_format.h | 65 +++++++---- src/google_breakpad/common/minidump_size.h | 107 ++++++++++++++++++ .../processor/minidump_processor.h | 6 +- .../processor/symbol_supplier.h | 2 +- src/processor/logging.h | 2 +- src/processor/minidump.cc | 38 +++---- src/processor/minidump_stackwalk.cc | 10 +- 12 files changed, 193 insertions(+), 63 deletions(-) create mode 100644 src/google_breakpad/common/minidump_size.h diff --git a/Makefile.am b/Makefile.am index c78c1293..128bba01 100644 --- a/Makefile.am +++ b/Makefile.am @@ -52,6 +52,7 @@ lib_LTLIBRARIES = src/libbreakpad.la src_libbreakpad_la_SOURCES = \ src/google_breakpad/common/breakpad_types.h \ src/google_breakpad/common/minidump_format.h \ + src/google_breakpad/common/minidump_size.h \ src/google_breakpad/processor/basic_source_line_resolver.h \ src/google_breakpad/processor/call_stack.h \ src/google_breakpad/processor/code_module.h \ diff --git a/Makefile.in b/Makefile.in index c6283f55..cb0e6343 100644 --- a/Makefile.in +++ b/Makefile.in @@ -380,6 +380,7 @@ lib_LTLIBRARIES = src/libbreakpad.la src_libbreakpad_la_SOURCES = \ src/google_breakpad/common/breakpad_types.h \ src/google_breakpad/common/minidump_format.h \ + src/google_breakpad/common/minidump_size.h \ src/google_breakpad/processor/basic_source_line_resolver.h \ src/google_breakpad/processor/call_stack.h \ src/google_breakpad/processor/code_module.h \ diff --git a/src/client/minidump_file_writer-inl.h b/src/client/minidump_file_writer-inl.h index 4505b4f2..7c556a27 100644 --- a/src/client/minidump_file_writer-inl.h +++ b/src/client/minidump_file_writer-inl.h @@ -37,26 +37,27 @@ #include #include "client/minidump_file_writer.h" +#include "google_breakpad/common/minidump_size.h" namespace google_breakpad { template inline bool TypedMDRVA::Allocate() { allocation_state_ = SINGLE_OBJECT; - return UntypedMDRVA::Allocate(sizeof(MDType)); + return UntypedMDRVA::Allocate(minidump_size::size()); } template inline bool TypedMDRVA::Allocate(size_t additional) { allocation_state_ = SINGLE_OBJECT; - return UntypedMDRVA::Allocate(sizeof(MDType) + additional); + return UntypedMDRVA::Allocate(minidump_size::size() + additional); } template inline bool TypedMDRVA::AllocateArray(size_t count) { assert(count); allocation_state_ = ARRAY; - return UntypedMDRVA::Allocate(sizeof(MDType) * count); + return UntypedMDRVA::Allocate(minidump_size::size() * count); } template @@ -64,14 +65,14 @@ inline bool TypedMDRVA::AllocateObjectAndArray(unsigned int count, size_t size) { assert(count && size); allocation_state_ = SINGLE_OBJECT_WITH_ARRAY; - return UntypedMDRVA::Allocate(sizeof(MDType) + count * size); + return UntypedMDRVA::Allocate(minidump_size::size() + count * size); } template inline bool TypedMDRVA::CopyIndex(unsigned int index, MDType *item) { assert(allocation_state_ == ARRAY); - return writer_->Copy(position_ + index * sizeof(MDType), item, - sizeof(MDType)); + return writer_->Copy(position_ + index * minidump_size::size(), item, + minidump_size::size()); } template @@ -79,12 +80,13 @@ inline bool TypedMDRVA::CopyIndexAfterObject(unsigned int index, const void *src, size_t size) { assert(allocation_state_ == SINGLE_OBJECT_WITH_ARRAY); - return writer_->Copy(position_ + sizeof(MDType) + index * size, src, size); + return writer_->Copy(position_ + minidump_size::size() + index * size, + src, size); } template inline bool TypedMDRVA::Flush() { - return writer_->Copy(position_, &data_, sizeof(MDType)); + return writer_->Copy(position_, &data_, minidump_size::size()); } } // namespace google_breakpad diff --git a/src/client/minidump_file_writer.h b/src/client/minidump_file_writer.h index 39fc90b8..f569a553 100644 --- a/src/client/minidump_file_writer.h +++ b/src/client/minidump_file_writer.h @@ -200,12 +200,12 @@ class TypedMDRVA : public UntypedMDRVA { // alter its contents. MDType *get() { return &data_; } - // Allocates sizeof(MDType) bytes. + // Allocates minidump_size::size() bytes. // Must not call more than once. // Return true on success, or false on failure bool Allocate(); - // Allocates sizeof(MDType) + |additional| bytes. + // Allocates minidump_size::size() + |additional| bytes. // Must not call more than once. // Return true on success, or false on failure bool Allocate(size_t additional); diff --git a/src/common/linux/guid_creator.cc b/src/common/linux/guid_creator.cc index d6d4a5bb..d133c6b0 100644 --- a/src/common/linux/guid_creator.cc +++ b/src/common/linux/guid_creator.cc @@ -64,7 +64,7 @@ const GUIDGenerator kGuidGenerator; bool CreateGUID(GUID *guid) { return kGuidGenerator.CreateGUID(guid); -}; +} // Parse guid to string. bool GUIDToString(const GUID *guid, char *buf, int buf_len) { diff --git a/src/google_breakpad/common/minidump_format.h b/src/google_breakpad/common/minidump_format.h index 9606dff9..bf95d7d0 100644 --- a/src/google_breakpad/common/minidump_format.h +++ b/src/google_breakpad/common/minidump_format.h @@ -44,6 +44,12 @@ * writing affected structures, MD_*_SIZE macros are provided where needed, * containing the useful size of the structures without padding. * + * Structures that are defined by Microsoft to contain a zero-length array + * are instead defined here to contain an array with one element, as + * zero-length arrays are forbidden by standard C and C++. In these cases, + * *_minsize constants are provided to be used in place of sizeof. For a + * cleaner interface to these sizes when using C++, see minidump_size.h. + * * These structures are also sufficient to populate minidump files. * * These definitions may be extended to support handling minidump files @@ -67,6 +73,7 @@ #ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_FORMAT_H__ #define GOOGLE_BREAKPAD_COMMON_MINIDUMP_FORMAT_H__ +#include #include "google_breakpad/common/breakpad_types.h" @@ -502,9 +509,11 @@ typedef enum { typedef struct { u_int32_t length; /* Length of buffer in bytes (not characters), * excluding 0-terminator */ - u_int16_t buffer[0]; /* UTF-16-encoded, 0-terminated */ + u_int16_t buffer[1]; /* UTF-16-encoded, 0-terminated */ } MDString; /* MINIDUMP_STRING */ +static const size_t MDString_minsize = offsetof(MDString, buffer[0]); + typedef struct { u_int32_t thread_id; @@ -519,9 +528,12 @@ typedef struct { typedef struct { u_int32_t number_of_threads; - MDRawThread threads[0]; + MDRawThread threads[1]; } MDRawThreadList; /* MINIDUMP_THREAD_LIST */ +static const size_t MDRawThreadList_minsize = offsetof(MDRawThreadList, + threads[0]); + typedef struct { u_int64_t base_of_image; @@ -576,19 +588,25 @@ typedef struct { MDCVHeader cv_header; u_int32_t signature; /* time_t debug information created */ u_int32_t age; /* revision of PDB file */ - u_int8_t pdb_file_name[0]; /* Pathname or filename of PDB file */ + u_int8_t pdb_file_name[1]; /* Pathname or filename of PDB file */ } MDCVInfoPDB20; +static const size_t MDCVInfoPDB20_minsize = offsetof(MDCVInfoPDB20, + pdb_file_name[0]); + #define MD_CVINFOPDB20_SIGNATURE 0x3031424e /* cvHeader.signature = '01BN' */ typedef struct { u_int32_t cv_signature; MDGUID signature; /* GUID, identifies PDB file */ u_int32_t age; /* Identifies incremental changes to PDB file */ - u_int8_t pdb_file_name[0]; /* Pathname or filename of PDB file, + u_int8_t pdb_file_name[1]; /* Pathname or filename of PDB file, * 0-terminated 8-bit character data (UTF-8?) */ } MDCVInfoPDB70; +static const size_t MDCVInfoPDB70_minsize = offsetof(MDCVInfoPDB70, + pdb_file_name[0]); + #define MD_CVINFOPDB70_SIGNATURE 0x53445352 /* cvSignature = 'SDSR' */ /* In addition to the two CodeView record formats above, used for linking @@ -618,21 +636,30 @@ typedef struct { u_int32_t length; /* Length of entire MDImageDebugMisc structure */ u_int8_t unicode; /* True if data is multibyte */ u_int8_t reserved[3]; - u_int8_t data[0]; + u_int8_t data[1]; } MDImageDebugMisc; /* IMAGE_DEBUG_MISC */ +static const size_t MDImageDebugMisc_minsize = offsetof(MDImageDebugMisc, + data[0]); + typedef struct { u_int32_t number_of_modules; - MDRawModule modules[0]; + MDRawModule modules[1]; } MDRawModuleList; /* MINIDUMP_MODULE_LIST */ +static const size_t MDRawModuleList_minsize = offsetof(MDRawModuleList, + modules[0]); + typedef struct { u_int32_t number_of_memory_ranges; - MDMemoryDescriptor memory_ranges[0]; + MDMemoryDescriptor memory_ranges[1]; } MDRawMemoryList; /* MINIDUMP_MEMORY_LIST */ +static const size_t MDRawMemoryList_minsize = offsetof(MDRawMemoryList, + memory_ranges[0]); + #define MD_EXCEPTION_MAXIMUM_PARAMETERS 15 @@ -848,7 +875,7 @@ typedef enum { /* EXC_GPFLT */ /* EXC_I386_PGFLT = 14: should not occur in user space */ /* EXC_I386_EXTERRFLT = 16: mapped to EXC_ARITHMETIC/EXC_I386_EXTERR */ - MD_EXCEPTION_CODE_MAC_X86_ALIGNMENT_FAULT = 17, + MD_EXCEPTION_CODE_MAC_X86_ALIGNMENT_FAULT = 17 /* EXC_ALIGNFLT (for vector operations) */ /* EXC_I386_ENOEXTFLT = 32: should be handled by the kernel */ /* EXC_I386_ENDPERR = 33: should not occur */ @@ -885,13 +912,9 @@ typedef struct { u_int16_t processor_level; /* x86: 5 = 586, 6 = 686, ... */ u_int16_t processor_revision; /* x86: 0xMMSS, where MM=model, * SS=stepping */ - union { - u_int16_t reserved0; - struct { - u_int8_t number_of_processors; - u_int8_t product_type; /* Windows: VER_NT_* from WinNT.h */ - }; - }; + + u_int8_t number_of_processors; + u_int8_t product_type; /* Windows: VER_NT_* from WinNT.h */ /* The next 5 fields are from the OSVERSIONINFO structure as returned * by GetVersionEx */ @@ -907,13 +930,9 @@ typedef struct { * (sw_vers -buildVersion). * Linux: uname -srvmo */ - union { - u_int32_t reserved1; - struct { - u_int16_t suite_mask; /* Windows: VER_SUITE_* from WinNT.h */ - u_int16_t reserved2; - }; - }; + u_int16_t suite_mask; /* Windows: VER_SUITE_* from WinNT.h */ + u_int16_t reserved2; + MDCPUInformation cpu; } MDRawSystemInfo; /* MINIDUMP_SYSTEM_INFO */ @@ -947,7 +966,7 @@ typedef enum { /* The following values are Breakpad-defined. */ MD_OS_UNIX = 0x8000, /* Generic Unix-ish */ MD_OS_MAC_OS_X = 0x8101, /* Mac OS X/Darwin */ - MD_OS_LINUX = 0x8201, /* Linux */ + MD_OS_LINUX = 0x8201 /* Linux */ } MDOSPlatform; diff --git a/src/google_breakpad/common/minidump_size.h b/src/google_breakpad/common/minidump_size.h new file mode 100644 index 00000000..01b42a2b --- /dev/null +++ b/src/google_breakpad/common/minidump_size.h @@ -0,0 +1,107 @@ +// Copyright (c) 2007, 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. */ + +// minidump_size.h: Provides a C++ template for programmatic access to +// the sizes of various types defined in minidump_format.h. +// +// Author: Mark Mentovai + +#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_SIZE_H__ +#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_SIZE_H__ + +#include + +#include "google_breakpad/common/minidump_format.h" + +namespace google_breakpad { + +template +class minidump_size { + public: + static size_t size() { return sizeof(T); } +}; + +// Explicit specializations for variable-length types. The size returned +// for these should be the size for an object without its variable-length +// section. + +template<> +class minidump_size { + public: + static size_t size() { return MDString_minsize; } +}; + +template<> +class minidump_size { + public: + static size_t size() { return MDRawThreadList_minsize; } +}; + +template<> +class minidump_size { + public: + static size_t size() { return MDCVInfoPDB20_minsize; } +}; + +template<> +class minidump_size { + public: + static size_t size() { return MDCVInfoPDB70_minsize; } +}; + +template<> +class minidump_size { + public: + static size_t size() { return MDImageDebugMisc_minsize; } +}; + +template<> +class minidump_size { + public: + static size_t size() { return MDRawModuleList_minsize; } +}; + +template<> +class minidump_size { + public: + static size_t size() { return MDRawMemoryList_minsize; } +}; + +// Explicit specialization for MDRawModule, for which sizeof may include +// tail-padding on some architectures but not others. + +template<> +class minidump_size { + public: + static size_t size() { return MD_MODULE_SIZE; } +}; + +} // namespace google_breakpad + +#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_SIZE_H__ */ diff --git a/src/google_breakpad/processor/minidump_processor.h b/src/google_breakpad/processor/minidump_processor.h index 9e7ea191..fc0024bc 100644 --- a/src/google_breakpad/processor/minidump_processor.h +++ b/src/google_breakpad/processor/minidump_processor.h @@ -46,9 +46,9 @@ class MinidumpProcessor { public: // Return type for Process() enum ProcessResult { - PROCESS_OK, // the minidump was processed successfully - PROCESS_ERROR, // there was an error processing the minidump - PROCESS_INTERRUPTED, // processing was interrupted by the SymbolSupplier + PROCESS_OK, // the minidump was processed successfully + PROCESS_ERROR, // there was an error processing the minidump + PROCESS_INTERRUPTED // processing was interrupted by the SymbolSupplier }; // Initializes this MinidumpProcessor. supplier should be an diff --git a/src/google_breakpad/processor/symbol_supplier.h b/src/google_breakpad/processor/symbol_supplier.h index 8fc88a66..0459c8aa 100644 --- a/src/google_breakpad/processor/symbol_supplier.h +++ b/src/google_breakpad/processor/symbol_supplier.h @@ -52,7 +52,7 @@ class SymbolSupplier { FOUND, // stops processing the minidump immediately - INTERRUPT, + INTERRUPT }; virtual ~SymbolSupplier() {} diff --git a/src/processor/logging.h b/src/processor/logging.h index 40738836..b638ff58 100644 --- a/src/processor/logging.h +++ b/src/processor/logging.h @@ -72,7 +72,7 @@ class LogStream { public: enum Severity { SEVERITY_INFO, - SEVERITY_ERROR, + SEVERITY_ERROR }; // Begin logging a message to the stream identified by |stream|, at the diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index ed0ba365..3548fb95 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -106,15 +106,13 @@ static inline void Swap(u_int32_t* value) { } -static inline void Swap(u_int64_t* value) { - *value = (*value >> 56) | - ((*value >> 40) & 0x000000000000ff00LL) | - ((*value >> 24) & 0x0000000000ff0000LL) | - ((*value >> 8) & 0x00000000ff000000LL) | - ((*value << 8) & 0x000000ff00000000LL) | - ((*value << 24) & 0x0000ff0000000000LL) | - ((*value << 40) & 0x00ff000000000000LL) | - (*value << 56); +static void Swap(u_int64_t* value) { + u_int32_t* value32 = reinterpret_cast(value); + Swap(&value32[0]); + Swap(&value32[1]); + u_int32_t temp = value32[0]; + value32[0] = value32[1]; + value32[1] = temp; } @@ -1392,7 +1390,7 @@ string MinidumpModule::debug_file() const { // if misc_record->data is 0-terminated, so use an explicit size. file = string( reinterpret_cast(misc_record->data), - module_.misc_record.data_size - sizeof(MDImageDebugMisc)); + module_.misc_record.data_size - MDImageDebugMisc_minsize); } else { // There's a misc_record but it encodes the debug filename in UTF-16. // (Actually, because miscellaneous records are so old, it's probably @@ -1401,7 +1399,7 @@ string MinidumpModule::debug_file() const { // return. unsigned int bytes = - module_.misc_record.data_size - sizeof(MDImageDebugMisc); + module_.misc_record.data_size - MDImageDebugMisc_minsize; if (bytes % 2 == 0) { unsigned int utf16_words = bytes / 2; @@ -1559,7 +1557,7 @@ const u_int8_t* MinidumpModule::GetCVRecord(u_int32_t* size) { // problems. x86 and ppc are able to cope, though. This allocation // style is needed because the MDCVInfoPDB70 or MDCVInfoPDB20 are // variable-sized due to their pdb_file_name fields; these structures - // are not sizeof(MDCVInfoPDB70) or sizeof(MDCVInfoPDB20) and treating + // are not MDCVInfoPDB70_minsize or MDCVInfoPDB20_minsize and treating // them as such would result in incomplete structures or overruns. scoped_ptr< vector > cv_record( new vector(module_.cv_record.data_size)); @@ -1580,9 +1578,9 @@ const u_int8_t* MinidumpModule::GetCVRecord(u_int32_t* size) { if (signature == MD_CVINFOPDB70_SIGNATURE) { // Now that the structure type is known, recheck the size. - if (sizeof(MDCVInfoPDB70) > module_.cv_record.data_size) { + if (MDCVInfoPDB70_minsize > module_.cv_record.data_size) { BPLOG(ERROR) << "MinidumpModule CodeView7 record size mismatch, " << - sizeof(MDCVInfoPDB70) << " > " << + MDCVInfoPDB70_minsize << " > " << module_.cv_record.data_size; return NULL; } @@ -1606,9 +1604,9 @@ const u_int8_t* MinidumpModule::GetCVRecord(u_int32_t* size) { } } else if (signature == MD_CVINFOPDB20_SIGNATURE) { // Now that the structure type is known, recheck the size. - if (sizeof(MDCVInfoPDB20) > module_.cv_record.data_size) { + if (MDCVInfoPDB20_minsize > module_.cv_record.data_size) { BPLOG(ERROR) << "MinidumpModule CodeView2 record size mismatch, " << - sizeof(MDCVInfoPDB20) << " > " << + MDCVInfoPDB20_minsize << " > " << module_.cv_record.data_size; return NULL; } @@ -1662,9 +1660,9 @@ const MDImageDebugMisc* MinidumpModule::GetMiscRecord(u_int32_t* size) { return NULL; } - if (sizeof(MDImageDebugMisc) > module_.misc_record.data_size) { + if (MDImageDebugMisc_minsize > module_.misc_record.data_size) { BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record " - "size mismatch, " << sizeof(MDImageDebugMisc) << " > " << + "size mismatch, " << MDImageDebugMisc_minsize << " > " << module_.misc_record.data_size; return NULL; } @@ -1686,7 +1684,7 @@ const MDImageDebugMisc* MinidumpModule::GetMiscRecord(u_int32_t* size) { // is allocated as u_int8_t[] can cause alignment problems. x86 and // ppc are able to cope, though. This allocation style is needed // because the MDImageDebugMisc is variable-sized due to its data field; - // this structure is not sizeof(MDImageDebugMisc) and treating it as such + // this structure is not MDImageDebugMisc_minsize and treating it as such // would result in an incomplete structure or an overrun. scoped_ptr< vector > misc_record_mem( new vector(module_.misc_record.data_size)); @@ -1710,7 +1708,7 @@ const MDImageDebugMisc* MinidumpModule::GetMiscRecord(u_int32_t* size) { // in practice due to the layout of MDImageDebugMisc. u_int16_t* data16 = reinterpret_cast(&(misc_record->data)); unsigned int dataBytes = module_.misc_record.data_size - - sizeof(MDImageDebugMisc); + MDImageDebugMisc_minsize; unsigned int dataLength = dataBytes / 2; for (unsigned int characterIndex = 0; characterIndex < dataLength; diff --git a/src/processor/minidump_stackwalk.cc b/src/processor/minidump_stackwalk.cc index 01b601c7..35f0aa27 100644 --- a/src/processor/minidump_stackwalk.cc +++ b/src/processor/minidump_stackwalk.cc @@ -233,7 +233,7 @@ static void PrintModules(const CodeModules *modules) { printf("\n"); printf("Loaded modules:\n"); - u_int64_t main_address = 0xffffffffffffffffLL; + u_int64_t main_address = 0; const CodeModule *main_module = modules->GetMainModule(); if (main_module) { main_address = main_module->base_address(); @@ -249,7 +249,8 @@ static void PrintModules(const CodeModules *modules) { base_address, base_address + module->size() - 1, PathnameStripper::File(module->code_file()).c_str(), module->version().empty() ? "???" : module->version().c_str(), - base_address == main_address ? " (main)" : ""); + main_module != NULL && base_address == main_address ? + " (main)" : ""); } } @@ -262,7 +263,7 @@ static void PrintModulesMachineReadable(const CodeModules *modules) { if (!modules) return; - u_int64_t main_address = 0xffffffffffffffffLL; + u_int64_t main_address = 0; const CodeModule *main_module = modules->GetMainModule(); if (main_module) { main_address = main_module->base_address(); @@ -284,7 +285,8 @@ static void PrintModulesMachineReadable(const CodeModules *modules) { StripSeparator(module->debug_identifier()).c_str(), kOutputSeparator, base_address, kOutputSeparator, base_address + module->size() - 1, - kOutputSeparator, base_address == main_address ? 1 : 0); + kOutputSeparator, + main_module != NULL && base_address == main_address ? 1 : 0); } }