[Lldb-commits] [lldb] r335822 - Retrieve a function PDB symbol correctly from nested blocks
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Thu Jun 28 03:03:42 PDT 2018
Author: labath
Date: Thu Jun 28 03:03:42 2018
New Revision: 335822
URL: http://llvm.org/viewvc/llvm-project?rev=335822&view=rev
Log:
Retrieve a function PDB symbol correctly from nested blocks
Summary:
This patch fixes a problem with retrieving a function symbol by an
address in a nested block. In the current implementation of
ResolveSymbolContext function it retrieves a symbol with
PDB_SymType::None and then checks if found symbol's tag equals to
PDB_SymType::Function. So, if nested block's symbol was found,
ResolveSymbolContext does not resolve a function.
Reviewers: asmith, labath, zturner
Reviewed By: asmith, labath
Differential Revision: https://reviews.llvm.org/D47939
Patch by Aleksandr Urakov <aleksandr.urakov at jetbrains.com>
Added:
lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionNestedBlockTest.cpp
lldb/trunk/lit/SymbolFile/PDB/function-nested-block.test
Modified:
lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
lldb/trunk/tools/lldb-test/lldb-test.cpp
Added: lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionNestedBlockTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionNestedBlockTest.cpp?rev=335822&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionNestedBlockTest.cpp (added)
+++ lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionNestedBlockTest.cpp Thu Jun 28 03:03:42 2018
@@ -0,0 +1,8 @@
+int main() {
+ auto r = 0;
+ for (auto i = 1; i <= 10; i++) {
+ r += i & 1 + (i - 1) & 1 - 1;
+ }
+
+ return r;
+}
Added: lldb/trunk/lit/SymbolFile/PDB/function-nested-block.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/PDB/function-nested-block.test?rev=335822&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/PDB/function-nested-block.test (added)
+++ lldb/trunk/lit/SymbolFile/PDB/function-nested-block.test Thu Jun 28 03:03:42 2018
@@ -0,0 +1,7 @@
+REQUIRES: windows, lld
+RUN: clang-cl /c /Zi %S/Inputs/FunctionNestedBlockTest.cpp /o %t.obj
+RUN: lld-link /debug:full /nodefaultlib /entry:main %t.obj /out:%t.exe
+RUN: lldb-test symbols -find=function -file FunctionNestedBlockTest.cpp -line 4 %t.exe | FileCheck %s
+
+CHECK: Found 1 functions:
+CHECK: name = "{{.*}}", mangled = "_main"
Modified: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp?rev=335822&r1=335821&r2=335822&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp Thu Jun 28 03:03:42 2018
@@ -347,6 +347,11 @@ bool SymbolFilePDB::ParseCompileUnitSupp
FileSpec spec(file->getFileName(), false, FileSpec::Style::windows);
support_files.AppendIfUnique(spec);
}
+
+ // LLDB uses the DWARF-like file numeration (one based),
+ // the zeroth file is the compile unit itself
+ support_files.Insert(0, *sc.comp_unit);
+
return true;
}
@@ -596,12 +601,6 @@ SymbolFilePDB::ResolveSymbolContext(cons
resolve_scope & eSymbolContextFunction ||
resolve_scope & eSymbolContextBlock ||
resolve_scope & eSymbolContextLineEntry) {
- addr_t file_vm_addr = so_addr.GetFileAddress();
- auto symbol_up =
- m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::None);
- if (!symbol_up)
- return 0;
-
auto cu_sp = GetCompileUnitContainsAddress(so_addr);
if (!cu_sp) {
if (resolved_flags | eSymbolContextVariable) {
@@ -612,39 +611,39 @@ SymbolFilePDB::ResolveSymbolContext(cons
sc.comp_unit = cu_sp.get();
resolved_flags |= eSymbolContextCompUnit;
lldbassert(sc.module_sp == cu_sp->GetModule());
+ }
- switch (symbol_up->getSymTag()) {
- case PDB_SymType::Function:
- if (resolve_scope & eSymbolContextFunction) {
- auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
- assert(pdb_func);
- auto func_uid = pdb_func->getSymIndexId();
- sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();
- if (sc.function == nullptr)
- sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc);
- if (sc.function) {
- resolved_flags |= eSymbolContextFunction;
- if (resolve_scope & eSymbolContextBlock) {
- Block &block = sc.function->GetBlock(true);
- sc.block = block.FindBlockByID(sc.function->GetID());
- if (sc.block)
- resolved_flags |= eSymbolContextBlock;
- }
+ if (resolve_scope & eSymbolContextFunction) {
+ addr_t file_vm_addr = so_addr.GetFileAddress();
+ auto symbol_up =
+ m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::Function);
+ if (symbol_up) {
+ auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
+ assert(pdb_func);
+ auto func_uid = pdb_func->getSymIndexId();
+ sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();
+ if (sc.function == nullptr)
+ sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc);
+ if (sc.function) {
+ resolved_flags |= eSymbolContextFunction;
+ if (resolve_scope & eSymbolContextBlock) {
+ Block &block = sc.function->GetBlock(true);
+ sc.block = block.FindBlockByID(sc.function->GetID());
+ if (sc.block)
+ resolved_flags |= eSymbolContextBlock;
}
}
- break;
- default:
- break;
}
+ }
- if (resolve_scope & eSymbolContextLineEntry) {
- if (auto *line_table = sc.comp_unit->GetLineTable()) {
- Address addr(so_addr);
- if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
- resolved_flags |= eSymbolContextLineEntry;
- }
+ if (resolve_scope & eSymbolContextLineEntry) {
+ if (auto *line_table = sc.comp_unit->GetLineTable()) {
+ Address addr(so_addr);
+ if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
+ resolved_flags |= eSymbolContextLineEntry;
}
}
+
return resolved_flags;
}
@@ -1631,7 +1630,9 @@ void SymbolFilePDB::BuildSupportFileIdTo
auto source_files = m_session_up->getSourceFilesForCompiland(compiland);
if (!source_files)
return;
- int index = 0;
+
+ // LLDB uses the DWARF-like file numeration (one based)
+ int index = 1;
while (auto file = source_files->getNext()) {
uint32_t source_id = file->getUniqueId();
Modified: lldb/trunk/tools/lldb-test/lldb-test.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-test/lldb-test.cpp?rev=335822&r1=335821&r2=335822&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-test/lldb-test.cpp (original)
+++ lldb/trunk/tools/lldb-test/lldb-test.cpp Thu Jun 28 03:03:42 2018
@@ -35,8 +35,8 @@
#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
@@ -108,8 +108,7 @@ enum class FindType {
static cl::opt<FindType> Find(
"find", cl::desc("Choose search type:"),
cl::values(
- clEnumValN(FindType::None, "none",
- "No search, just dump the module."),
+ clEnumValN(FindType::None, "none", "No search, just dump the module."),
clEnumValN(FindType::Function, "function", "Find functions."),
clEnumValN(FindType::Namespace, "namespace", "Find namespaces."),
clEnumValN(FindType::Type, "type", "Find types."),
@@ -151,6 +150,8 @@ static cl::opt<bool> Verify("verify", cl
static cl::opt<std::string> File("file",
cl::desc("File (compile unit) to search."),
cl::sub(SymbolsSubcommand));
+static cl::opt<int> Line("line", cl::desc("Line to search."),
+ cl::sub(SymbolsSubcommand));
static Expected<CompilerDeclContext> getDeclContext(SymbolVendor &Vendor);
@@ -163,7 +164,7 @@ static Error verify(lldb_private::Module
static Expected<Error (*)(lldb_private::Module &)> getAction();
static int dumpSymbols(Debugger &Dbg);
-}
+} // namespace symbols
namespace irmemorymap {
static cl::opt<std::string> Target(cl::Positional, cl::desc("<target>"),
@@ -179,7 +180,7 @@ static cl::opt<bool> UseHostOnlyAllocati
using AllocationT = std::pair<addr_t, addr_t>;
using AddrIntervalMap =
- IntervalMap<addr_t, unsigned, 8, IntervalMapHalfOpenInfo<addr_t>>;
+ IntervalMap<addr_t, unsigned, 8, IntervalMapHalfOpenInfo<addr_t>>;
struct IRMemoryMapTestState {
TargetSP Target;
@@ -334,7 +335,32 @@ opts::symbols::getDeclContext(SymbolVend
Error opts::symbols::findFunctions(lldb_private::Module &Module) {
SymbolVendor &Vendor = *Module.GetSymbolVendor();
SymbolContextList List;
- if (Regex) {
+ if (!File.empty()) {
+ assert(Line != 0);
+
+ FileSpec src_file(File, false);
+ size_t cu_count = Module.GetNumCompileUnits();
+ for (size_t i = 0; i < cu_count; i++) {
+ lldb::CompUnitSP cu_sp = Module.GetCompileUnitAtIndex(i);
+ if (!cu_sp)
+ continue;
+
+ LineEntry le;
+ cu_sp->FindLineEntry(0, Line, &src_file, false, &le);
+ if (!le.IsValid())
+ continue;
+
+ auto addr = le.GetSameLineContiguousAddressRange().GetBaseAddress();
+ if (!addr.IsValid())
+ continue;
+
+ SymbolContext sc;
+ uint32_t resolved =
+ addr.CalculateSymbolContext(&sc, eSymbolContextFunction);
+ if (resolved & eSymbolContextFunction)
+ List.Append(sc);
+ }
+ } else if (Regex) {
RegularExpression RE(Name);
assert(RE.IsValid());
Vendor.FindFunctions(RE, true, false, List);
@@ -346,7 +372,7 @@ Error opts::symbols::findFunctions(lldb_
ContextOr->IsValid() ? &*ContextOr : nullptr;
Vendor.FindFunctions(ConstString(Name), ContextPtr, getFunctionNameFlags(),
- true, false, List);
+ true, false, List);
}
outs() << formatv("Found {0} functions:\n", List.GetSize());
StreamString Stream;
@@ -386,7 +412,7 @@ Error opts::symbols::findTypes(lldb_priv
DenseSet<SymbolFile *> SearchedFiles;
TypeMap Map;
Vendor.FindTypes(SC, ConstString(Name), ContextPtr, true, UINT32_MAX,
- SearchedFiles, Map);
+ SearchedFiles, Map);
outs() << formatv("Found {0} types:\n", Map.GetSize());
StreamString Stream;
@@ -458,8 +484,8 @@ Error opts::symbols::verify(lldb_private
if (!comp_unit)
return make_string_error("Connot parse compile unit {0}.", i);
- outs() << "Processing '" << comp_unit->GetFilename().AsCString() <<
- "' compile unit.\n";
+ outs() << "Processing '" << comp_unit->GetFilename().AsCString()
+ << "' compile unit.\n";
LineTable *lt = comp_unit->GetLineTable();
if (!lt)
@@ -478,7 +504,7 @@ Error opts::symbols::verify(lldb_private
for (uint32_t i = 1; i < count; i++) {
lldb::addr_t curr_end =
- le.range.GetBaseAddress().GetFileAddress() + le.range.GetByteSize();
+ le.range.GetBaseAddress().GetFileAddress() + le.range.GetByteSize();
if (!lt->GetLineEntryAtIndex(i, le))
return make_string_error("Can't get a line entry of a compile unit");
@@ -499,9 +525,11 @@ Expected<Error (*)(lldb_private::Module
if (Find != FindType::None)
return make_string_error(
"Cannot both search and verify symbol information.");
- if (Regex || !Context.empty() || !Name.empty() || !File.empty())
- return make_string_error("-regex, -context, -name and -file options are not "
- "applicable for symbol verification.");
+ if (Regex || !Context.empty() || !Name.empty() || !File.empty() ||
+ Line != 0)
+ return make_string_error(
+ "-regex, -context, -name, -file and -line options are not "
+ "applicable for symbol verification.");
return verify;
}
@@ -520,32 +548,38 @@ Expected<Error (*)(lldb_private::Module
switch (Find) {
case FindType::None:
- if (!Context.empty() || !Name.empty() || !File.empty())
+ if (!Context.empty() || !Name.empty() || !File.empty() || Line != 0)
return make_string_error(
"Specify search type (-find) to use search options.");
return dumpModule;
case FindType::Function:
- if (!File.empty())
- return make_string_error("Cannot search for functions by file name.");
- if (Regex && getFunctionNameFlags() != 0)
- return make_string_error("Cannot search for functions using both regular "
- "expressions and function-flags.");
+ if (!File.empty() + (Line != 0) == 1)
+ return make_string_error("Both file name and line number must be "
+ "specified when searching a function "
+ "by file position.");
+ if (Regex + (getFunctionNameFlags() != 0) + !File.empty() >= 2)
+ return make_string_error("Only one of regular expression, function-flags "
+ "and file position may be used simultaneously "
+ "when searching a function.");
return findFunctions;
case FindType::Namespace:
- if (Regex || !File.empty())
+ if (Regex || !File.empty() || Line != 0)
return make_string_error("Cannot search for namespaces using regular "
- "expressions or file names.");
+ "expressions, file names or line numbers.");
return findNamespaces;
case FindType::Type:
- if (Regex || !File.empty())
+ if (Regex || !File.empty() || Line != 0)
return make_string_error("Cannot search for types using regular "
- "expressions or file names.");
+ "expressions, file names or line numbers.");
return findTypes;
case FindType::Variable:
+ if (Line != 0)
+ return make_string_error("Cannot search for variables "
+ "using line numbers.");
return findVariables;
}
}
More information about the lldb-commits
mailing list