mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-03-10 17:26:28 +00:00
Initial import, which includes the Windows client-side dump_syms tool, and
part of the server-side dump processor. git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@4 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
49
src/tools/windows/dump_syms/dump_syms.cc
Normal file
49
src/tools/windows/dump_syms/dump_syms.cc
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright (C) 2006 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Windows utility to dump the line number data from a pdb file to
|
||||
// a text-based format that we can use from the minidump processor.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include "pdb_source_line_writer.h"
|
||||
|
||||
using std::wstring;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s <pdb file>", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
wchar_t filename[_MAX_PATH];
|
||||
if (mbstowcs_s(NULL, filename, argv[1], _MAX_PATH) == -1) {
|
||||
fprintf(stderr, "invalid multibyte character in %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
google_airbag::PDBSourceLineWriter writer;
|
||||
if (!writer.Open(wstring(filename))) {
|
||||
fprintf(stderr, "Open failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!writer.WriteMap(stdout)) {
|
||||
fprintf(stderr, "WriteMap failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
writer.Close();
|
||||
return 0;
|
||||
}
|
||||
206
src/tools/windows/dump_syms/dump_syms.vcproj
Executable file
206
src/tools/windows/dump_syms/dump_syms.vcproj
Executable file
@@ -0,0 +1,206 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="dump_syms"
|
||||
ProjectGUID="{792E1530-E2C5-4289-992E-317BA30E9D9F}"
|
||||
RootNamespace="dumpsyms"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
>
|
||||
<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;"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies=""$(VSInstallDir)\DIA SDK\lib\diaguids.lib""
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
>
|
||||
<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;NDEBUG;_CONSOLE;"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies=""$(VSInstallDir)\DIA SDK\lib\diaguids.lib""
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\pdb_source_line_writer.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\dump_syms.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pdb_source_line_writer.cc"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
216
src/tools/windows/dump_syms/pdb_source_line_writer.cc
Normal file
216
src/tools/windows/dump_syms/pdb_source_line_writer.cc
Normal file
@@ -0,0 +1,216 @@
|
||||
// Copyright (C) 2006 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <atlbase.h>
|
||||
#include <dia2.h>
|
||||
#include "pdb_source_line_writer.h"
|
||||
|
||||
namespace google_airbag {
|
||||
|
||||
PDBSourceLineWriter::PDBSourceLineWriter() : output_(NULL) {
|
||||
}
|
||||
|
||||
PDBSourceLineWriter::~PDBSourceLineWriter() {
|
||||
}
|
||||
|
||||
bool PDBSourceLineWriter::Open(const wstring &pdb_file) {
|
||||
Close();
|
||||
|
||||
if (FAILED(CoInitialize(NULL))) {
|
||||
fprintf(stderr, "CoInitialize failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
CComPtr<IDiaDataSource> data_source;
|
||||
if (FAILED(data_source.CoCreateInstance(CLSID_DiaSource))) {
|
||||
fprintf(stderr, "CoCreateInstance CLSID_DiaSource failed "
|
||||
"(msdia80.dll unregistered?)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FAILED(data_source->loadDataFromPdb(pdb_file.c_str()))) {
|
||||
fprintf(stderr, "loadDataFromPdb failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FAILED(data_source->openSession(&session_))) {
|
||||
fprintf(stderr, "openSession failed\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PDBSourceLineWriter::PrintLines(IDiaEnumLineNumbers *lines) {
|
||||
// The line number format is:
|
||||
// <rva> <line number> <source file id>
|
||||
CComPtr<IDiaLineNumber> line;
|
||||
ULONG count;
|
||||
|
||||
while (SUCCEEDED(lines->Next(1, &line, &count)) && count == 1) {
|
||||
DWORD rva;
|
||||
if (FAILED(line->get_relativeVirtualAddress(&rva))) {
|
||||
fprintf(stderr, "failed to get line rva\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD source_id;
|
||||
if (FAILED(line->get_sourceFileId(&source_id))) {
|
||||
fprintf(stderr, "failed to get line source file id\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD line_num;
|
||||
if (FAILED(line->get_lineNumber(&line_num))) {
|
||||
fprintf(stderr, "failed to get line number\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(output_, "%x %d %d\n", rva, line_num, source_id);
|
||||
line.Release();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PDBSourceLineWriter::PrintFunction(IDiaSymbol *function) {
|
||||
// The function format is:
|
||||
// FUNC <address> <function>
|
||||
CComBSTR name;
|
||||
if (FAILED(function->get_name(&name))) {
|
||||
fprintf(stderr, "failed to get function name\n");
|
||||
return false;
|
||||
}
|
||||
if (name.Length() == 0) {
|
||||
fprintf(stderr, "empty function name\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ULONGLONG length;
|
||||
if (FAILED(function->get_length(&length))) {
|
||||
fprintf(stderr, "failed to get function length\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD rva;
|
||||
if (FAILED(function->get_relativeVirtualAddress(&rva))) {
|
||||
fprintf(stderr, "couldn't get rva\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
CComPtr<IDiaEnumLineNumbers> lines;
|
||||
if (FAILED(session_->findLinesByRVA(rva, DWORD(length), &lines))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fwprintf(output_, L"FUNC %x %s\n", rva, name);
|
||||
if (!PrintLines(lines)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PDBSourceLineWriter::PrintSourceFiles() {
|
||||
CComPtr<IDiaSymbol> global;
|
||||
if (FAILED(session_->get_globalScope(&global))) {
|
||||
fprintf(stderr, "get_globalScope failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
CComPtr<IDiaEnumSymbols> compilands;
|
||||
if (FAILED(global->findChildren(SymTagCompiland, NULL,
|
||||
nsNone, &compilands))) {
|
||||
fprintf(stderr, "findChildren failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
CComPtr<IDiaSymbol> compiland;
|
||||
ULONG count;
|
||||
while (SUCCEEDED(compilands->Next(1, &compiland, &count)) && count == 1) {
|
||||
CComPtr<IDiaEnumSourceFiles> source_files;
|
||||
if (FAILED(session_->findFile(compiland, NULL, nsNone, &source_files))) {
|
||||
return false;
|
||||
}
|
||||
CComPtr<IDiaSourceFile> file;
|
||||
while (SUCCEEDED(source_files->Next(1, &file, &count)) && count == 1) {
|
||||
DWORD file_id;
|
||||
if (FAILED(file->get_uniqueId(&file_id))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CComBSTR file_name;
|
||||
if (FAILED(file->get_fileName(&file_name))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fwprintf(output_, L"FILE %d %s\n", file_id, file_name);
|
||||
file.Release();
|
||||
}
|
||||
compiland.Release();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PDBSourceLineWriter::PrintFunctions() {
|
||||
CComPtr<IDiaEnumSymbolsByAddr> symbols;
|
||||
if (FAILED(session_->getSymbolsByAddr(&symbols))) {
|
||||
fprintf(stderr, "failed to get symbol enumerator\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
CComPtr<IDiaSymbol> symbol;
|
||||
if (FAILED(symbols->symbolByAddr(1, 0, &symbol))) {
|
||||
fprintf(stderr, "failed to enumerate symbols\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD rva_last = 0;
|
||||
if (FAILED(symbol->get_relativeVirtualAddress(&rva_last))) {
|
||||
fprintf(stderr, "failed to get symbol rva\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ULONG count;
|
||||
do {
|
||||
DWORD tag;
|
||||
if (FAILED(symbol->get_symTag(&tag))) {
|
||||
fprintf(stderr, "failed to get symbol tag\n");
|
||||
return false;
|
||||
}
|
||||
if (tag == SymTagFunction) {
|
||||
if (!PrintFunction(symbol)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
symbol.Release();
|
||||
} while (SUCCEEDED(symbols->Next(1, &symbol, &count)) && count == 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PDBSourceLineWriter::WriteMap(FILE *map_file) {
|
||||
bool ret = false;
|
||||
output_ = map_file;
|
||||
if (PrintSourceFiles() && PrintFunctions()) {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
output_ = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PDBSourceLineWriter::Close() {
|
||||
session_.Release();
|
||||
}
|
||||
|
||||
} // namespace google_airbag
|
||||
77
src/tools/windows/dump_syms/pdb_source_line_writer.h
Normal file
77
src/tools/windows/dump_syms/pdb_source_line_writer.h
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright (C) 2006 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// PDBSourceLineWriter uses a pdb file produced by Visual C++ to output
|
||||
// a line/address map for use with SourceLineResolver.
|
||||
|
||||
#ifndef _PDB_SOURCE_LINE_WRITER_H__
|
||||
#define _PDB_SOURCE_LINE_WRITER_H__
|
||||
|
||||
#include <string>
|
||||
#include <atlcomcli.h>
|
||||
|
||||
struct IDiaEnumLineNumbers;
|
||||
struct IDiaSession;
|
||||
struct IDiaSymbol;
|
||||
|
||||
namespace google_airbag {
|
||||
|
||||
using std::wstring;
|
||||
|
||||
class PDBSourceLineWriter {
|
||||
public:
|
||||
explicit PDBSourceLineWriter();
|
||||
~PDBSourceLineWriter();
|
||||
|
||||
// Opens the given pdb file. If there is already a pdb file open,
|
||||
// it is automatically closed. Returns true on success.
|
||||
bool Open(const wstring &pdb_file);
|
||||
|
||||
// Writes a map file from the current pdb file to the given file stream.
|
||||
// Returns true on success.
|
||||
bool WriteMap(FILE *map_file);
|
||||
|
||||
// Closes the current pdb file and its associated resources.
|
||||
void Close();
|
||||
|
||||
private:
|
||||
// Outputs the line/address pairs for each line in the enumerator.
|
||||
// Returns true on success.
|
||||
bool PrintLines(IDiaEnumLineNumbers *lines);
|
||||
|
||||
// Outputs a function address and name, followed by its source line list.
|
||||
// Returns true on success.
|
||||
bool PrintFunction(IDiaSymbol *function);
|
||||
|
||||
// Outputs all functions as described above. Returns true on success.
|
||||
bool PrintFunctions();
|
||||
|
||||
// Outputs all of the source files in the session's pdb file.
|
||||
// Returns true on success.
|
||||
bool PrintSourceFiles();
|
||||
|
||||
// The session for the currently-open pdb file.
|
||||
CComPtr<IDiaSession> session_;
|
||||
|
||||
// The current output file for this WriteMap invocation.
|
||||
FILE *output_;
|
||||
|
||||
// Disallow copy ctor and operator=
|
||||
PDBSourceLineWriter(const PDBSourceLineWriter&);
|
||||
void operator=(const PDBSourceLineWriter&);
|
||||
};
|
||||
|
||||
} // namespace google_airbag
|
||||
|
||||
#endif // _PDB_SOURCE_LINE_WRITER_H__
|
||||
8
src/tools/windows/dump_syms/run_regtest.sh
Executable file
8
src/tools/windows/dump_syms/run_regtest.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
Release/dump_syms.exe testdata/dump_syms_regtest.pdb > testdata/dump_syms_regtest.new
|
||||
if diff -u testdata/dump_syms_regtest.new testdata/dump_syms_regtest.out >& testdata/dump_syms_regtest.diff; then
|
||||
rm testdata/dump_syms_regtest.diff testdata/dump_syms_regtest.new
|
||||
echo "PASS"
|
||||
else
|
||||
echo "FAIL, see testdata/dump_syms_regtest.[new|diff]"
|
||||
fi
|
||||
1532
src/tools/windows/dump_syms/testdata/dump_syms_regtest.out
vendored
Executable file
1532
src/tools/windows/dump_syms/testdata/dump_syms_regtest.out
vendored
Executable file
File diff suppressed because it is too large
Load Diff
BIN
src/tools/windows/dump_syms/testdata/dump_syms_regtest.pdb
vendored
Executable file
BIN
src/tools/windows/dump_syms/testdata/dump_syms_regtest.pdb
vendored
Executable file
Binary file not shown.
Reference in New Issue
Block a user