aboutsummaryrefslogtreecommitdiff
path: root/src/tools/windows/symupload
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/windows/symupload')
-rw-r--r--src/tools/windows/symupload/symupload.cc180
-rwxr-xr-xsrc/tools/windows/symupload/symupload.vcproj215
2 files changed, 395 insertions, 0 deletions
diff --git a/src/tools/windows/symupload/symupload.cc b/src/tools/windows/symupload/symupload.cc
new file mode 100644
index 00000000..7b530d0f
--- /dev/null
+++ b/src/tools/windows/symupload/symupload.cc
@@ -0,0 +1,180 @@
+// Copyright (c) 2006, 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.
+
+// Tool to upload an exe/dll and its associated symbols to an HTTP server.
+// The PDB file is located automatically, using the path embedded in the
+// executable. The upload is sent as a multipart/form-data POST request,
+// with the following parameters:
+// module: the name of the module, e.g. app.exe
+// ver: the file version of the module, e.g. 1.2.3.4
+// guid: the GUID string embedded in the module pdb,
+// e.g. 11111111-2222-3333-4444-555555555555
+// symbol_file: the airbag-format symbol file
+
+#include <windows.h>
+#include <wininet.h>
+#include <dbghelp.h>
+
+#include <cstdio>
+#include <vector>
+#include <string>
+#include <map>
+
+#include "common/windows/pdb_source_line_writer.h"
+#include "common/windows/http_upload.h"
+
+using std::string;
+using std::wstring;
+using std::vector;
+using std::map;
+using google_airbag::HTTPUpload;
+using google_airbag::PDBSourceLineWriter;
+
+// Extracts the file version information for the given filename,
+// as a string, for example, "1.2.3.4". Returns true on success.
+static bool GetFileVersionString(const wchar_t *filename, wstring *version) {
+ DWORD handle;
+ DWORD version_size = GetFileVersionInfoSize(filename, &handle);
+ if (version_size < sizeof(VS_FIXEDFILEINFO)) {
+ return false;
+ }
+
+ vector<char> version_info(version_size);
+ if (!GetFileVersionInfo(filename, handle, version_size, &version_info[0])) {
+ return false;
+ }
+
+ void *file_info_buffer = NULL;
+ unsigned int file_info_length;
+ if (!VerQueryValue(&version_info[0], L"\\",
+ &file_info_buffer, &file_info_length)) {
+ return false;
+ }
+
+ // The maximum value of each version component is 65535 (0xffff),
+ // so the max length is 24, including the terminating null.
+ wchar_t ver_string[24];
+ VS_FIXEDFILEINFO *file_info =
+ reinterpret_cast<VS_FIXEDFILEINFO*>(file_info_buffer);
+ _snwprintf_s(ver_string, sizeof(ver_string) / sizeof(wchar_t), _TRUNCATE,
+ L"%d.%d.%d.%d",
+ file_info->dwFileVersionMS >> 16,
+ file_info->dwFileVersionMS & 0xffff,
+ file_info->dwFileVersionLS >> 16,
+ file_info->dwFileVersionLS & 0xffff);
+ *version = ver_string;
+ return true;
+}
+
+// Creates a new temporary file and writes the symbol data from the given
+// exe/dll file to it. Returns the path to the temp file in temp_file_path,
+// and the unique identifier (GUID) for the pdb in module_guid.
+static bool DumpSymbolsToTempFile(const wchar_t *exe_file,
+ wstring *temp_file_path,
+ wstring *module_guid) {
+ google_airbag::PDBSourceLineWriter writer;
+ if (!writer.Open(exe_file, PDBSourceLineWriter::EXE_FILE)) {
+ return false;
+ }
+
+ wchar_t temp_path[_MAX_PATH];
+ if (GetTempPath(_MAX_PATH, temp_path) == 0) {
+ return false;
+ }
+
+ wchar_t temp_filename[_MAX_PATH];
+ if (GetTempFileName(temp_path, L"sym", 0, temp_filename) == 0) {
+ return false;
+ }
+
+ FILE *temp_file = NULL;
+ if (_wfopen_s(&temp_file, temp_filename, L"w") != 0) {
+ return false;
+ }
+
+ bool success = writer.WriteMap(temp_file);
+ fclose(temp_file);
+ if (!success) {
+ _wunlink(temp_filename);
+ return false;
+ }
+
+ *temp_file_path = temp_filename;
+ *module_guid = writer.GetModuleGUID();
+ return true;
+}
+
+// Returns the base name of a file, e.g. strips off the path.
+static wstring GetBaseName(const wstring &filename) {
+ wstring base_name(filename);
+ size_t slash_pos = base_name.find_last_of(L"/\\");
+ if (slash_pos != string::npos) {
+ base_name.erase(0, slash_pos + 1);
+ }
+ return base_name;
+}
+
+int wmain(int argc, wchar_t *argv[]) {
+ if (argc < 3) {
+ wprintf(L"Usage: %s file.[exe|dll] <symbol upload URL>\n", argv[0]);
+ return 0;
+ }
+ const wchar_t *module = argv[1], *url = argv[2];
+ wstring module_basename = GetBaseName(module);
+
+ wstring file_version;
+ if (!GetFileVersionString(module, &file_version)) {
+ fwprintf(stderr, L"Could not get file version for %s\n", module);
+ return 1;
+ }
+
+ wstring symbol_file, module_guid;
+ if (!DumpSymbolsToTempFile(module, &symbol_file, &module_guid)) {
+ fwprintf(stderr, L"Could not get symbol data from %s\n", module);
+ return 1;
+ }
+
+ map<wstring, wstring> parameters;
+ parameters[L"module"] = module_basename;
+ parameters[L"version"] = file_version;
+ parameters[L"guid"] = module_guid;
+
+ bool success = HTTPUpload::SendRequest(url, parameters,
+ symbol_file, L"symbol_file");
+ _wunlink(symbol_file.c_str());
+
+ if (!success) {
+ fwprintf(stderr, L"Symbol file upload failed\n");
+ return 1;
+ }
+
+ wprintf(L"Uploaded symbols for %s/%s/%s\n",
+ module_basename.c_str(), file_version.c_str(), module_guid.c_str());
+ return 0;
+}
diff --git a/src/tools/windows/symupload/symupload.vcproj b/src/tools/windows/symupload/symupload.vcproj
new file mode 100755
index 00000000..63b731c1
--- /dev/null
+++ b/src/tools/windows/symupload/symupload.vcproj
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="symupload"
+ ProjectGUID="{E156ED87-9DE9-47C8-94EC-A5A9CDD65E18}"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="&quot;$(VSInstallDir)\DIA SDK\include&quot;;..\..\.."
+ 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="&quot;$(VSInstallDir)\DIA SDK\lib\diaguids.lib&quot; wininet.lib version.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"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(VSInstallDir)\DIA SDK\include&quot;;..\..\.."
+ 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="&quot;$(VSInstallDir)\DIA SDK\lib\diaguids.lib&quot; wininet.lib version.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="..\..\..\common\windows\http_upload.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\common\windows\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="..\..\..\common\windows\http_upload.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\common\windows\pdb_source_line_writer.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\symupload.cc"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>