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 |