Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / tools / win / RetrieveSymbols / RetrieveSymbols.cpp
blobf183673f2879e2a492fbcb28b32882c9f2249c61
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Symbol downloading demonstration code.
6 // For more information see ReadMe.txt and this blog post:
7 // https://randomascii.wordpress.com/2013/03/09/symbols-the-microsoft-way/
9 #include <stdio.h>
10 #include <Windows.h>
11 #include <DbgHelp.h>
12 #include <string>
14 // Link with the dbghelp import library
15 #pragma comment(lib, "dbghelp.lib")
17 // Uncomment this line to test with known-good parameters.
18 //#define TESTING
20 int main(int argc, char* argv[])
22 // Tell dbghelp to print diagnostics to the debugger output.
23 SymSetOptions(SYMOPT_DEBUG);
25 // Initialize dbghelp
26 const HANDLE fakeProcess = (HANDLE)1;
27 BOOL result = SymInitialize(fakeProcess, NULL, FALSE);
29 #ifdef TESTING
30 // Set a search path and cache directory. If this isn't set
31 // then _NT_SYMBOL_PATH will be used instead.
32 // Force setting it here to make sure that the test succeeds.
33 SymSetSearchPath(fakeProcess,
34 "SRV*c:\\symbolstest*http://msdl.microsoft.com/download/symbols");
36 // Valid PDB data to test the code.
37 std::string gTextArg = "072FF0EB54D24DFAAE9D13885486EE09";
38 const char* ageText = "2";
39 const char* fileName = "kernel32.pdb";
41 // Valid PE data to test the code
42 fileName = "crypt32.dll";
43 const char* dateStampText = "4802A0D7";
44 const char* sizeText = "95000";
45 //fileName = "chrome_child.dll";
46 //const char* dateStampText = "5420D824";
47 //const char* sizeText = "20a6000";
48 #else
49 if (argc < 4)
51 printf("Error: insufficient arguments.\n");
52 printf("Usage: %s guid age pdbname\n", argv[0]);
53 printf("Usage: %s dateStamp size pename\n", argv[0]);
54 printf("Example: %s 6720c31f4ac24f3ab0243e0641a4412f 1 "
55 "chrome_child.dll.pdb\n", argv[0]);
56 printf("Example: %s 4802A0D7 95000 crypt32.dll\n", argv[0]);
57 return 0;
60 std::string gTextArg = argv[1];
61 const char* dateStampText = argv[1];
62 const char* ageText = argv[2];
63 const char* sizeText = argv[2];
64 const char* fileName = argv[3];
65 #endif
67 // Parse the GUID and age from the text
68 GUID g = {};
69 DWORD age = 0;
70 DWORD dateStamp = 0;
71 DWORD size = 0;
73 // Settings for SymFindFileInPath
74 void* id = nullptr;
75 DWORD flags = 0;
76 DWORD two = 0;
78 const char* ext = strrchr(fileName, '.');
79 if (!ext)
81 printf("No extension found on %s. Fatal error.\n", fileName);
82 return 0;
85 if (_stricmp(ext, ".pdb") == 0)
87 std::string gText;
88 // Scan the GUID argument and remove all non-hex characters. This allows
89 // passing GUIDs with '-', '{', and '}' characters.
90 for (auto c : gTextArg)
92 if (isxdigit(c))
94 gText.push_back(c);
97 printf("Parsing symbol data for a PDB file.\n");
98 if (gText.size() != 32)
100 printf("Error: GUIDs must be exactly 32 characters"
101 " (%s was stripped to %s).\n", gTextArg.c_str(), gText.c_str());
102 return 10;
105 int count = sscanf_s(gText.substr(0, 8).c_str(), "%x", &g.Data1);
106 DWORD temp;
107 count += sscanf_s(gText.substr(8, 4).c_str(), "%x", &temp);
108 g.Data2 = (unsigned short)temp;
109 count += sscanf_s(gText.substr(12, 4).c_str(), "%x", &temp);
110 g.Data3 = (unsigned short)temp;
111 for (auto i = 0; i < ARRAYSIZE(g.Data4); ++i)
113 count += sscanf_s(gText.substr(16 + i * 2, 2).c_str(), "%x", &temp);
114 g.Data4[i] = (unsigned char)temp;
116 count += sscanf_s(ageText, "%x", &age);
118 if (count != 12)
120 printf("Error: couldn't parse the GUID/age string. Sorry.\n");
121 return 10;
123 flags = SSRVOPT_GUIDPTR;
124 id = &g;
125 two = age;
126 printf("Looking for %s %s %s.\n", gText.c_str(), ageText, fileName);
128 else
130 printf("Parsing symbol data for a PE (.dll or .exe) file.\n");
131 if (strlen(dateStampText) != 8)
132 printf("Warning!!! The datestamp (%s) is not eight characters long. "
133 "This is usually wrong.\n", dateStampText);
134 int count = sscanf_s(dateStampText, "%x", &dateStamp);
135 count += sscanf_s(sizeText, "%x", &size);
136 flags = SSRVOPT_DWORDPTR;
137 id = &dateStamp;
138 two = size;
139 printf("Looking for %s %x %x.\n", fileName, dateStamp, two);
142 char filePath[MAX_PATH] = {};
143 DWORD three = 0;
145 if (SymFindFileInPath(fakeProcess, NULL, fileName, id, two, three,
146 flags, filePath, NULL, NULL))
148 printf("Found symbol file - placed it in %s.\n", filePath);
150 else
152 printf("Error: symbols not found - error %u. Are dbghelp.dll and "
153 "symsrv.dll in the same directory as this executable?\n",
154 GetLastError());
155 printf("Note that symbol server lookups sometimes fail randomly. "
156 "Try again?\n");
159 SymCleanup(fakeProcess);
161 return 0;