mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2024-11-28 00:44:16 +01:00
Library to handle SymSrv integration (#111). r=bryner
http://groups.google.com/group/airbag-dev/browse_thread/thread/b40e66d1d57e61b5 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@105 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
48dab62c2d
commit
50e299b00e
@ -51,6 +51,7 @@
|
|||||||
|
|
||||||
namespace google_airbag {
|
namespace google_airbag {
|
||||||
|
|
||||||
|
using std::string;
|
||||||
using std::wstring;
|
using std::wstring;
|
||||||
|
|
||||||
class WindowsStringUtils {
|
class WindowsStringUtils {
|
||||||
@ -72,6 +73,11 @@ class WindowsStringUtils {
|
|||||||
static void safe_wcsncpy(wchar_t *destination, size_t destination_size,
|
static void safe_wcsncpy(wchar_t *destination, size_t destination_size,
|
||||||
const wchar_t *source, size_t count);
|
const wchar_t *source, size_t count);
|
||||||
|
|
||||||
|
// Performs multi-byte to wide character conversion on C++ strings, using
|
||||||
|
// mbstowcs_s (MSVC8) or mbstowcs (pre-MSVC8). Returns false on failure,
|
||||||
|
// without setting wcs.
|
||||||
|
static bool safe_mbstowcs(const string &mbs, wstring *wcs);
|
||||||
|
|
||||||
// Returns the base name of a file, e.g. strips off the path.
|
// Returns the base name of a file, e.g. strips off the path.
|
||||||
static wstring GetBaseName(const wstring &filename);
|
static wstring GetBaseName(const wstring &filename);
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#include "common/windows/string_utils-inl.h"
|
#include "common/windows/string_utils-inl.h"
|
||||||
|
|
||||||
namespace google_airbag {
|
namespace google_airbag {
|
||||||
@ -41,4 +43,50 @@ wstring WindowsStringUtils::GetBaseName(const wstring &filename) {
|
|||||||
return base_name;
|
return base_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool WindowsStringUtils::safe_mbstowcs(const string &mbs, wstring *wcs) {
|
||||||
|
assert(wcs);
|
||||||
|
|
||||||
|
// First, determine the length of the destination buffer.
|
||||||
|
size_t wcs_length;
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||||
|
errno_t err;
|
||||||
|
if ((err = mbstowcs_s(&wcs_length, NULL, 0, mbs.c_str(), _TRUNCATE)) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else // _MSC_VER >= 1400
|
||||||
|
if ((wcs_length = mbstowcs(NULL, mbs.c_str(), mbs.length())) < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Leave space for the 0-terminator.
|
||||||
|
++wcs_length;
|
||||||
|
#endif // _MSC_VER >= 1400
|
||||||
|
|
||||||
|
// TODO(mmentovai): move scoped_ptr into common and use it for wcs_c.
|
||||||
|
wchar_t *wcs_c = new wchar_t[wcs_length];
|
||||||
|
|
||||||
|
// Now, convert.
|
||||||
|
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||||
|
if ((err = mbstowcs_s(NULL, wcs_c, wcs_length, mbs.c_str(),
|
||||||
|
_TRUNCATE)) != 0) {
|
||||||
|
delete[] wcs_c;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else // _MSC_VER >= 1400
|
||||||
|
if (mbstowcs(wcs_c, mbs.c_str(), mbs.length()) < 0) {
|
||||||
|
delete[] wcs_c;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure presence of 0-terminator.
|
||||||
|
wcs_c[wcs_length - 1] = '\0';
|
||||||
|
#endif // _MSC_VER >= 1400
|
||||||
|
|
||||||
|
*wcs = wcs_c;
|
||||||
|
delete[] wcs_c;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace google_airbag
|
} // namespace google_airbag
|
||||||
|
516
src/tools/windows/converter/ms_symbol_server_converter.cc
Normal file
516
src/tools/windows/converter/ms_symbol_server_converter.cc
Normal file
@ -0,0 +1,516 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// ms_symbol_server_converter.cc: Obtain symbol files from a Microsoft
|
||||||
|
// symbol server, and convert them to Airbag's dumped format.
|
||||||
|
//
|
||||||
|
// See ms_symbol_server_converter.h for documentation.
|
||||||
|
//
|
||||||
|
// Author: Mark Mentovai
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <DbgHelp.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include "tools/windows/converter/ms_symbol_server_converter.h"
|
||||||
|
#include "common/windows/pdb_source_line_writer.h"
|
||||||
|
#include "common/windows/string_utils-inl.h"
|
||||||
|
|
||||||
|
// SYMOPT_NO_PROMPTS is not defined in earlier platform SDKs. Define it
|
||||||
|
// in that case, in the event that this code is used with a newer version
|
||||||
|
// of DbgHelp at runtime that recognizes the option. The presence of this
|
||||||
|
// bit in the symbol options should not harm earlier versions of DbgHelp.
|
||||||
|
#ifndef SYMOPT_NO_PROMPTS
|
||||||
|
#define SYMOPT_NO_PROMPTS 0x00080000
|
||||||
|
#endif // SYMOPT_NO_PROMPTS
|
||||||
|
|
||||||
|
namespace google_airbag {
|
||||||
|
|
||||||
|
// Use sscanf_s if it is available, to quench the warning about scanf being
|
||||||
|
// deprecated. Use scanf where sscanf_is not available. Note that the
|
||||||
|
// parameters passed to sscanf and sscanf_s are only compatible as long as
|
||||||
|
// fields of type c, C, s, S, and [ are not used.
|
||||||
|
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||||
|
#define SSCANF sscanf_s
|
||||||
|
#else // _MSC_VER >= 1400
|
||||||
|
#define SSCANF sscanf
|
||||||
|
#endif // _MSC_VER >= 1400
|
||||||
|
|
||||||
|
bool GUIDOrSignatureIdentifier::InitializeFromString(
|
||||||
|
const string &identifier) {
|
||||||
|
type_ = TYPE_NONE;
|
||||||
|
|
||||||
|
size_t length = identifier.length();
|
||||||
|
|
||||||
|
if (length > 32 && length <= 40) {
|
||||||
|
// GUID
|
||||||
|
if (SSCANF(identifier.c_str(),
|
||||||
|
"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%X",
|
||||||
|
&guid_.Data1, &guid_.Data2, &guid_.Data3,
|
||||||
|
&guid_.Data4[0], &guid_.Data4[1],
|
||||||
|
&guid_.Data4[2], &guid_.Data4[3],
|
||||||
|
&guid_.Data4[4], &guid_.Data4[5],
|
||||||
|
&guid_.Data4[6], &guid_.Data4[7],
|
||||||
|
&age_) != 12) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
type_ = TYPE_GUID;
|
||||||
|
} else if (length > 8 && length <= 15) {
|
||||||
|
// Signature
|
||||||
|
if (SSCANF(identifier.c_str(), "%08X%x", &signature_, &age_) != 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
type_ = TYPE_SIGNATURE;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef SSCANF
|
||||||
|
|
||||||
|
MSSymbolServerConverter::MSSymbolServerConverter(
|
||||||
|
const string &local_cache, const vector<string> &symbol_servers)
|
||||||
|
: symbol_path_(),
|
||||||
|
fail_dns_(false),
|
||||||
|
fail_timeout_(false),
|
||||||
|
fail_not_found_(false) {
|
||||||
|
// Setting local_cache can be done without verifying that it exists because
|
||||||
|
// SymSrv will create it if it is missing - any creation failures will occur
|
||||||
|
// at that time, so there's nothing to check here, making it safe to
|
||||||
|
// assign this in the constructor.
|
||||||
|
|
||||||
|
assert(symbol_servers.size() > 0);
|
||||||
|
|
||||||
|
// These are characters that are interpreted as having special meanings in
|
||||||
|
// symbol_path_.
|
||||||
|
const char *kInvalidCharacters = "*;";
|
||||||
|
assert(local_cache.find_first_of(kInvalidCharacters) == string::npos);
|
||||||
|
|
||||||
|
for (vector<string>::const_iterator symbol_server = symbol_servers.begin();
|
||||||
|
symbol_server != symbol_servers.end();
|
||||||
|
++symbol_server) {
|
||||||
|
// The symbol path format is explained by
|
||||||
|
// http://msdn.microsoft.com/library/en-us/debug/base/using_symsrv.asp .
|
||||||
|
// "srv*" is the same as "symsrv*symsrv.dll*", which means that
|
||||||
|
// symsrv.dll is to be responsible for locating symbols. symsrv.dll
|
||||||
|
// interprets the rest of the string as a series of symbol stores separated
|
||||||
|
// by '*'. "srv*local_cache*symbol_server" means to check local_cache
|
||||||
|
// first for the symbol file, and if it is not found there, to check
|
||||||
|
// symbol_server. Symbol files found on the symbol server will be placed
|
||||||
|
// in the local cache, decompressed.
|
||||||
|
//
|
||||||
|
// Multiple specifications in this format may be presented, separated by
|
||||||
|
// semicolons.
|
||||||
|
|
||||||
|
assert((*symbol_server).find_first_of(kInvalidCharacters) == string::npos);
|
||||||
|
symbol_path_ += "srv*" + local_cache + "*" + *symbol_server + ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip the trailing semicolon.
|
||||||
|
symbol_path_.erase(symbol_path_.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A stack-based class that manages SymInitialize and SymCleanup calls.
|
||||||
|
class AutoSymSrv {
|
||||||
|
public:
|
||||||
|
AutoSymSrv() : initialized_(false) {}
|
||||||
|
|
||||||
|
~AutoSymSrv() {
|
||||||
|
if (!Cleanup()) {
|
||||||
|
// Print the error message here, because destructors have no return
|
||||||
|
// value.
|
||||||
|
fprintf(stderr, "~AutoSymSrv: SymCleanup: error %d\n", GetLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Initialize(HANDLE process, char *path, bool invade_process) {
|
||||||
|
process_ = process;
|
||||||
|
initialized_ = SymInitialize(process, path, invade_process) == TRUE;
|
||||||
|
return initialized_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Cleanup() {
|
||||||
|
if (initialized_) {
|
||||||
|
if (SymCleanup(process_)) {
|
||||||
|
initialized_ = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE process_;
|
||||||
|
bool initialized_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A stack-based class that "owns" a pathname and deletes it when destroyed,
|
||||||
|
// unless told not to by having its Release() method called. Early deletions
|
||||||
|
// are supported by calling Delete().
|
||||||
|
class AutoDeleter {
|
||||||
|
public:
|
||||||
|
AutoDeleter(const string &path) : path_(path) {}
|
||||||
|
|
||||||
|
~AutoDeleter() {
|
||||||
|
int error;
|
||||||
|
if ((error = Delete()) != 0) {
|
||||||
|
// Print the error message here, because destructors have no return
|
||||||
|
// value.
|
||||||
|
fprintf(stderr, "~AutoDeleter: Delete: error %d for %s\n",
|
||||||
|
error, path_.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Delete() {
|
||||||
|
if (path_.empty())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int error = remove(path_.c_str());
|
||||||
|
Release();
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Release() {
|
||||||
|
path_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
string path_;
|
||||||
|
};
|
||||||
|
|
||||||
|
MSSymbolServerConverter::LocateResult
|
||||||
|
MSSymbolServerConverter::LocateSymbolFile(const MissingSymbolInfo &missing,
|
||||||
|
string *symbol_file) {
|
||||||
|
assert(symbol_file);
|
||||||
|
symbol_file->clear();
|
||||||
|
|
||||||
|
GUIDOrSignatureIdentifier identifier;
|
||||||
|
if (!identifier.InitializeFromString(missing.debug_identifier)) {
|
||||||
|
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());
|
||||||
|
return LOCATE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE process = GetCurrentProcess(); // CloseHandle is not needed.
|
||||||
|
AutoSymSrv symsrv;
|
||||||
|
if (!symsrv.Initialize(process,
|
||||||
|
const_cast<char *>(symbol_path_.c_str()),
|
||||||
|
false)) {
|
||||||
|
fprintf(stderr, "LocateSymbolFile: SymInitialize: error %d for %s %s %s\n",
|
||||||
|
GetLastError(),
|
||||||
|
missing.debug_file.c_str(),
|
||||||
|
missing.debug_identifier.c_str(),
|
||||||
|
missing.version.c_str());
|
||||||
|
return LOCATE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SymRegisterCallback64(process, SymCallback,
|
||||||
|
reinterpret_cast<ULONG64>(this))) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"LocateSymbolFile: SymRegisterCallback64: error %d for %s %s %s\n",
|
||||||
|
GetLastError(),
|
||||||
|
missing.debug_file.c_str(),
|
||||||
|
missing.debug_identifier.c_str(),
|
||||||
|
missing.version.c_str());
|
||||||
|
return LOCATE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SYMOPT_DEBUG arranges for SymCallback to be called with additional
|
||||||
|
// debugging information. This is used to determine the nature of failures.
|
||||||
|
DWORD options = SymGetOptions() | SYMOPT_DEBUG | SYMOPT_NO_PROMPTS |
|
||||||
|
SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_SECURE;
|
||||||
|
SymSetOptions(options);
|
||||||
|
|
||||||
|
// SymCallback will set these as needed inisde the SymFindFileInPath call.
|
||||||
|
fail_dns_ = false;
|
||||||
|
fail_timeout_ = false;
|
||||||
|
fail_not_found_ = false;
|
||||||
|
|
||||||
|
// Do the lookup.
|
||||||
|
char path[MAX_PATH];
|
||||||
|
if (!SymFindFileInPath(
|
||||||
|
process, NULL,
|
||||||
|
const_cast<char *>(missing.debug_file.c_str()),
|
||||||
|
const_cast<void *>(identifier.guid_or_signature_pointer()),
|
||||||
|
identifier.age(), 0,
|
||||||
|
identifier.type() == GUIDOrSignatureIdentifier::TYPE_GUID ?
|
||||||
|
SSRVOPT_GUIDPTR : SSRVOPT_DWORDPTR,
|
||||||
|
path, SymFindFileInPathCallback, this)) {
|
||||||
|
DWORD error = GetLastError();
|
||||||
|
if (error == ERROR_FILE_NOT_FOUND) {
|
||||||
|
// This can be returned for a number of reasons. Use the crumbs
|
||||||
|
// collected by SymCallback to determine which one is relevant.
|
||||||
|
|
||||||
|
// These errors are possibly transient.
|
||||||
|
if (fail_dns_ || fail_timeout_) {
|
||||||
|
return LOCATE_RETRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is an authoritiative file-not-found message.
|
||||||
|
if (fail_not_found_) {
|
||||||
|
return LOCATE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the error is FILE_NOT_FOUND but none of the known error
|
||||||
|
// conditions are matched, fall through to LOCATE_FAILURE.
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"LocateSymbolFile: SymFindFileInPath: error %d for %s %s %s\n",
|
||||||
|
error,
|
||||||
|
missing.debug_file.c_str(),
|
||||||
|
missing.debug_identifier.c_str(),
|
||||||
|
missing.version.c_str());
|
||||||
|
return LOCATE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The AutoDeleter ensures that the file is only kept when returning
|
||||||
|
// LOCATE_SUCCESS.
|
||||||
|
AutoDeleter deleter(path);
|
||||||
|
|
||||||
|
// 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",
|
||||||
|
GetLastError(),
|
||||||
|
missing.debug_file.c_str(),
|
||||||
|
missing.debug_identifier.c_str(),
|
||||||
|
missing.version.c_str());
|
||||||
|
return LOCATE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleter.Release();
|
||||||
|
|
||||||
|
*symbol_file = path;
|
||||||
|
return LOCATE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
BOOL CALLBACK MSSymbolServerConverter::SymCallback(HANDLE process,
|
||||||
|
ULONG action,
|
||||||
|
ULONG64 data,
|
||||||
|
ULONG64 context) {
|
||||||
|
MSSymbolServerConverter *self =
|
||||||
|
reinterpret_cast<MSSymbolServerConverter *>(context);
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case CBA_EVENT: {
|
||||||
|
IMAGEHLP_CBA_EVENT *cba_event =
|
||||||
|
reinterpret_cast<IMAGEHLP_CBA_EVENT *>(data);
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
string desc(cba_event->desc);
|
||||||
|
|
||||||
|
// desc_action maps strings (in desc) to boolean pointers that are to
|
||||||
|
// be set to true if the string matches.
|
||||||
|
struct desc_action {
|
||||||
|
const char *desc; // The substring to match.
|
||||||
|
bool *action; // On match, this pointer will be set to true.
|
||||||
|
};
|
||||||
|
|
||||||
|
static const desc_action desc_actions[] = {
|
||||||
|
// When a DNS error occurs, it could be indiciative of network
|
||||||
|
// problems.
|
||||||
|
{ "SYMSRV: The server name or address could not be resolved\n",
|
||||||
|
&self->fail_dns_ },
|
||||||
|
|
||||||
|
// This message is produced if no connection is opened.
|
||||||
|
{ "SYMSRV: A connection with the server could not be established\n",
|
||||||
|
&self->fail_timeout_ },
|
||||||
|
|
||||||
|
// This message is produced if a connection is established but the
|
||||||
|
// server fails to respond to the HTTP request.
|
||||||
|
{ "SYMSRV: The operation timed out\n",
|
||||||
|
&self->fail_timeout_ },
|
||||||
|
|
||||||
|
// This message is produced when the requested file is not found,
|
||||||
|
// even if one or more of the above messages are also produced.
|
||||||
|
// It's trapped to distinguish between not-found and unknown-failure
|
||||||
|
// conditions. Note that this message will not be produced if a
|
||||||
|
// connection is established and the server begins to respond to the
|
||||||
|
// HTTP request but does not finish transmitting the file.
|
||||||
|
{ " not found\n",
|
||||||
|
&self->fail_not_found_ }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int desc_action_index = 0;
|
||||||
|
desc_action_index < sizeof(desc_actions) / sizeof(desc_action);
|
||||||
|
++desc_action_index) {
|
||||||
|
if (desc.find(desc_actions[desc_action_index].desc) != string::npos) {
|
||||||
|
*(desc_actions[desc_action_index].action) = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is a mere fly on the wall. Treat everything as unhandled.
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
BOOL CALLBACK MSSymbolServerConverter::SymFindFileInPathCallback(
|
||||||
|
char *filename, void *context) {
|
||||||
|
// FALSE ends the search, indicating that the located symbol file is
|
||||||
|
// satisfactory.
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MSSymbolServerConverter::LocateResult
|
||||||
|
MSSymbolServerConverter::LocateAndConvertSymbolFile(
|
||||||
|
const MissingSymbolInfo &missing,
|
||||||
|
bool keep_symbol_file,
|
||||||
|
string *converted_symbol_file,
|
||||||
|
string *symbol_file) {
|
||||||
|
assert(converted_symbol_file);
|
||||||
|
converted_symbol_file->clear();
|
||||||
|
if (symbol_file) {
|
||||||
|
symbol_file->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
string pdb_file;
|
||||||
|
LocateResult result = LocateSymbolFile(missing, &pdb_file);
|
||||||
|
if (result != LOCATE_SUCCESS) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (symbol_file && keep_symbol_file) {
|
||||||
|
*symbol_file = pdb_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);
|
||||||
|
|
||||||
|
// Be sure that it's a .pdb file, since we'll be replacing .pdb with .sym
|
||||||
|
// for the converted file's name.
|
||||||
|
string pdb_extension = pdb_file.substr(pdb_file.length() - 4);
|
||||||
|
// 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",
|
||||||
|
missing.debug_file.c_str(),
|
||||||
|
missing.debug_identifier.c_str(),
|
||||||
|
missing.version.c_str(),
|
||||||
|
pdb_file.c_str());
|
||||||
|
return LOCATE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(),
|
||||||
|
pdb_file_w.c_str());
|
||||||
|
return LOCATE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*converted_symbol_file = pdb_file.substr(0, pdb_file.length() - 4) + ".sym";
|
||||||
|
|
||||||
|
FILE *converted_output = NULL;
|
||||||
|
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||||
|
errno_t err;
|
||||||
|
if ((err = fopen_s(&converted_output, converted_symbol_file->c_str(), "w"))
|
||||||
|
!= 0) {
|
||||||
|
#else // _MSC_VER >= 1400
|
||||||
|
// fopen_s and errno_t were introduced in MSVC8. Use fopen for earlier
|
||||||
|
// environments. Don't use fopen with MSVC8 and later, because it's
|
||||||
|
// deprecated. fopen does not provide reliable error codes, so just use
|
||||||
|
// -1 in the event of a failure.
|
||||||
|
int err;
|
||||||
|
if (!(converted_output = fopen(converted_symbol_file->c_str(), "w"))) {
|
||||||
|
err = -1;
|
||||||
|
#endif // _MSC_VER >= 1400
|
||||||
|
fprintf(stderr, "LocateAndConvertSymbolFile: "
|
||||||
|
"fopen_s: error %d for %s %s %s %s\n",
|
||||||
|
err,
|
||||||
|
missing.debug_file.c_str(),
|
||||||
|
missing.debug_identifier.c_str(),
|
||||||
|
missing.version.c_str(),
|
||||||
|
converted_symbol_file->c_str());
|
||||||
|
return LOCATE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoDeleter sym_deleter(*converted_symbol_file);
|
||||||
|
|
||||||
|
bool success = writer.WriteMap(converted_output);
|
||||||
|
fclose(converted_output);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
fprintf(stderr, "LocateAndConvertSymbolFile: "
|
||||||
|
"PDBSourceLineWriter::WriteMap failed 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keep_symbol_file) {
|
||||||
|
pdb_deleter.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
sym_deleter.Release();
|
||||||
|
|
||||||
|
return LOCATE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace google_airbag
|
201
src/tools/windows/converter/ms_symbol_server_converter.h
Normal file
201
src/tools/windows/converter/ms_symbol_server_converter.h
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// ms_symbol_server_converter.h: Obtain symbol files from a Microsoft
|
||||||
|
// symbol server, and convert them to Airbag's dumped format.
|
||||||
|
//
|
||||||
|
// At runtime, MSSymbolServerConverter and code that it calls depend on being
|
||||||
|
// able to locate suitable versions of dbghelp.dll and symsrv.dll. For best
|
||||||
|
// results, place these files in the same directory as the executable.
|
||||||
|
// dbghelp.dll and symsrv.dll as supplied with Debugging Tools for Windows are
|
||||||
|
// both redistributable, as indicated by the package's redist.txt file.
|
||||||
|
//
|
||||||
|
// When connecting to Microsoft's symbol server at
|
||||||
|
// http://msdl.microsoft.com/download/symbols/, which provides access to
|
||||||
|
// symbols for the operating system itself, symsrv.dll requires agreement to
|
||||||
|
// Microsoft's "Terms of Use for Microsoft Symbols and Binaries." Because this
|
||||||
|
// library places the symbol engine into a promptless mode, the dialog with the
|
||||||
|
// terms will not appear, and use of Microsoft's symbol server will not be
|
||||||
|
// possible. To indicate agreement to the terms, create a file called
|
||||||
|
// symsrv.yes in the same directory as symsrv.dll. (Note that symsrv.dll will
|
||||||
|
// also recognize a symsrv.no file as indicating that you do not accept the
|
||||||
|
// terms; the .yes file takes priority over the .no file.) The terms of use
|
||||||
|
// are contained within symsrv.dll; they were formerly available online at
|
||||||
|
// http://www.microsoft.com/whdc/devtools/debugging/symsrvTOU2.mspx , but
|
||||||
|
// do not appear to be available online any longer as of January, 2007. It is
|
||||||
|
// possible to view the terms from within WinDbg (Debugging Tools for Windows)
|
||||||
|
// by removing any symsrv.yes and symsrv.no files from WinDbg's directory,
|
||||||
|
// setting the symbol path to include Microsoft's symbol server (.sympath), and
|
||||||
|
// 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
|
||||||
|
// http://www.microsoft.com/whdc/devtools/debugging/ .
|
||||||
|
//
|
||||||
|
// Author: Mark Mentovai
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MS_SYMBOL_SERVER_CONVERTER_H__
|
||||||
|
#define MS_SYMBOL_SERVER_CONVERTER_H__
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace google_airbag {
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
|
// MissingSymbolInfo contains the subset of the information in the processor's
|
||||||
|
// CodeModule structure relevant to obtaining a missing symbol file. Only
|
||||||
|
// debug_file and debug_identifier are relevant in actually obtaining the
|
||||||
|
// missing file; the other fields are for convenience.
|
||||||
|
struct MissingSymbolInfo {
|
||||||
|
string code_file;
|
||||||
|
string code_identifier;
|
||||||
|
string debug_file;
|
||||||
|
string debug_identifier;
|
||||||
|
string version;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GUIDOrSignatureIdentifier {
|
||||||
|
public:
|
||||||
|
enum GUIDOrSignatureType {
|
||||||
|
TYPE_NONE = 0,
|
||||||
|
TYPE_GUID,
|
||||||
|
TYPE_SIGNATURE
|
||||||
|
};
|
||||||
|
|
||||||
|
GUIDOrSignatureIdentifier() : type_(TYPE_NONE) {}
|
||||||
|
|
||||||
|
// Converts |identifier|, a debug_identifier-formatted string, into its
|
||||||
|
// component fields: either a GUID and age, or signature and age. If
|
||||||
|
// successful, sets the relevant fields in the object, including the type
|
||||||
|
// field, and returns true. On error, returns false.
|
||||||
|
bool InitializeFromString(const string &identifier);
|
||||||
|
|
||||||
|
GUIDOrSignatureType type() const { return type_; }
|
||||||
|
GUID guid() const { return guid_; }
|
||||||
|
DWORD signature() const { return signature_; }
|
||||||
|
int age() const { return age_; }
|
||||||
|
const void *guid_or_signature_pointer() const { return &guid_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
GUIDOrSignatureType type_;
|
||||||
|
|
||||||
|
// An identifier contains either a 128-bit uuid or a 32-bit signature.
|
||||||
|
union {
|
||||||
|
GUID guid_;
|
||||||
|
DWORD signature_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// All identifiers used here have age fields, which indicate a specific
|
||||||
|
// revision given a uuid or signature.
|
||||||
|
int age_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MSSymbolServerConverter {
|
||||||
|
public:
|
||||||
|
enum LocateResult {
|
||||||
|
LOCATE_FAILURE = 0,
|
||||||
|
LOCATE_NOT_FOUND, // Authoritative: the file is not present.
|
||||||
|
LOCATE_RETRY, // Transient (network?) error, try again later.
|
||||||
|
LOCATE_SUCCESS
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a new object. local_cache is the location (pathname) of a local
|
||||||
|
// symbol store used to hold downloaded and converted symbol files. This
|
||||||
|
// directory will be created by LocateSymbolFile when it successfully
|
||||||
|
// retrieves a symbol file. symbol_servers contains a list of locations (URLs
|
||||||
|
// or pathnames) of the upstream symbol server stores, given in order of
|
||||||
|
// preference, with the first string in the vector identifying the first
|
||||||
|
// store to try. The vector must contain at least one string. None of the
|
||||||
|
// strings passed to this constructor may contain asterisk ('*') or semicolon
|
||||||
|
// (';') characters, as the symbol engine uses these characters as separators.
|
||||||
|
MSSymbolServerConverter(const string &local_cache,
|
||||||
|
const vector<string> &symbol_servers);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// the pathname of the decompressed symbol file as it is stored in the
|
||||||
|
// local cache.
|
||||||
|
LocateResult LocateSymbolFile(const MissingSymbolInfo &missing,
|
||||||
|
string *symbol_file);
|
||||||
|
|
||||||
|
// Calls LocateSymbolFile and converts the returned symbol file to the
|
||||||
|
// dumped-symbol format, storing it adjacent to the symbol file. The
|
||||||
|
// only conversion supported is from pdb files. Returns the return
|
||||||
|
// 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.
|
||||||
|
LocateResult LocateAndConvertSymbolFile(const MissingSymbolInfo &missing,
|
||||||
|
bool keep_symbol_file,
|
||||||
|
string *converted_symbol_file,
|
||||||
|
string *symbol_file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 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
|
||||||
|
// that SymFindFileInPath might encounter.
|
||||||
|
static BOOL CALLBACK SymCallback(HANDLE process, ULONG action, ULONG64 data,
|
||||||
|
ULONG64 context);
|
||||||
|
|
||||||
|
// Called by SymFindFileInPath (in LocateSymbolFile) after a candidate
|
||||||
|
// symbol file is located, when it's present in the local cache.
|
||||||
|
// 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,
|
||||||
|
void *context);
|
||||||
|
|
||||||
|
// The search path used by SymSrv, built based on the arguments to the
|
||||||
|
// constructor.
|
||||||
|
string symbol_path_;
|
||||||
|
|
||||||
|
// SymCallback will set at least one of these failure variables if
|
||||||
|
// SymFindFileInPath fails for an expected reason.
|
||||||
|
bool fail_dns_; // DNS failures (fail_not_found_ will also be set).
|
||||||
|
bool fail_timeout_; // Timeouts (fail_not_found_ will also be set).
|
||||||
|
bool fail_not_found_; // The file could not be found. If this is the only
|
||||||
|
// fail_* member set, then it is authoritative.
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace google_airbag
|
||||||
|
|
||||||
|
#endif // MS_SYMBOL_SERVER_CONVERTER_H__
|
319
src/tools/windows/converter/ms_symbol_server_converter.vcproj
Normal file
319
src/tools/windows/converter/ms_symbol_server_converter.vcproj
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="8.00"
|
||||||
|
Name="ms_symbol_server_converter"
|
||||||
|
ProjectGUID="{1463C4CD-23FC-4DE9-BFDE-283338200157}"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories=""$(VSInstallDir)\DIA SDK\include";..\..\.."
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
AdditionalDependencies="dbghelp.lib diaguids.lib"
|
||||||
|
AdditionalLibraryDirectories=""$(VSInstallDir)\DIA SDK\lib""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories=""$(VSInstallDir)\DIA SDK\include";..\..\.."
|
||||||
|
PreprocessorDefinitions="WIN32;_CONSOLE;WIN32_LEAN_AND_MEAN"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
AdditionalDependencies="dbghelp.lib diaguids.lib"
|
||||||
|
AdditionalLibraryDirectories=""$(VSInstallDir)\DIA SDK\lib""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="DebugStaticCRT|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories=""$(VSInstallDir)\DIA SDK\include";..\..\.."
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
AdditionalDependencies="dbghelp.lib diaguids.lib"
|
||||||
|
AdditionalLibraryDirectories=""$(VSInstallDir)\DIA SDK\lib""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="ReleaseStaticCRT|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories=""$(VSInstallDir)\DIA SDK\include";..\..\.."
|
||||||
|
PreprocessorDefinitions="WIN32;_CONSOLE;WIN32_LEAN_AND_MEAN"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
AdditionalDependencies="dbghelp.lib diaguids.lib"
|
||||||
|
AdditionalLibraryDirectories=""$(VSInstallDir)\DIA SDK\lib""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\common\windows\guid_string.cc"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\ms_symbol_server_converter.cc"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\common\windows\pdb_source_line_writer.cc"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\common\windows\string_utils.cc"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\common\windows\guid_string.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\ms_symbol_server_converter.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\common\windows\pdb_source_line_writer.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\common\windows\string_utils-inl.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
Loading…
Reference in New Issue
Block a user