Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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. | |
| 4 | |
| 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/ | |
| 8 | |
| 9 #include "stdio.h" | |
|
zturner
2015/02/24 23:53:07
Minor nit: any reason you chose to use quote synta
brucedawson
2015/02/25 00:15:21
Copy paste error I think. Fixed.
| |
| 10 #include <Windows.h> | |
| 11 #include <DbgHelp.h> | |
| 12 #include <string> | |
| 13 | |
| 14 // Link with the dbghelp import library | |
| 15 #pragma comment(lib, "dbghelp.lib") | |
| 16 | |
| 17 // Uncomment this line to test with known-good parameters. | |
| 18 //#define TESTING | |
| 19 | |
| 20 int main(int argc, char* argv[]) | |
| 21 { | |
| 22 // Tell dbghelp to print diagnostics to the debugger output. | |
| 23 SymSetOptions(SYMOPT_DEBUG); | |
| 24 | |
| 25 // Initialize dbghelp | |
| 26 const HANDLE fakeProcess = (HANDLE)1; | |
| 27 BOOL result = SymInitialize(fakeProcess, NULL, FALSE); | |
| 28 | |
| 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"); | |
| 35 | |
| 36 // Valid PDB data to test the code. | |
| 37 std::string gText = "072FF0EB54D24DFAAE9D13885486EE09"; | |
|
zturner
2015/02/24 23:53:07
Is this supposed to be called gTextArg? Looks lik
brucedawson
2015/02/25 00:15:21
Good catch. I fixed that and verified that the TES
| |
| 38 const char* ageText = "2"; | |
| 39 const char* fileName = "kernel32.pdb"; | |
| 40 | |
| 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) | |
| 50 { | |
| 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; | |
| 58 } | |
| 59 | |
| 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 | |
| 66 | |
| 67 // Parse the GUID and age from the text | |
| 68 GUID g = {}; | |
| 69 DWORD age = 0; | |
| 70 DWORD dateStamp = 0; | |
| 71 DWORD size = 0; | |
| 72 | |
| 73 // Settings for SymFindFileInPath | |
| 74 void* id = nullptr; | |
| 75 DWORD flags = 0; | |
| 76 DWORD two = 0; | |
| 77 | |
| 78 const char* ext = strrchr(fileName, '.'); | |
| 79 if (!ext) | |
| 80 { | |
| 81 printf("No extension found on %s. Fatal error.\n", fileName); | |
| 82 return 0; | |
| 83 } | |
| 84 | |
| 85 if (_stricmp(ext, ".pdb") == 0) | |
| 86 { | |
| 87 std::string gText; | |
|
zturner
2015/02/24 23:53:07
How about GUIDFromString()? Removes almost this e
brucedawson
2015/02/25 00:15:22
I looked at that function before and it seemed...
zturner
2015/02/25 00:29:33
Ahh yea, I didn't notice that. There's CLSIDFromS
| |
| 88 // Scan the GUID argument and remove all non-hex characters. This allows | |
| 89 // passing GUIDs with '-', '{', and '}' characters. | |
| 90 for (auto c : gTextArg) | |
| 91 { | |
| 92 if (isxdigit(c)) | |
| 93 { | |
| 94 gText.push_back(c); | |
| 95 } | |
| 96 } | |
| 97 printf("Parsing symbol data for a PDB file.\n"); | |
| 98 if (gText.size() != 32) | |
| 99 { | |
| 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; | |
| 103 } | |
| 104 | |
| 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) | |
| 112 { | |
| 113 count += sscanf_s(gText.substr(16 + i * 2, 2).c_str(), "%x", &temp); | |
| 114 g.Data4[i] = (unsigned char)temp; | |
| 115 } | |
| 116 count += sscanf_s(ageText, "%x", &age); | |
| 117 | |
| 118 if (count != 12) | |
| 119 { | |
| 120 printf("Error: couldn't parse the GUID/age string. Sorry.\n"); | |
| 121 return 10; | |
| 122 } | |
| 123 flags = SSRVOPT_GUIDPTR; | |
| 124 id = &g; | |
| 125 two = age; | |
| 126 printf("Looking for %s %s %s.\n", gText.c_str(), ageText, fileName); | |
| 127 } | |
| 128 else | |
| 129 { | |
| 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); | |
| 140 } | |
| 141 | |
| 142 char filePath[MAX_PATH] = {}; | |
| 143 DWORD three = 0; | |
| 144 | |
| 145 if (SymFindFileInPath(fakeProcess, NULL, fileName, id, two, three, | |
| 146 flags, filePath, NULL, NULL)) | |
| 147 { | |
| 148 printf("Found symbol file - placed it in %s.\n", filePath); | |
| 149 } | |
| 150 else | |
| 151 { | |
| 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"); | |
| 157 } | |
| 158 | |
| 159 SymCleanup(fakeProcess); | |
| 160 | |
| 161 return 0; | |
| 162 } | |
| OLD | NEW |