mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-01-01 20:24:40 +01:00
Change PrintFunctions to print functions in address order and not print duplicate public functions.
BUG=427 R=mark@chromium.org Review URL: https://breakpad.appspot.com/1634002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1319 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
1c8e155b3a
commit
9aaae65466
7 changed files with 13891 additions and 14789 deletions
|
|
@ -347,7 +347,6 @@ bool PDBSourceLineWriter::PrintFunctions() {
|
|||
ULONG count = 0;
|
||||
DWORD rva = 0;
|
||||
CComPtr<IDiaSymbol> global;
|
||||
std::set<DWORD> rvas;
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(session_->get_globalScope(&global))) {
|
||||
|
|
@ -357,22 +356,8 @@ bool PDBSourceLineWriter::PrintFunctions() {
|
|||
|
||||
CComPtr<IDiaEnumSymbols> symbols = NULL;
|
||||
|
||||
// Find all public symbols.
|
||||
hr = global->findChildren(SymTagPublicSymbol, NULL, nsNone, &symbols);
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
CComPtr<IDiaSymbol> symbol = NULL;
|
||||
|
||||
while (SUCCEEDED(symbols->Next(1, &symbol, &count)) && count == 1) {
|
||||
if (!PrintCodePublicSymbol(symbol))
|
||||
return false;
|
||||
symbol.Release();
|
||||
}
|
||||
|
||||
symbols.Release();
|
||||
}
|
||||
|
||||
// Find all function symbols.
|
||||
// Find all function symbols first.
|
||||
std::set<DWORD> rvas;
|
||||
hr = global->findChildren(SymTagFunction, NULL, nsNone, &symbols);
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
|
|
@ -382,10 +367,31 @@ bool PDBSourceLineWriter::PrintFunctions() {
|
|||
if (SUCCEEDED(symbol->get_relativeVirtualAddress(&rva))) {
|
||||
// To maintain existing behavior of one symbol per address, place the
|
||||
// rva onto a set here to uniquify them.
|
||||
rvas.insert(rva);
|
||||
} else {
|
||||
fprintf(stderr, "get_relativeVirtualAddress failed on the symbol\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
symbol.Release();
|
||||
}
|
||||
|
||||
symbols.Release();
|
||||
}
|
||||
|
||||
// Find all public symbols. Store public symbols that are not also private
|
||||
// symbols for later.
|
||||
std::set<DWORD> public_only_rvas;
|
||||
hr = global->findChildren(SymTagPublicSymbol, NULL, nsNone, &symbols);
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
CComPtr<IDiaSymbol> symbol = NULL;
|
||||
|
||||
while (SUCCEEDED(symbols->Next(1, &symbol, &count)) && count == 1) {
|
||||
if (SUCCEEDED(symbol->get_relativeVirtualAddress(&rva))) {
|
||||
if (rvas.count(rva) == 0) {
|
||||
rvas.insert(rva);
|
||||
if (!PrintFunction(symbol, symbol))
|
||||
return false;
|
||||
rvas.insert(rva); // Keep symbols in rva order.
|
||||
public_only_rvas.insert(rva);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "get_relativeVirtualAddress failed on the symbol\n");
|
||||
|
|
@ -398,6 +404,42 @@ bool PDBSourceLineWriter::PrintFunctions() {
|
|||
symbols.Release();
|
||||
}
|
||||
|
||||
std::set<DWORD>::iterator it;
|
||||
|
||||
// For each rva, dump the first symbol DIA knows about at the address.
|
||||
for (it = rvas.begin(); it != rvas.end(); ++it) {
|
||||
CComPtr<IDiaSymbol> symbol = NULL;
|
||||
// If the symbol is not in the public list, look for SymTagFunction. This is
|
||||
// a workaround to a bug where DIA will hang if searching for a private
|
||||
// symbol at an address where only a public symbol exists.
|
||||
// See http://connect.microsoft.com/VisualStudio/feedback/details/722366
|
||||
if (public_only_rvas.count(*it) == 0) {
|
||||
if (SUCCEEDED(session_->findSymbolByRVA(*it, SymTagFunction, &symbol))) {
|
||||
// Sometimes findSymbolByRVA returns S_OK, but NULL.
|
||||
if (symbol) {
|
||||
if (!PrintFunction(symbol, symbol))
|
||||
return false;
|
||||
symbol.Release();
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "findSymbolByRVA SymTagFunction failed\n");
|
||||
return false;
|
||||
}
|
||||
} else if (SUCCEEDED(session_->findSymbolByRVA(*it,
|
||||
SymTagPublicSymbol,
|
||||
&symbol))) {
|
||||
// Sometimes findSymbolByRVA returns S_OK, but NULL.
|
||||
if (symbol) {
|
||||
if (!PrintCodePublicSymbol(symbol))
|
||||
return false;
|
||||
symbol.Release();
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "findSymbolByRVA SymTagPublicSymbol failed\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// When building with PGO, the compiler can split functions into
|
||||
// "hot" and "cold" blocks, and move the "cold" blocks out to separate
|
||||
// pages, so the function can be noncontiguous. To find these blocks,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue