diff --git a/src/common/windows/dia_util.h b/src/common/windows/dia_util.h index 4b259b45..b9e0df2d 100644 --- a/src/common/windows/dia_util.h +++ b/src/common/windows/dia_util.h @@ -1,59 +1,64 @@ -// Copyright 2013 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. - -// Utilities for loading debug streams and tables from a PDB file. - -#include -#include - -namespace google_breakpad { - -// Find the debug stream of the given |name| in the given |session|. Returns -// true on success, false on error of if the stream does not exist. On success -// the stream will be returned via |debug_stream|. -bool FindDebugStream(const wchar_t* name, - IDiaSession* session, - IDiaEnumDebugStreamData** debug_stream); - -// Finds the first table implementing the COM interface with ID |iid| in the -// given |session|. Returns true on success, false on error or if no such -// table is found. On success the table will be returned via |table|. -bool FindTable(REFIID iid, IDiaSession* session, void** table); - -// A templated version of FindTable. Finds the first table implementing type -// |InterfaceType| in the given |session|. Returns true on success, false on -// error or if no such table is found. On success the table will be returned via -// |table|. -template -bool FindTable(IDiaSession* session, InterfaceType** table) { - return FindTable(__uuidof(InterfaceType), - session, - reinterpret_cast(table)); -} - -} // namespace google_breakpad +// Copyright 2013 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. + +// Utilities for loading debug streams and tables from a PDB file. + +#ifndef COMMON_WINDOWS_DIA_UTIL_H_ +#define COMMON_WINDOWS_DIA_UTIL_H_ + +#include +#include + +namespace google_breakpad { + +// Find the debug stream of the given |name| in the given |session|. Returns +// true on success, false on error of if the stream does not exist. On success +// the stream will be returned via |debug_stream|. +bool FindDebugStream(const wchar_t* name, + IDiaSession* session, + IDiaEnumDebugStreamData** debug_stream); + +// Finds the first table implementing the COM interface with ID |iid| in the +// given |session|. Returns true on success, false on error or if no such +// table is found. On success the table will be returned via |table|. +bool FindTable(REFIID iid, IDiaSession* session, void** table); + +// A templated version of FindTable. Finds the first table implementing type +// |InterfaceType| in the given |session|. Returns true on success, false on +// error or if no such table is found. On success the table will be returned via +// |table|. +template +bool FindTable(IDiaSession* session, InterfaceType** table) { + return FindTable(__uuidof(InterfaceType), + session, + reinterpret_cast(table)); +} + +} // namespace google_breakpad + +#endif // COMMON_WINDOWS_DIA_UTIL_H_ diff --git a/src/common/windows/guid_string.h b/src/common/windows/guid_string.h index f8aa8a23..6b92675b 100644 --- a/src/common/windows/guid_string.h +++ b/src/common/windows/guid_string.h @@ -29,8 +29,8 @@ // guid_string.cc: Convert GUIDs to strings. -#ifndef COMMON_WINDOWS_GUID_STRING_H__ -#define COMMON_WINDOWS_GUID_STRING_H__ +#ifndef COMMON_WINDOWS_GUID_STRING_H_ +#define COMMON_WINDOWS_GUID_STRING_H_ #include @@ -55,4 +55,4 @@ class GUIDString { } // namespace google_breakpad -#endif // COMMON_WINDOWS_GUID_STRING_H__ +#endif // COMMON_WINDOWS_GUID_STRING_H_ diff --git a/src/common/windows/http_upload.h b/src/common/windows/http_upload.h index 8a17aab1..0594cde3 100644 --- a/src/common/windows/http_upload.h +++ b/src/common/windows/http_upload.h @@ -31,12 +31,12 @@ // request using wininet. It currently supports requests that contain // a set of string parameters (key/value pairs), and a file to upload. -#ifndef COMMON_WINDOWS_HTTP_UPLOAD_H__ -#define COMMON_WINDOWS_HTTP_UPLOAD_H__ +#ifndef COMMON_WINDOWS_HTTP_UPLOAD_H_ +#define COMMON_WINDOWS_HTTP_UPLOAD_H_ -#pragma warning( push ) +#pragma warning(push) // Disable exception handler warnings. -#pragma warning( disable : 4530 ) +#pragma warning(disable : 4530) #include #include @@ -121,6 +121,6 @@ class HTTPUpload { } // namespace google_breakpad -#pragma warning( pop ) +#pragma warning(pop) -#endif // COMMON_WINDOWS_HTTP_UPLOAD_H__ +#endif // COMMON_WINDOWS_HTTP_UPLOAD_H_ diff --git a/src/common/windows/omap.h b/src/common/windows/omap.h index 88e8589e..bc293afb 100644 --- a/src/common/windows/omap.h +++ b/src/common/windows/omap.h @@ -1,72 +1,72 @@ -// Copyright 2013 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. - -// Provides an API for mapping symbols through OMAP information, if a PDB file -// is augmented with it. This allows breakpad to work with addresses in -// transformed images by transforming the symbols themselves, rather than -// transforming addresses prior to querying symbols (the way it is typically -// done by Windows-native tools, including the DIA). - -#ifndef COMMON_WINDOWS_OMAP_H__ -#define COMMON_WINDOWS_OMAP_H__ - -#include "common/windows/omap_internal.h" - -namespace google_breakpad { - -// If the given session contains OMAP data this extracts it, populating -// |omap_data|, and then disabling automatic translation for the session. -// OMAP data is present in the PDB if |omap_data| is not empty. This returns -// true on success, false otherwise. -bool GetOmapDataAndDisableTranslation(IDiaSession* dia_session, - OmapData* omap_data); - -// Given raw OMAP data builds an ImageMap. This can be used to query individual -// image ranges using MapAddressRange. -// |omap_data|| is the OMAP data extracted from the PDB. -// |image_map| will be populated with a description of the image mapping. If -// |omap_data| is empty then this will also be empty. -void BuildImageMap(const OmapData& omap_data, ImageMap* image_map); - -// Given an address range in the original image space determines how exactly it -// has been tranformed. -// |omap_data| is the OMAP data extracted from the PDB, which must not be -// empty. -// |original_range| is the address range in the original image being queried. -// |mapped_ranges| will be populated with a full description of the mapping. -// They may be disjoint in the transformed image so a vector is needed to -// fully represent the mapping. This will be appended to if it is not -// empty. If |omap_data| is empty then |mapped_ranges| will simply be -// populated with a copy of |original_range| (the identity transform). -void MapAddressRange(const ImageMap& image_map, - const AddressRange& original_range, - AddressRangeVector* mapped_ranges); - -} // namespace google_breakpad - -#endif // COMMON_WINDOWS_OMAP_H__ +// Copyright 2013 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. + +// Provides an API for mapping symbols through OMAP information, if a PDB file +// is augmented with it. This allows breakpad to work with addresses in +// transformed images by transforming the symbols themselves, rather than +// transforming addresses prior to querying symbols (the way it is typically +// done by Windows-native tools, including the DIA). + +#ifndef COMMON_WINDOWS_OMAP_H_ +#define COMMON_WINDOWS_OMAP_H_ + +#include "common/windows/omap_internal.h" + +namespace google_breakpad { + +// If the given session contains OMAP data this extracts it, populating +// |omap_data|, and then disabling automatic translation for the session. +// OMAP data is present in the PDB if |omap_data| is not empty. This returns +// true on success, false otherwise. +bool GetOmapDataAndDisableTranslation(IDiaSession* dia_session, + OmapData* omap_data); + +// Given raw OMAP data builds an ImageMap. This can be used to query individual +// image ranges using MapAddressRange. +// |omap_data|| is the OMAP data extracted from the PDB. +// |image_map| will be populated with a description of the image mapping. If +// |omap_data| is empty then this will also be empty. +void BuildImageMap(const OmapData& omap_data, ImageMap* image_map); + +// Given an address range in the original image space determines how exactly it +// has been tranformed. +// |omap_data| is the OMAP data extracted from the PDB, which must not be +// empty. +// |original_range| is the address range in the original image being queried. +// |mapped_ranges| will be populated with a full description of the mapping. +// They may be disjoint in the transformed image so a vector is needed to +// fully represent the mapping. This will be appended to if it is not +// empty. If |omap_data| is empty then |mapped_ranges| will simply be +// populated with a copy of |original_range| (the identity transform). +void MapAddressRange(const ImageMap& image_map, + const AddressRange& original_range, + AddressRangeVector* mapped_ranges); + +} // namespace google_breakpad + +#endif // COMMON_WINDOWS_OMAP_H_ diff --git a/src/common/windows/omap_internal.h b/src/common/windows/omap_internal.h index 1364eb9e..3f904d7a 100644 --- a/src/common/windows/omap_internal.h +++ b/src/common/windows/omap_internal.h @@ -1,137 +1,137 @@ -// Copyright 2013 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. - -// Declares internal implementation details for functionality in omap.h and -// omap.cc. - -#ifndef COMMON_WINDOWS_OMAP_INTERNAL_H__ -#define COMMON_WINDOWS_OMAP_INTERNAL_H__ - -#include -#include - -#include - -namespace google_breakpad { - -// The OMAP struct is defined by debughlp.h, which doesn't play nicely with -// imagehlp.h. We simply redefine it. -struct OMAP { - DWORD rva; - DWORD rvaTo; -}; -static_assert(sizeof(OMAP) == 8, "Wrong size for OMAP structure."); -typedef std::vector OmapTable; - -// This contains the OMAP data extracted from an image. -struct OmapData { - // The table of OMAP entries describing the transformation from the - // original image to the transformed image. - OmapTable omap_from; - // The table of OMAP entries describing the transformation from the - // instrumented image to the original image. - OmapTable omap_to; - // The length of the original untransformed image. - DWORD length_original; - - OmapData() : length_original(0) { } -}; - -// This represents a range of addresses in an image. -struct AddressRange { - DWORD rva; - DWORD length; - - AddressRange() : rva(0), length(0) { } - AddressRange(DWORD rva, DWORD length) : rva(rva), length(length) { } - - // Returns the end address of this range. - DWORD end() const { return rva + length; } - - // Addreses only compare as less-than or greater-than if they are not - // overlapping. Otherwise, they compare equal. - int Compare(const AddressRange& rhs) const; - bool operator<(const AddressRange& rhs) const { return Compare(rhs) == -1; } - bool operator>(const AddressRange& rhs) const { return Compare(rhs) == 1; } - - // Equality operators compare exact values. - bool operator==(const AddressRange& rhs) const { - return rva == rhs.rva && length == rhs.length; - } - bool operator!=(const AddressRange& rhs) const { return !((*this) == rhs); } -}; - -typedef std::vector AddressRangeVector; - -// This represents an address range in an original image, and its corresponding -// range in the transformed image. -struct MappedRange { - // An address in the original image. - DWORD rva_original; - // The corresponding addresses in the transformed image. - DWORD rva_transformed; - // The length of the address range. - DWORD length; - // It is possible for code to be injected into a transformed image, for which - // there is no corresponding code in the original image. If this range of - // transformed image is immediately followed by such injected code we maintain - // a record of its length here. - DWORD injected; - // It is possible for code to be removed from the original image. This happens - // for things like padding between blocks. There is no actual content lost, - // but the spacing between items may be lost. This keeps track of any removed - // content immediately following the |original| range. - DWORD removed; -}; -// A vector of mapped ranges is used as a more useful representation of -// OMAP data. -typedef std::vector Mapping; - -// Used as a secondary search structure accompanying a Mapping. -struct EndpointIndex { - DWORD endpoint; - size_t index; -}; -typedef std::vector EndpointIndexMap; - -// An ImageMap is vector of mapped ranges, plus a secondary index into it for -// doing interval searches. (An interval tree would also work, but is overkill -// because we don't need insertion and deletion.) -struct ImageMap { - // This is a description of the mapping between original and transformed - // image, sorted by addresses in the original image. - Mapping mapping; - // For all interval endpoints in |mapping| this stores the minimum index of - // an interval in |mapping| that contains the endpoint. Useful for doing - // interval intersection queries. - EndpointIndexMap endpoint_index_map; -}; - -} // namespace google_breakpad - -#endif // COMMON_WINDOWS_OMAP_INTERNAL_H__ +// Copyright 2013 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. + +// Declares internal implementation details for functionality in omap.h and +// omap.cc. + +#ifndef COMMON_WINDOWS_OMAP_INTERNAL_H_ +#define COMMON_WINDOWS_OMAP_INTERNAL_H_ + +#include +#include + +#include + +namespace google_breakpad { + +// The OMAP struct is defined by debughlp.h, which doesn't play nicely with +// imagehlp.h. We simply redefine it. +struct OMAP { + DWORD rva; + DWORD rvaTo; +}; +static_assert(sizeof(OMAP) == 8, "Wrong size for OMAP structure."); +typedef std::vector OmapTable; + +// This contains the OMAP data extracted from an image. +struct OmapData { + // The table of OMAP entries describing the transformation from the + // original image to the transformed image. + OmapTable omap_from; + // The table of OMAP entries describing the transformation from the + // instrumented image to the original image. + OmapTable omap_to; + // The length of the original untransformed image. + DWORD length_original; + + OmapData() : length_original(0) { } +}; + +// This represents a range of addresses in an image. +struct AddressRange { + DWORD rva; + DWORD length; + + AddressRange() : rva(0), length(0) { } + AddressRange(DWORD rva, DWORD length) : rva(rva), length(length) { } + + // Returns the end address of this range. + DWORD end() const { return rva + length; } + + // Addreses only compare as less-than or greater-than if they are not + // overlapping. Otherwise, they compare equal. + int Compare(const AddressRange& rhs) const; + bool operator<(const AddressRange& rhs) const { return Compare(rhs) == -1; } + bool operator>(const AddressRange& rhs) const { return Compare(rhs) == 1; } + + // Equality operators compare exact values. + bool operator==(const AddressRange& rhs) const { + return rva == rhs.rva && length == rhs.length; + } + bool operator!=(const AddressRange& rhs) const { return !((*this) == rhs); } +}; + +typedef std::vector AddressRangeVector; + +// This represents an address range in an original image, and its corresponding +// range in the transformed image. +struct MappedRange { + // An address in the original image. + DWORD rva_original; + // The corresponding addresses in the transformed image. + DWORD rva_transformed; + // The length of the address range. + DWORD length; + // It is possible for code to be injected into a transformed image, for which + // there is no corresponding code in the original image. If this range of + // transformed image is immediately followed by such injected code we maintain + // a record of its length here. + DWORD injected; + // It is possible for code to be removed from the original image. This happens + // for things like padding between blocks. There is no actual content lost, + // but the spacing between items may be lost. This keeps track of any removed + // content immediately following the |original| range. + DWORD removed; +}; +// A vector of mapped ranges is used as a more useful representation of +// OMAP data. +typedef std::vector Mapping; + +// Used as a secondary search structure accompanying a Mapping. +struct EndpointIndex { + DWORD endpoint; + size_t index; +}; +typedef std::vector EndpointIndexMap; + +// An ImageMap is vector of mapped ranges, plus a secondary index into it for +// doing interval searches. (An interval tree would also work, but is overkill +// because we don't need insertion and deletion.) +struct ImageMap { + // This is a description of the mapping between original and transformed + // image, sorted by addresses in the original image. + Mapping mapping; + // For all interval endpoints in |mapping| this stores the minimum index of + // an interval in |mapping| that contains the endpoint. Useful for doing + // interval intersection queries. + EndpointIndexMap endpoint_index_map; +}; + +} // namespace google_breakpad + +#endif // COMMON_WINDOWS_OMAP_INTERNAL_H_ diff --git a/src/common/windows/pdb_source_line_writer.cc b/src/common/windows/pdb_source_line_writer.cc index 5de7ade6..516f2f48 100644 --- a/src/common/windows/pdb_source_line_writer.cc +++ b/src/common/windows/pdb_source_line_writer.cc @@ -74,7 +74,7 @@ enum UnwindOperationCodes { UWOP_SET_FPREG, /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */ UWOP_SAVE_NONVOL, /* info == register number, offset in next slot */ UWOP_SAVE_NONVOL_FAR, /* info == register number, offset in next 2 slots */ - //XXX: these are missing from MSDN! + // XXX: these are missing from MSDN! // See: http://www.osronline.com/ddkx/kmarch/64bitamd_4rs7.htm UWOP_SAVE_XMM, UWOP_SAVE_XMM_FAR, @@ -125,8 +125,19 @@ PDBSourceLineWriter::PDBSourceLineWriter() : output_(NULL) { PDBSourceLineWriter::~PDBSourceLineWriter() { } +bool PDBSourceLineWriter::SetCodeFile(const wstring &exe_file) { + if (code_file_.empty()) { + code_file_ = exe_file; + return true; + } + // Setting a different code file path is an error. It is success only if the + // file paths are the same. + return exe_file == code_file_; +} + bool PDBSourceLineWriter::Open(const wstring &file, FileFormat format) { Close(); + code_file_.clear(); if (FAILED(CoInitialize(NULL))) { fprintf(stderr, "CoInitialize failed\n"); @@ -140,6 +151,7 @@ bool PDBSourceLineWriter::Open(const wstring &file, FileFormat format) { StringFromGUID2(CLSID_DiaSource, classid, kGuidSize); // vc80 uses bce36434-2c24-499e-bf49-8bd99b0eeb68. // vc90 uses 4C41678E-887B-4365-A09E-925D28DB33C2. + // vc100 uses B86AE24D-BF2F-4AC9-B5A2-34B14E4CE11D. fprintf(stderr, "CoCreateInstance CLSID_DiaSource %S failed " "(msdia*.dll unregistered?)\n", classid); return false; @@ -162,7 +174,8 @@ bool PDBSourceLineWriter::Open(const wstring &file, FileFormat format) { case ANY_FILE: if (FAILED(data_source->loadDataFromPdb(file.c_str()))) { if (FAILED(data_source->loadDataForExe(file.c_str(), NULL, NULL))) { - fprintf(stderr, "loadDataForPdb and loadDataFromExe failed for %ws\n", file.c_str()); + fprintf(stderr, "loadDataForPdb and loadDataFromExe failed for %ws\n", + file.c_str()); return false; } code_file_ = file; @@ -641,7 +654,7 @@ bool PDBSourceLineWriter::PrintFrameDataUsingEXE() { unwind_rva, &img->LastRvaSection)); - DWORD stack_size = 8; // minimal stack size is 8 for RIP + DWORD stack_size = 8; // minimal stack size is 8 for RIP DWORD rip_offset = 8; do { for (UBYTE c = 0; c < unwind_info->count_of_codes; c++) { @@ -674,12 +687,12 @@ bool PDBSourceLineWriter::PrintFrameDataUsingEXE() { break; case UWOP_SAVE_NONVOL: case UWOP_SAVE_XMM128: { - c++; //skip slot with offset + c++; // skip slot with offset break; } case UWOP_SAVE_NONVOL_FAR: case UWOP_SAVE_XMM128_FAR: { - c += 2; //skip 2 slots with offset + c += 2; // skip 2 slots with offset break; } case UWOP_PUSH_MACHFRAME: { @@ -832,7 +845,7 @@ bool PDBSourceLineWriter::FindPEFile() { CComBSTR symbols_file; if (SUCCEEDED(global->get_symbolsFileName(&symbols_file))) { wstring file(symbols_file); - + // Look for an EXE or DLL file. const wchar_t *extensions[] = { L"exe", L"dll" }; for (int i = 0; i < sizeof(extensions) / sizeof(extensions[0]); i++) { @@ -1064,7 +1077,7 @@ bool PDBSourceLineWriter::WriteMap(FILE *map_file) { // This is not a critical piece of the symbol file. PrintPEInfo(); ret = ret && - PrintSourceFiles() && + PrintSourceFiles() && PrintFunctions() && PrintFrameData(); @@ -1206,8 +1219,7 @@ bool PDBSourceLineWriter::GetPEInfo(PEModuleInfo *info) { if (opt->Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { // 64-bit PE file. SizeOfImage = opt->SizeOfImage; - } - else { + } else { // 32-bit PE file. SizeOfImage = img->FileHeader->OptionalHeader.SizeOfImage; } diff --git a/src/common/windows/pdb_source_line_writer.h b/src/common/windows/pdb_source_line_writer.h index d928a607..9aeb2a44 100644 --- a/src/common/windows/pdb_source_line_writer.h +++ b/src/common/windows/pdb_source_line_writer.h @@ -30,8 +30,8 @@ // PDBSourceLineWriter uses a pdb file produced by Visual C++ to output // a line/address map for use with BasicSourceLineResolver. -#ifndef _PDB_SOURCE_LINE_WRITER_H__ -#define _PDB_SOURCE_LINE_WRITER_H__ +#ifndef COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_ +#define COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_ #include @@ -101,10 +101,14 @@ class PDBSourceLineWriter { // Returns true on success. bool Open(const wstring &file, FileFormat format); - // Locates the pdb file for the given executable (exe or dll) file, - // and opens it. If there is already a pdb file open, it is automatically - // closed. Returns true on success. - bool OpenExecutable(const wstring &exe_file); + // Sets the code file full path. This is optional for 32-bit modules. It is + // also optional for 64-bit modules when there is an executable file stored + // in the same directory as the PDB file. It is only required for 64-bit + // modules when the executable file is not in the same location as the PDB + // file and it must be called after Open() and before WriteMap(). + // If Open() was called for an executable file, then it is an error to call + // SetCodeFile() with a different file path and it will return false. + bool SetCodeFile(const wstring &exe_file); // Writes a map file from the current pdb file to the given file stream. // Returns true on success. @@ -179,12 +183,12 @@ class PDBSourceLineWriter { // and an ID is stored for it, or false if it has not. bool FileIDIsCached(const wstring &file) { return unique_files_.find(file) != unique_files_.end(); - }; + } // Cache this filename and ID for later reuse. void CacheFileID(const wstring &file, DWORD id) { unique_files_[file] = id; - }; + } // Store this ID in the cache as a duplicate for this filename. void StoreDuplicateFileID(const wstring &file, DWORD id) { @@ -193,7 +197,7 @@ class PDBSourceLineWriter { // map this id to the previously seen one file_ids_[id] = iter->second; } - }; + } // Given a file's unique ID, return the ID that should be used to // reference it. There may be multiple files with identical filenames @@ -204,7 +208,7 @@ class PDBSourceLineWriter { if (iter == file_ids_.end()) return id; return iter->second; - }; + } // Find the PE file corresponding to the loaded PDB file, and // set the code_file_ member. Returns false on failure. @@ -250,4 +254,4 @@ class PDBSourceLineWriter { } // namespace google_breakpad -#endif // _PDB_SOURCE_LINE_WRITER_H__ +#endif // COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_ diff --git a/src/common/windows/string_utils-inl.h b/src/common/windows/string_utils-inl.h index d281aaa1..9b636072 100644 --- a/src/common/windows/string_utils-inl.h +++ b/src/common/windows/string_utils-inl.h @@ -30,8 +30,8 @@ // string_utils-inl.h: Safer string manipulation on Windows, supporting // pre-MSVC8 environments. -#ifndef COMMON_WINDOWS_STRING_UTILS_INL_H__ -#define COMMON_WINDOWS_STRING_UTILS_INL_H__ +#ifndef COMMON_WINDOWS_STRING_UTILS_INL_H_ +#define COMMON_WINDOWS_STRING_UTILS_INL_H_ #include #include @@ -139,4 +139,4 @@ inline void WindowsStringUtils::safe_wcsncpy(wchar_t *destination, } // namespace google_breakpad -#endif // COMMON_WINDOWS_STRING_UTILS_INL_H__ +#endif // COMMON_WINDOWS_STRING_UTILS_INL_H_ diff --git a/src/tools/windows/converter/ms_symbol_server_converter.cc b/src/tools/windows/converter/ms_symbol_server_converter.cc index 2b6278ba..fad35faf 100644 --- a/src/tools/windows/converter/ms_symbol_server_converter.cc +++ b/src/tools/windows/converter/ms_symbol_server_converter.cc @@ -113,10 +113,12 @@ MSSymbolServerConverter::MSSymbolServerConverter( assert(symbol_servers.size() > 0); +#if !defined(NDEBUG) // These are characters that are interpreted as having special meanings in // symbol_path_. - const char *kInvalidCharacters = "*;"; + const char kInvalidCharacters[] = "*;"; assert(local_cache.find_first_of(kInvalidCharacters) == string::npos); +#endif // !defined(NDEBUG) for (vector::const_iterator symbol_server = symbol_servers.begin(); symbol_server != symbol_servers.end(); @@ -183,7 +185,7 @@ class AutoSymSrv { // are supported by calling Delete(). class AutoDeleter { public: - AutoDeleter(const string &path) : path_(path) {} + explicit AutoDeleter(const string &path) : path_(path) {} ~AutoDeleter() { int error; @@ -213,18 +215,20 @@ class AutoDeleter { }; MSSymbolServerConverter::LocateResult -MSSymbolServerConverter::LocateSymbolFile(const MissingSymbolInfo &missing, - string *symbol_file) { - assert(symbol_file); - symbol_file->clear(); +MSSymbolServerConverter::LocateFile(const string &debug_or_code_file, + const string &debug_or_code_id, + const string &version, + string *file_name) { + assert(file_name); + file_name->clear(); GUIDOrSignatureIdentifier identifier; - if (!identifier.InitializeFromString(missing.debug_identifier)) { + if (!identifier.InitializeFromString(debug_or_code_id)) { fprintf(stderr, - "LocateSymbolFile: Unparseable debug_identifier for %s %s %s\n", - missing.debug_file.c_str(), - missing.debug_identifier.c_str(), - missing.version.c_str()); + "LocateFile: Unparseable identifier for %s %s %s\n", + debug_or_code_file.c_str(), + debug_or_code_id.c_str(), + version.c_str()); return LOCATE_FAILURE; } @@ -233,22 +237,22 @@ MSSymbolServerConverter::LocateSymbolFile(const MissingSymbolInfo &missing, if (!symsrv.Initialize(process, const_cast(symbol_path_.c_str()), false)) { - fprintf(stderr, "LocateSymbolFile: SymInitialize: error %d for %s %s %s\n", + fprintf(stderr, "LocateFile: SymInitialize: error %d for %s %s %s\n", GetLastError(), - missing.debug_file.c_str(), - missing.debug_identifier.c_str(), - missing.version.c_str()); + debug_or_code_file.c_str(), + debug_or_code_id.c_str(), + version.c_str()); return LOCATE_FAILURE; } if (!SymRegisterCallback64(process, SymCallback, reinterpret_cast(this))) { fprintf(stderr, - "LocateSymbolFile: SymRegisterCallback64: error %d for %s %s %s\n", + "LocateFile: SymRegisterCallback64: error %d for %s %s %s\n", GetLastError(), - missing.debug_file.c_str(), - missing.debug_identifier.c_str(), - missing.version.c_str()); + debug_or_code_file.c_str(), + debug_or_code_id.c_str(), + version.c_str()); return LOCATE_FAILURE; } @@ -267,7 +271,7 @@ MSSymbolServerConverter::LocateSymbolFile(const MissingSymbolInfo &missing, char path[MAX_PATH]; if (!SymFindFileInPath( process, NULL, - const_cast(missing.debug_file.c_str()), + const_cast(debug_or_code_file.c_str()), const_cast(identifier.guid_or_signature_pointer()), identifier.age(), 0, identifier.type() == GUIDOrSignatureIdentifier::TYPE_GUID ? @@ -286,11 +290,11 @@ MSSymbolServerConverter::LocateSymbolFile(const MissingSymbolInfo &missing, // This is an authoritiative file-not-found message. if (fail_not_found_) { fprintf(stderr, - "LocateSymbolFile: SymFindFileInPath: LOCATE_NOT_FOUND error " + "LocateFile: SymFindFileInPath: LOCATE_NOT_FOUND error " "for %s %s %s\n", - missing.debug_file.c_str(), - missing.debug_identifier.c_str(), - missing.version.c_str()); + debug_or_code_file.c_str(), + debug_or_code_id.c_str(), + version.c_str()); return LOCATE_NOT_FOUND; } @@ -299,14 +303,17 @@ MSSymbolServerConverter::LocateSymbolFile(const MissingSymbolInfo &missing, } fprintf(stderr, - "LocateSymbolFile: SymFindFileInPath: error %d for %s %s %s\n", + "LocateFile: SymFindFileInPath: error %d for %s %s %s\n", error, - missing.debug_file.c_str(), - missing.debug_identifier.c_str(), - missing.version.c_str()); + debug_or_code_file.c_str(), + debug_or_code_id.c_str(), + version.c_str()); return LOCATE_FAILURE; } + // Making sure path is null-terminated. + path[MAX_PATH - 1] = '\0'; + // The AutoDeleter ensures that the file is only kept when returning // LOCATE_SUCCESS. AutoDeleter deleter(path); @@ -314,20 +321,37 @@ MSSymbolServerConverter::LocateSymbolFile(const MissingSymbolInfo &missing, // Do the cleanup here even though it will happen when symsrv goes out of // scope, to allow it to influence the return value. if (!symsrv.Cleanup()) { - fprintf(stderr, "LocateSymbolFile: SymCleanup: error %d for %s %s %s\n", + fprintf(stderr, "LocateFile: SymCleanup: error %d for %s %s %s\n", GetLastError(), - missing.debug_file.c_str(), - missing.debug_identifier.c_str(), - missing.version.c_str()); + debug_or_code_file.c_str(), + debug_or_code_id.c_str(), + version.c_str()); return LOCATE_FAILURE; } deleter.Release(); - *symbol_file = path; + printf("Downloaded: %s\n", path); + *file_name = path; return LOCATE_SUCCESS; } + +MSSymbolServerConverter::LocateResult +MSSymbolServerConverter::LocatePEFile(const MissingSymbolInfo &missing, + string *pe_file) { + return LocateFile(missing.code_file, missing.code_identifier, + missing.version, pe_file); +} + +MSSymbolServerConverter::LocateResult +MSSymbolServerConverter::LocateSymbolFile(const MissingSymbolInfo &missing, + string *symbol_file) { + return LocateFile(missing.debug_file, missing.debug_identifier, + missing.version, symbol_file); +} + + // static BOOL CALLBACK MSSymbolServerConverter::SymCallback(HANDLE process, ULONG action, @@ -341,7 +365,7 @@ BOOL CALLBACK MSSymbolServerConverter::SymCallback(HANDLE process, IMAGEHLP_CBA_EVENT *cba_event = reinterpret_cast(data); - // Put the string into a string object to be able to use string::find + // Put the string into a string object to be able to use string::find // for substring matching. This is important because the not-found // message does not use the entire string but is appended to the URL // that SymSrv attempted to retrieve. @@ -398,7 +422,7 @@ BOOL CALLBACK MSSymbolServerConverter::SymCallback(HANDLE process, // static BOOL CALLBACK MSSymbolServerConverter::SymFindFileInPathCallback( - char *filename, void *context) { + const char *filename, void *context) { // FALSE ends the search, indicating that the located symbol file is // satisfactory. return FALSE; @@ -408,8 +432,10 @@ MSSymbolServerConverter::LocateResult MSSymbolServerConverter::LocateAndConvertSymbolFile( const MissingSymbolInfo &missing, bool keep_symbol_file, + bool keep_pe_file, string *converted_symbol_file, - string *symbol_file) { + string *symbol_file, + string *out_pe_file) { assert(converted_symbol_file); converted_symbol_file->clear(); if (symbol_file) { @@ -426,11 +452,26 @@ MSSymbolServerConverter::LocateAndConvertSymbolFile( *symbol_file = pdb_file; } + // The conversion of a symbol file for a Windows 64-bit module requires + // loading of the executable file. If there is no executable file, convert + // using only the PDB file. Without an executable file, the conversion will + // fail for 64-bit modules but it should succeed for 32-bit modules. + string pe_file; + result = LocatePEFile(missing, &pe_file); + if (result != LOCATE_SUCCESS) { + fprintf(stderr, "WARNING: Could not download: %s\n", pe_file.c_str()); + } + + if (out_pe_file && keep_pe_file) { + *out_pe_file = pe_file; + } + // Conversion may fail because the file is corrupt. If a broken file is // kept in the local cache, LocateSymbolFile will not hit the network again // to attempt to locate it. To guard against problems like this, the // symbol file in the local cache will be removed if conversion fails. AutoDeleter pdb_deleter(pdb_file); + AutoDeleter pe_deleter(pe_file); // Be sure that it's a .pdb file, since we'll be replacing .pdb with .sym // for the converted file's name. @@ -438,19 +479,7 @@ MSSymbolServerConverter::LocateAndConvertSymbolFile( // strcasecmp is called _stricmp here. if (_stricmp(pdb_extension.c_str(), ".pdb") != 0) { fprintf(stderr, "LocateAndConvertSymbolFile: " - "LocateSymbolFile: no .pdb extension for %s %s %s %s\n", - missing.debug_file.c_str(), - missing.debug_identifier.c_str(), - missing.version.c_str(), - pdb_file.c_str()); - return LOCATE_FAILURE; - } - - // PDBSourceLineWriter wants the filename as a wstring, so convert it. - wstring pdb_file_w; - if (!WindowsStringUtils::safe_mbstowcs(pdb_file, &pdb_file_w)) { - fprintf(stderr, "LocateAndConvertSymbolFile: " - "WindowsStringUtils::safe_mbstowcs failed for %s %s %s %s\n", + "no .pdb extension for %s %s %s %s\n", missing.debug_file.c_str(), missing.debug_identifier.c_str(), missing.version.c_str(), @@ -459,15 +488,36 @@ MSSymbolServerConverter::LocateAndConvertSymbolFile( } PDBSourceLineWriter writer; - if (!writer.Open(pdb_file_w, PDBSourceLineWriter::PDB_FILE)) { - fprintf(stderr, "LocateAndConvertSymbolFile: " - "PDBSourceLineWriter::Open failed for %s %s %s %ws\n", - missing.debug_file.c_str(), - missing.debug_identifier.c_str(), - missing.version.c_str(), + wstring pe_file_w; + if (!WindowsStringUtils::safe_mbstowcs(pe_file, &pe_file_w)) { + fprintf(stderr, + "LocateAndConvertSymbolFile: " + "WindowsStringUtils::safe_mbstowcs failed for %s\n", + pe_file.c_str()); + return LOCATE_FAILURE; + } + wstring pdb_file_w; + if (!WindowsStringUtils::safe_mbstowcs(pdb_file, &pdb_file_w)) { + fprintf(stderr, + "LocateAndConvertSymbolFile: " + "WindowsStringUtils::safe_mbstowcs failed for %s\n", pdb_file_w.c_str()); return LOCATE_FAILURE; } + if (!writer.Open(pdb_file_w, PDBSourceLineWriter::PDB_FILE)) { + fprintf(stderr, + "ERROR: PDBSourceLineWriter::Open failed for %s %s %s %ws\n", + missing.debug_file.c_str(), missing.debug_identifier.c_str(), + missing.version.c_str(), pdb_file_w.c_str()); + return LOCATE_FAILURE; + } + if (!writer.SetCodeFile(pe_file_w)) { + fprintf(stderr, + "ERROR: PDBSourceLineWriter::SetCodeFile failed for %s %s %s %ws\n", + missing.debug_file.c_str(), missing.debug_identifier.c_str(), + missing.version.c_str(), pe_file_w.c_str()); + return LOCATE_FAILURE; + } *converted_symbol_file = pdb_file.substr(0, pdb_file.length() - 4) + ".sym"; @@ -514,6 +564,10 @@ MSSymbolServerConverter::LocateAndConvertSymbolFile( pdb_deleter.Release(); } + if (keep_pe_file) { + pe_deleter.Release(); + } + sym_deleter.Release(); return LOCATE_SUCCESS; diff --git a/src/tools/windows/converter/ms_symbol_server_converter.gyp b/src/tools/windows/converter/ms_symbol_server_converter.gyp new file mode 100644 index 00000000..57ec7906 --- /dev/null +++ b/src/tools/windows/converter/ms_symbol_server_converter.gyp @@ -0,0 +1,46 @@ +# Copyright 2013 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. + +{ + 'includes': [ + '../../../build/common.gypi', + ], + 'targets': [ + { + 'target_name': 'ms_symbol_server_converter', + 'type': 'static_library', + 'msvs_guid': '1463C4CD-23FC-4DE9-BFDE-283338200157', + 'sources': [ + 'ms_symbol_server_converter.cc', + ], + 'dependencies': [ + '../../../common/windows/common_windows.gyp:common_windows_lib', + ], + }, + ], +} diff --git a/src/tools/windows/converter/ms_symbol_server_converter.h b/src/tools/windows/converter/ms_symbol_server_converter.h index fffb7b8b..3db84f47 100644 --- a/src/tools/windows/converter/ms_symbol_server_converter.h +++ b/src/tools/windows/converter/ms_symbol_server_converter.h @@ -55,16 +55,15 @@ // attempting to load symbols from their server (.reload). // // This code has been tested with dbghelp.dll 6.5.3.7 and symsrv.dll 6.5.3.8, -// included with Microsoft Visual Studio 8 in Common7/IDE. This has also -// been tested with dbghelp.dll and symsrv.dll 6.6.7.5, included with that -// version of Debugging Tools for Windows, available at +// included with Microsoft Visual Studio 8 in Common7/IDE. This has also been +// tested with dbghelp.dll and symsrv.dll versions 6.6.7.5 and 6.12.2.633, +// included with the same versions of Debugging Tools for Windows, available at // http://www.microsoft.com/whdc/devtools/debugging/ . // // Author: Mark Mentovai - -#ifndef MS_SYMBOL_SERVER_CONVERTER_H__ -#define MS_SYMBOL_SERVER_CONVERTER_H__ +#ifndef TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_ +#define TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_ #include @@ -145,6 +144,13 @@ class MSSymbolServerConverter { MSSymbolServerConverter(const string &local_cache, const vector &symbol_servers); + // Locates the PE file (DLL or EXE) specified by the identifying information + // in |missing|, by checking the symbol stores identified when the object + // was created. When returning LOCATE_SUCCESS, pe_file is set to + // the pathname of the decompressed PE file as it is stored in the + // local cache. + LocateResult LocatePEFile(const MissingSymbolInfo &missing, string *pe_file); + // Locates the symbol file specified by the identifying information in // |missing|, by checking the symbol stores identified when the object // was created. When returning LOCATE_SUCCESS, symbol_file is set to @@ -159,16 +165,28 @@ class MSSymbolServerConverter { // value of LocateSymbolFile, or if LocateSymbolFile succeeds but // conversion fails, returns LOCATE_FAILURE. The pathname to the // pdb file and to the converted symbol file are returned in - // converted_symbol_file and symbol_file. symbol_file is optional and - // may be NULL. If only the converted symbol file is desired, set - // keep_symbol_file to false to indicate that the original symbol file - // (pdb) should be deleted after conversion. + // |converted_symbol_file|, |symbol_file|, and |pe_file|. |symbol_file| and + // |pe_file| are optional and may be NULL. If only the converted symbol file + // is desired, set |keep_symbol_file| and |keep_pe_file| to false to indicate + // that the original symbol file (pdb) and executable file (exe, dll) should + // be deleted after conversion. LocateResult LocateAndConvertSymbolFile(const MissingSymbolInfo &missing, bool keep_symbol_file, + bool keep_pe_file, string *converted_symbol_file, - string *symbol_file); + string *symbol_file, + string *pe_file); private: + // Locates the PDB or PE file (DLL or EXE) specified by the identifying + // information in |debug_or_code_file| and |debug_or_code_id|, by checking + // the symbol stores identified when the object was created. When + // returning LOCATE_SUCCESS, file_name is set to the pathname of the + // decompressed PDB or PE file file as it is stored in the local cache. + LocateResult LocateFile(const string &debug_or_code_file, + const string &debug_or_code_id, + const string &version, string *file_name); + // Called by various SymSrv functions to report status as progress is made // and to allow the callback to influence processing. Messages sent to this // callback can be used to distinguish between the various failure modes @@ -181,7 +199,7 @@ class MSSymbolServerConverter { // SymFindFileInPath actually seems to accept NULL for a callback function // and behave properly for our needs in that case, but the documentation // doesn't mention it, so this little callback is provided. - static BOOL CALLBACK SymFindFileInPathCallback(char *filename, + static BOOL CALLBACK SymFindFileInPathCallback(const char *filename, void *context); // The search path used by SymSrv, built based on the arguments to the @@ -198,4 +216,4 @@ class MSSymbolServerConverter { } // namespace google_breakpad -#endif // MS_SYMBOL_SERVER_CONVERTER_H__ +#endif // TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_ diff --git a/src/tools/windows/converter/ms_symbol_server_converter.vcproj b/src/tools/windows/converter/ms_symbol_server_converter.vcproj index 6a72ec03..ee1263a1 100644 --- a/src/tools/windows/converter/ms_symbol_server_converter.vcproj +++ b/src/tools/windows/converter/ms_symbol_server_converter.vcproj @@ -1,319 +1,368 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Debug + x64 + + + Purify + Win32 + + + Purify + x64 + + + Release + Win32 + + + Release + x64 + + + + {1463C4CD-23FC-4DE9-BFDE-283338200157} + Win32Proj + ms_symbol_server_converter + true + + + + Unicode + StaticLibrary + + + + + + + + + $(ExecutablePath);$(MSBuildProjectDirectory)\..\..\..\third_party\cygwin\bin\;$(MSBuildProjectDirectory)\..\..\..\third_party\python_26\ + $(SolutionDir)$(Configuration)\ + $(OutDir)obj\$(ProjectName)\ + false + false + false + false + true + true + $(ProjectName) + $(OutDir)lib\$(ProjectName)$(TargetExt) + + + + ..\..\..;$(VSInstallDir)\DIA SDK\include;..\..\..\third_party\platformsdk_win7\files\Include;$(VSInstallDir)\VC\atlmfc\include;%(AdditionalIncludeDirectories) + /MP %(AdditionalOptions) + EnableFastChecks + true + ProgramDatabase + 4100;4127;4396;4503;4512;4819;4995;4702;4800;%(DisableSpecificWarnings) + false + true + false + Disabled + _DEBUG;_WIN32_WINNT=0x0600;WINVER=0x0600;WIN32;_WINDOWS;_HAS_EXCEPTIONS=0;NOMINMAX;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_SECURE_ATL;CHROMIUM_BUILD;TOOLKIT_VIEWS=1;ENABLE_GPU=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + MultiThreadedDebug + false + true + Level4 + + + ../../../third_party/platformsdk_win7/files/Lib;%(AdditionalLibraryDirectories) + /ignore:4221 %(AdditionalOptions) + $(OutDir)lib\$(ProjectName)$(TargetExt) + + + wininet.lib;version.lib;msimg32.lib;ws2_32.lib;usp10.lib;psapi.lib;dbghelp.lib;$(VSInstallDir)\DIA SDK\lib\diaguids.lib;imagehlp.lib + ../../../third_party/platformsdk_win7/files/Lib;%(AdditionalLibraryDirectories) + /safeseh /dynamicbase /ignore:4199 /ignore:4221 /nxcompat %(AdditionalOptions) + dbghelp.dll;dwmapi.dll;uxtheme.dll;%(DelayLoadDLLs) + false + true + $(OutDir)lib\$(TargetName).lib + $(OutDir)$(TargetName).map + Console + MachineX86 + + + dlldata.c + true + %(Filename).h + %(Filename)_i.c + $(IntDir) + %(Filename)_p.c + %(Filename).tlb + + + ../../..;..\..\..;$(VSInstallDir)\DIA SDK\include;..\..\..\third_party\platformsdk_win7\files\Include;$(VSInstallDir)\VC\atlmfc\include;%(AdditionalIncludeDirectories) + 0x0409 + _DEBUG;_WIN32_WINNT=0x0600;WINVER=0x0600;WIN32;_WINDOWS;_HAS_EXCEPTIONS=0;NOMINMAX;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_SECURE_ATL;CHROMIUM_BUILD;TOOLKIT_VIEWS=1;ENABLE_GPU=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + + + + + ..\..\..;$(VSInstallDir)\DIA SDK\include;..\..\..\third_party\platformsdk_win7\files\Include;$(VSInstallDir)\VC\atlmfc\include;%(AdditionalIncludeDirectories) + /MP %(AdditionalOptions) + EnableFastChecks + true + ProgramDatabase + 4100;4127;4396;4503;4512;4819;4995;4702;4800;%(DisableSpecificWarnings) + false + true + false + Disabled + _DEBUG;_WIN32_WINNT=0x0600;WINVER=0x0600;WIN32;_WINDOWS;_HAS_EXCEPTIONS=0;NOMINMAX;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_SECURE_ATL;CHROMIUM_BUILD;TOOLKIT_VIEWS=1;ENABLE_GPU=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NO_TCMALLOC;%(PreprocessorDefinitions) + MultiThreadedDebug + false + true + Level4 + + + ../../../third_party/platformsdk_win7/files/Lib/x64;%(AdditionalLibraryDirectories) + /ignore:4221 %(AdditionalOptions) + $(OutDir)lib\$(ProjectName)$(TargetExt) + + + wininet.lib;version.lib;msimg32.lib;ws2_32.lib;usp10.lib;psapi.lib;dbghelp.lib;$(VSInstallDir)\DIA SDK\lib\diaguids.lib;imagehlp.lib + ../../../third_party/platformsdk_win7/files/Lib/x64;%(AdditionalLibraryDirectories) + /dynamicbase /ignore:4199 /ignore:4221 /nxcompat %(AdditionalOptions) + dbghelp.dll;dwmapi.dll;uxtheme.dll;%(DelayLoadDLLs) + false + true + $(OutDir)lib\$(TargetName).lib + $(OutDir)$(TargetName).map + Console + MachineX64 + + + dlldata.c + true + %(Filename).h + %(Filename)_i.c + $(IntDir) + %(Filename)_p.c + %(Filename).tlb + + + ../../..;..\..\..;$(VSInstallDir)\DIA SDK\include;..\..\..\third_party\platformsdk_win7\files\Include;$(VSInstallDir)\VC\atlmfc\include;%(AdditionalIncludeDirectories) + 0x0409 + _DEBUG;_WIN32_WINNT=0x0600;WINVER=0x0600;WIN32;_WINDOWS;_HAS_EXCEPTIONS=0;NOMINMAX;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_SECURE_ATL;CHROMIUM_BUILD;TOOLKIT_VIEWS=1;ENABLE_GPU=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NO_TCMALLOC;%(PreprocessorDefinitions) + + + + + ..\..\..;$(VSInstallDir)\DIA SDK\include;..\..\..\third_party\platformsdk_win7\files\Include;$(VSInstallDir)\VC\atlmfc\include;%(AdditionalIncludeDirectories) + /MP %(AdditionalOptions) + true + ProgramDatabase + 4100;4127;4396;4503;4512;4819;4995;4702;4800;%(DisableSpecificWarnings) + false + true + false + MaxSpeed + _WIN32_WINNT=0x0600;WINVER=0x0600;WIN32;_WINDOWS;_HAS_EXCEPTIONS=0;NOMINMAX;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_SECURE_ATL;CHROMIUM_BUILD;TOOLKIT_VIEWS=1;ENABLE_GPU=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NDEBUG;NVALGRIND;%(PreprocessorDefinitions) + MultiThreaded + false + true + Level4 + + + ../../../third_party/platformsdk_win7/files/Lib;%(AdditionalLibraryDirectories) + /ignore:4221 %(AdditionalOptions) + $(OutDir)lib\$(ProjectName)$(TargetExt) + + + wininet.lib;version.lib;msimg32.lib;ws2_32.lib;usp10.lib;psapi.lib;dbghelp.lib;$(VSInstallDir)\DIA SDK\lib\diaguids.lib;imagehlp.lib + ../../../third_party/platformsdk_win7/files/Lib;%(AdditionalLibraryDirectories) + /safeseh /dynamicbase /ignore:4199 /ignore:4221 /nxcompat %(AdditionalOptions) + dbghelp.dll;dwmapi.dll;uxtheme.dll;%(DelayLoadDLLs) + false + true + $(OutDir)lib\$(TargetName).lib + $(OutDir)$(TargetName).map + Console + MachineX86 + + + dlldata.c + true + %(Filename).h + %(Filename)_i.c + $(IntDir) + %(Filename)_p.c + %(Filename).tlb + + + ../../..;..\..\..;$(VSInstallDir)\DIA SDK\include;..\..\..\third_party\platformsdk_win7\files\Include;$(VSInstallDir)\VC\atlmfc\include;%(AdditionalIncludeDirectories) + 0x0409 + _WIN32_WINNT=0x0600;WINVER=0x0600;WIN32;_WINDOWS;_HAS_EXCEPTIONS=0;NOMINMAX;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_SECURE_ATL;CHROMIUM_BUILD;TOOLKIT_VIEWS=1;ENABLE_GPU=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NDEBUG;NVALGRIND;%(PreprocessorDefinitions);%(PreprocessorDefinitions) + + + + + ..\..\..;$(VSInstallDir)\DIA SDK\include;..\..\..\third_party\platformsdk_win7\files\Include;$(VSInstallDir)\VC\atlmfc\include;%(AdditionalIncludeDirectories) + /MP %(AdditionalOptions) + false + ProgramDatabase + 4100;4127;4396;4503;4512;4819;4995;4702;4800;%(DisableSpecificWarnings) + false + true + false + Disabled + _WIN32_WINNT=0x0600;WINVER=0x0600;WIN32;_WINDOWS;_HAS_EXCEPTIONS=0;NOMINMAX;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_SECURE_ATL;CHROMIUM_BUILD;TOOLKIT_VIEWS=1;ENABLE_GPU=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NO_TCMALLOC;NDEBUG;NVALGRIND;PURIFY;%(PreprocessorDefinitions) + MultiThreaded + false + true + Level4 + + + ../../../third_party/platformsdk_win7/files/Lib/x64;%(AdditionalLibraryDirectories) + /ignore:4221 %(AdditionalOptions) + $(OutDir)lib\$(ProjectName)$(TargetExt) + + + wininet.lib;version.lib;msimg32.lib;ws2_32.lib;usp10.lib;psapi.lib;dbghelp.lib;$(VSInstallDir)\DIA SDK\lib\diaguids.lib;imagehlp.lib + ../../../third_party/platformsdk_win7/files/Lib/x64;%(AdditionalLibraryDirectories) + /dynamicbase /ignore:4199 /ignore:4221 /nxcompat %(AdditionalOptions) + dbghelp.dll;dwmapi.dll;uxtheme.dll;%(DelayLoadDLLs) + false + false + true + $(OutDir)lib\$(TargetName).lib + $(OutDir)$(TargetName).map + Console + MachineX64 + + + dlldata.c + true + %(Filename).h + %(Filename)_i.c + $(IntDir) + %(Filename)_p.c + %(Filename).tlb + + + ../../..;..\..\..;$(VSInstallDir)\DIA SDK\include;..\..\..\third_party\platformsdk_win7\files\Include;$(VSInstallDir)\VC\atlmfc\include;%(AdditionalIncludeDirectories) + 0x0409 + _WIN32_WINNT=0x0600;WINVER=0x0600;WIN32;_WINDOWS;_HAS_EXCEPTIONS=0;NOMINMAX;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_SECURE_ATL;CHROMIUM_BUILD;TOOLKIT_VIEWS=1;ENABLE_GPU=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NO_TCMALLOC;NDEBUG;NVALGRIND;PURIFY;%(PreprocessorDefinitions);%(PreprocessorDefinitions) + + + + + ..\..\..;$(VSInstallDir)\DIA SDK\include;..\..\..\third_party\platformsdk_win7\files\Include;$(VSInstallDir)\VC\atlmfc\include;%(AdditionalIncludeDirectories) + /MP %(AdditionalOptions) + true + ProgramDatabase + 4100;4127;4396;4503;4512;4819;4995;4702;4800;%(DisableSpecificWarnings) + false + true + false + true + MaxSpeed + _WIN32_WINNT=0x0600;WINVER=0x0600;WIN32;_WINDOWS;_HAS_EXCEPTIONS=0;NOMINMAX;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_SECURE_ATL;CHROMIUM_BUILD;TOOLKIT_VIEWS=1;ENABLE_GPU=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NDEBUG;NVALGRIND;%(PreprocessorDefinitions) + MultiThreaded + false + true + true + Level4 + + + ../../../third_party/platformsdk_win7/files/Lib;%(AdditionalLibraryDirectories) + /ignore:4221 %(AdditionalOptions) + $(OutDir)lib\$(ProjectName)$(TargetExt) + + + wininet.lib;version.lib;msimg32.lib;ws2_32.lib;usp10.lib;psapi.lib;dbghelp.lib;$(VSInstallDir)\DIA SDK\lib\diaguids.lib;imagehlp.lib + ../../../third_party/platformsdk_win7/files/Lib;%(AdditionalLibraryDirectories) + /safeseh /dynamicbase /ignore:4199 /ignore:4221 /nxcompat %(AdditionalOptions) + dbghelp.dll;dwmapi.dll;uxtheme.dll;%(DelayLoadDLLs) + true + false + true + $(OutDir)lib\$(TargetName).lib + $(OutDir)$(TargetName).map + true + Console + MachineX86 + + + dlldata.c + true + %(Filename).h + %(Filename)_i.c + $(IntDir) + %(Filename)_p.c + %(Filename).tlb + + + ../../..;..\..\..;$(VSInstallDir)\DIA SDK\include;..\..\..\third_party\platformsdk_win7\files\Include;$(VSInstallDir)\VC\atlmfc\include;%(AdditionalIncludeDirectories) + 0x0409 + _WIN32_WINNT=0x0600;WINVER=0x0600;WIN32;_WINDOWS;_HAS_EXCEPTIONS=0;NOMINMAX;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_SECURE_ATL;CHROMIUM_BUILD;TOOLKIT_VIEWS=1;ENABLE_GPU=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NDEBUG;NVALGRIND;%(PreprocessorDefinitions);%(PreprocessorDefinitions) + + + + + ..\..\..;$(VSInstallDir)\DIA SDK\include;..\..\..\third_party\platformsdk_win7\files\Include;$(VSInstallDir)\VC\atlmfc\include;%(AdditionalIncludeDirectories) + /MP %(AdditionalOptions) + true + ProgramDatabase + 4100;4127;4396;4503;4512;4819;4995;4702;4800;%(DisableSpecificWarnings) + false + true + false + MaxSpeed + _WIN32_WINNT=0x0600;WINVER=0x0600;WIN32;_WINDOWS;_HAS_EXCEPTIONS=0;NOMINMAX;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_SECURE_ATL;CHROMIUM_BUILD;TOOLKIT_VIEWS=1;ENABLE_GPU=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NO_TCMALLOC;NDEBUG;NVALGRIND;%(PreprocessorDefinitions) + MultiThreaded + false + true + Level4 + + + ../../../third_party/platformsdk_win7/files/Lib/x64;%(AdditionalLibraryDirectories) + /ignore:4221 %(AdditionalOptions) + $(OutDir)lib\$(ProjectName)$(TargetExt) + + + wininet.lib;version.lib;msimg32.lib;ws2_32.lib;usp10.lib;psapi.lib;dbghelp.lib;$(VSInstallDir)\DIA SDK\lib\diaguids.lib;imagehlp.lib + ../../../third_party/platformsdk_win7/files/Lib/x64;%(AdditionalLibraryDirectories) + /dynamicbase /ignore:4199 /ignore:4221 /nxcompat %(AdditionalOptions) + dbghelp.dll;dwmapi.dll;uxtheme.dll;%(DelayLoadDLLs) + false + true + $(OutDir)lib\$(TargetName).lib + $(OutDir)$(TargetName).map + Console + MachineX64 + + + dlldata.c + true + %(Filename).h + %(Filename)_i.c + $(IntDir) + %(Filename)_p.c + %(Filename).tlb + + + ../../..;..\..\..;$(VSInstallDir)\DIA SDK\include;..\..\..\third_party\platformsdk_win7\files\Include;$(VSInstallDir)\VC\atlmfc\include;%(AdditionalIncludeDirectories) + 0x0409 + _WIN32_WINNT=0x0600;WINVER=0x0600;WIN32;_WINDOWS;_HAS_EXCEPTIONS=0;NOMINMAX;_CRT_RAND_S;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;WIN32_LEAN_AND_MEAN;_SECURE_ATL;CHROMIUM_BUILD;TOOLKIT_VIEWS=1;ENABLE_GPU=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NO_TCMALLOC;NDEBUG;NVALGRIND;%(PreprocessorDefinitions);%(PreprocessorDefinitions) + + + + + + + + + + +