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 #pragma warning(disable : 4100) | |
|
cpu_(ooo_6.6-7.5)
2014/02/13 03:32:42
pls add a comment to what they disable.
scottmg
2014/02/13 18:13:33
Removed now that I'm building with gyp, they're al
| |
| 6 #pragma warning(disable : 4530) | |
| 7 | |
| 8 #include <stdio.h> | |
| 9 | |
| 10 #include <string> | |
| 11 | |
| 12 #include "dia2.h" | |
|
cpu_(ooo_6.6-7.5)
2014/02/13 03:32:42
where is this header?
scottmg
2014/02/13 18:13:33
VSInstallDir/Include/DIA SDK/
Changed to #include
| |
| 13 | |
| 14 // Create an IDiaData source and open a PDB file. | |
| 15 static bool LoadDataFromPdb(const wchar_t* filename, | |
| 16 IDiaDataSource** source, | |
| 17 IDiaSession** session, | |
| 18 IDiaSymbol** global, | |
| 19 DWORD* machine_type) { | |
| 20 // Alternate path to search for debug data. | |
| 21 wchar_t* search_path = L"SRV**\\\\symbols\\symbols"; | |
|
cpu_(ooo_6.6-7.5)
2014/02/13 03:32:42
wchar_t search_path[] =
scottmg
2014/02/13 18:13:33
Done.
| |
| 22 DWORD mach_type = 0; | |
| 23 HRESULT hr = CoInitialize(NULL); | |
| 24 | |
| 25 // Obtain access to the provider. | |
| 26 hr = CoCreateInstance(__uuidof(DiaSource), | |
| 27 NULL, | |
| 28 CLSCTX_INPROC_SERVER, | |
| 29 __uuidof(IDiaDataSource), | |
| 30 (void**)source); | |
| 31 | |
| 32 if (FAILED(hr)) { | |
| 33 printf("CoCreateInstance failed - HRESULT = %08X\n", hr); | |
| 34 return false; | |
| 35 } | |
| 36 | |
| 37 wchar_t ext[MAX_PATH]; | |
| 38 _wsplitpath_s(filename, NULL, 0, NULL, 0, NULL, 0, ext, MAX_PATH); | |
| 39 | |
| 40 // Open and prepare the debug data associated with the executable. | |
| 41 hr = (*source)->loadDataForExe(filename, search_path, NULL); | |
| 42 if (FAILED(hr)) { | |
| 43 printf("loadDataForExe failed - HRESULT = %08X\n", hr); | |
| 44 return false; | |
| 45 } | |
| 46 | |
| 47 // Open a session for querying symbols. | |
| 48 hr = (*source)->openSession(session); | |
| 49 | |
| 50 if (FAILED(hr)) { | |
| 51 printf("openSession failed - HRESULT = %08X\n", hr); | |
| 52 return false; | |
| 53 } | |
| 54 | |
| 55 // Retrieve a reference to the global scope. | |
| 56 hr = (*session)->get_globalScope(global); | |
| 57 | |
| 58 if (hr != S_OK) { | |
|
cpu_(ooo_6.6-7.5)
2014/02/13 03:32:42
why not FAILED() ?
edit: I see it in many places,
scottmg
2014/02/13 18:13:33
Done.
| |
| 59 printf("get_globalScope failed\n"); | |
| 60 return false; | |
| 61 } | |
| 62 | |
| 63 // Set machine type for getting correct register names. | |
| 64 if ((*global)->get_machineType(&mach_type) == S_OK) { | |
| 65 switch (mach_type) { | |
| 66 case IMAGE_FILE_MACHINE_I386: | |
| 67 *machine_type = CV_CFL_80386; | |
| 68 break; | |
| 69 case IMAGE_FILE_MACHINE_IA64: | |
| 70 *machine_type = CV_CFL_IA64; | |
| 71 break; | |
| 72 case IMAGE_FILE_MACHINE_AMD64: | |
| 73 *machine_type = CV_CFL_AMD64; | |
| 74 break; | |
| 75 } | |
|
cpu_(ooo_6.6-7.5)
2014/02/13 03:32:42
default:
explode?
scottmg
2014/02/13 18:13:33
Done.
| |
| 76 } | |
| 77 | |
| 78 return true; | |
| 79 } | |
| 80 | |
| 81 // Release DIA objects and CoUninitialize. | |
| 82 static void Cleanup(IDiaSymbol* global_symbol, IDiaSession* dia_session) { | |
| 83 if (global_symbol) | |
| 84 global_symbol->Release(); | |
| 85 if (dia_session) | |
| 86 dia_session->Release(); | |
| 87 CoUninitialize(); | |
| 88 } | |
| 89 | |
| 90 static void PrintIfDynamicInitializer(const std::wstring& module, | |
| 91 IDiaSymbol* symbol) { | |
| 92 DWORD symtag; | |
| 93 | |
| 94 if (symbol->get_symTag(&symtag) != S_OK) | |
| 95 return; | |
| 96 | |
| 97 if (symtag != SymTagFunction && symtag != SymTagBlock) | |
| 98 return; | |
| 99 | |
| 100 BSTR bstr_name; | |
| 101 if (symbol->get_name(&bstr_name) == S_OK) { | |
| 102 if (bstr_name[0] != L'\0' && | |
| 103 wcsstr(bstr_name, L"`dynamic initializer for '")) { | |
|
cpu_(ooo_6.6-7.5)
2014/02/13 03:32:42
does it need the null check wiht [0] ? wouldn't ss
scottmg
2014/02/13 18:13:33
Done.
| |
| 104 wprintf(L"%s: %s\n", module.c_str(), bstr_name); | |
| 105 SysFreeString(bstr_name); | |
| 106 } | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 static bool DumpStaticInitializers(IDiaSymbol* global_symbol) { | |
| 111 // Retrieve the compilands first. | |
| 112 IDiaEnumSymbols* enum_symbols; | |
| 113 if (FAILED(global_symbol->findChildren( | |
| 114 SymTagCompiland, NULL, nsNone, &enum_symbols))) { | |
| 115 return false; | |
| 116 } | |
| 117 | |
| 118 IDiaSymbol* compiland; | |
| 119 ULONG celt = 0; | |
|
cpu_(ooo_6.6-7.5)
2014/02/13 03:32:42
celt needs a better name or if that is the better
scottmg
2014/02/13 18:13:33
Done.
| |
| 120 | |
| 121 std::wstring current_module; | |
| 122 while (SUCCEEDED(enum_symbols->Next(1, &compiland, &celt)) && (celt == 1)) { | |
| 123 BSTR bstr_name; | |
| 124 if (compiland->get_name(&bstr_name) != S_OK) { | |
| 125 current_module = L"<unknown>"; | |
|
cpu_(ooo_6.6-7.5)
2014/02/13 03:32:42
so bstr does not get allocated in this branch?
scottmg
2014/02/13 18:13:33
That's right.
| |
| 126 } else { | |
| 127 current_module = bstr_name; | |
| 128 SysFreeString(bstr_name); | |
| 129 } | |
| 130 | |
| 131 // Find all the symbols defined in this compiland, and print them if they | |
| 132 // have the name corresponding to an initializer. | |
| 133 IDiaEnumSymbols* enum_children; | |
| 134 if (SUCCEEDED(compiland->findChildren( | |
| 135 SymTagNull, NULL, nsNone, &enum_children))) { | |
| 136 IDiaSymbol* symbol; | |
| 137 ULONG children = 0; | |
| 138 while (SUCCEEDED(enum_children->Next(1, &symbol, &children)) && | |
| 139 (children == 1)) { | |
|
cpu_(ooo_6.6-7.5)
2014/02/13 03:32:42
I don't understand the logic of children == 1. May
scottmg
2014/02/13 18:13:33
That's the termination of the loop. Next(1, ...) a
| |
| 140 PrintIfDynamicInitializer(current_module, symbol); | |
| 141 symbol->Release(); | |
| 142 } | |
| 143 enum_children->Release(); | |
| 144 } | |
| 145 compiland->Release(); | |
| 146 } | |
| 147 | |
| 148 enum_symbols->Release(); | |
| 149 return true; | |
| 150 } | |
| 151 | |
| 152 int wmain(int argc, wchar_t* argv[]) { | |
| 153 if (argc != 2) { | |
| 154 wprintf(L"usage: %ls binary_name\n", argv[0]); | |
| 155 return 1; | |
| 156 } | |
| 157 | |
| 158 IDiaDataSource* dia_data_source; | |
| 159 IDiaSession* dia_session; | |
| 160 IDiaSymbol* global_symbol; | |
| 161 DWORD machine_type = CV_CFL_80386; | |
| 162 if (!LoadDataFromPdb(argv[1], | |
| 163 &dia_data_source, | |
| 164 &dia_session, | |
| 165 &global_symbol, | |
| 166 &machine_type)) { | |
| 167 wprintf(L"Couldn't load data from pdb.\n"); | |
| 168 return 1; | |
| 169 } | |
| 170 | |
| 171 wprintf(L"Static initializers in %s:\n", argv[1]); | |
| 172 | |
| 173 if (!DumpStaticInitializers(global_symbol)) | |
| 174 return 1; | |
| 175 | |
| 176 Cleanup(global_symbol, dia_session); | |
| 177 | |
| 178 return 0; | |
| 179 } | |
| OLD | NEW |