Chromium Code Reviews| Index: tools/win/static_initializers/static_initializers.cc |
| diff --git a/tools/win/static_initializers/static_initializers.cc b/tools/win/static_initializers/static_initializers.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..086c67a68f42e4b1fe213eb6c5d2a026901971c2 |
| --- /dev/null |
| +++ b/tools/win/static_initializers/static_initializers.cc |
| @@ -0,0 +1,179 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#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
|
| +#pragma warning(disable : 4530) |
| + |
| +#include <stdio.h> |
| + |
| +#include <string> |
| + |
| +#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
|
| + |
| +// Create an IDiaData source and open a PDB file. |
| +static bool LoadDataFromPdb(const wchar_t* filename, |
| + IDiaDataSource** source, |
| + IDiaSession** session, |
| + IDiaSymbol** global, |
| + DWORD* machine_type) { |
| + // Alternate path to search for debug data. |
| + 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.
|
| + DWORD mach_type = 0; |
| + HRESULT hr = CoInitialize(NULL); |
| + |
| + // Obtain access to the provider. |
| + hr = CoCreateInstance(__uuidof(DiaSource), |
| + NULL, |
| + CLSCTX_INPROC_SERVER, |
| + __uuidof(IDiaDataSource), |
| + (void**)source); |
| + |
| + if (FAILED(hr)) { |
| + printf("CoCreateInstance failed - HRESULT = %08X\n", hr); |
| + return false; |
| + } |
| + |
| + wchar_t ext[MAX_PATH]; |
| + _wsplitpath_s(filename, NULL, 0, NULL, 0, NULL, 0, ext, MAX_PATH); |
| + |
| + // Open and prepare the debug data associated with the executable. |
| + hr = (*source)->loadDataForExe(filename, search_path, NULL); |
| + if (FAILED(hr)) { |
| + printf("loadDataForExe failed - HRESULT = %08X\n", hr); |
| + return false; |
| + } |
| + |
| + // Open a session for querying symbols. |
| + hr = (*source)->openSession(session); |
| + |
| + if (FAILED(hr)) { |
| + printf("openSession failed - HRESULT = %08X\n", hr); |
| + return false; |
| + } |
| + |
| + // Retrieve a reference to the global scope. |
| + hr = (*session)->get_globalScope(global); |
| + |
| + 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.
|
| + printf("get_globalScope failed\n"); |
| + return false; |
| + } |
| + |
| + // Set machine type for getting correct register names. |
| + if ((*global)->get_machineType(&mach_type) == S_OK) { |
| + switch (mach_type) { |
| + case IMAGE_FILE_MACHINE_I386: |
| + *machine_type = CV_CFL_80386; |
| + break; |
| + case IMAGE_FILE_MACHINE_IA64: |
| + *machine_type = CV_CFL_IA64; |
| + break; |
| + case IMAGE_FILE_MACHINE_AMD64: |
| + *machine_type = CV_CFL_AMD64; |
| + break; |
| + } |
|
cpu_(ooo_6.6-7.5)
2014/02/13 03:32:42
default:
explode?
scottmg
2014/02/13 18:13:33
Done.
|
| + } |
| + |
| + return true; |
| +} |
| + |
| +// Release DIA objects and CoUninitialize. |
| +static void Cleanup(IDiaSymbol* global_symbol, IDiaSession* dia_session) { |
| + if (global_symbol) |
| + global_symbol->Release(); |
| + if (dia_session) |
| + dia_session->Release(); |
| + CoUninitialize(); |
| +} |
| + |
| +static void PrintIfDynamicInitializer(const std::wstring& module, |
| + IDiaSymbol* symbol) { |
| + DWORD symtag; |
| + |
| + if (symbol->get_symTag(&symtag) != S_OK) |
| + return; |
| + |
| + if (symtag != SymTagFunction && symtag != SymTagBlock) |
| + return; |
| + |
| + BSTR bstr_name; |
| + if (symbol->get_name(&bstr_name) == S_OK) { |
| + if (bstr_name[0] != L'\0' && |
| + 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.
|
| + wprintf(L"%s: %s\n", module.c_str(), bstr_name); |
| + SysFreeString(bstr_name); |
| + } |
| + } |
| +} |
| + |
| +static bool DumpStaticInitializers(IDiaSymbol* global_symbol) { |
| + // Retrieve the compilands first. |
| + IDiaEnumSymbols* enum_symbols; |
| + if (FAILED(global_symbol->findChildren( |
| + SymTagCompiland, NULL, nsNone, &enum_symbols))) { |
| + return false; |
| + } |
| + |
| + IDiaSymbol* compiland; |
| + 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.
|
| + |
| + std::wstring current_module; |
| + while (SUCCEEDED(enum_symbols->Next(1, &compiland, &celt)) && (celt == 1)) { |
| + BSTR bstr_name; |
| + if (compiland->get_name(&bstr_name) != S_OK) { |
| + 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.
|
| + } else { |
| + current_module = bstr_name; |
| + SysFreeString(bstr_name); |
| + } |
| + |
| + // Find all the symbols defined in this compiland, and print them if they |
| + // have the name corresponding to an initializer. |
| + IDiaEnumSymbols* enum_children; |
| + if (SUCCEEDED(compiland->findChildren( |
| + SymTagNull, NULL, nsNone, &enum_children))) { |
| + IDiaSymbol* symbol; |
| + ULONG children = 0; |
| + while (SUCCEEDED(enum_children->Next(1, &symbol, &children)) && |
| + (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
|
| + PrintIfDynamicInitializer(current_module, symbol); |
| + symbol->Release(); |
| + } |
| + enum_children->Release(); |
| + } |
| + compiland->Release(); |
| + } |
| + |
| + enum_symbols->Release(); |
| + return true; |
| +} |
| + |
| +int wmain(int argc, wchar_t* argv[]) { |
| + if (argc != 2) { |
| + wprintf(L"usage: %ls binary_name\n", argv[0]); |
| + return 1; |
| + } |
| + |
| + IDiaDataSource* dia_data_source; |
| + IDiaSession* dia_session; |
| + IDiaSymbol* global_symbol; |
| + DWORD machine_type = CV_CFL_80386; |
| + if (!LoadDataFromPdb(argv[1], |
| + &dia_data_source, |
| + &dia_session, |
| + &global_symbol, |
| + &machine_type)) { |
| + wprintf(L"Couldn't load data from pdb.\n"); |
| + return 1; |
| + } |
| + |
| + wprintf(L"Static initializers in %s:\n", argv[1]); |
| + |
| + if (!DumpStaticInitializers(global_symbol)) |
| + return 1; |
| + |
| + Cleanup(global_symbol, dia_session); |
| + |
| + return 0; |
| +} |