[Lldb-commits] [lldb] r347962 - [PDB] Support PDB-backed expressions evaluation
Aleksandr Urakov via lldb-commits
lldb-commits at lists.llvm.org
Thu Nov 29 23:12:22 PST 2018
Author: aleksandr.urakov
Date: Thu Nov 29 23:12:22 2018
New Revision: 347962
URL: http://llvm.org/viewvc/llvm-project?rev=347962&view=rev
Log:
[PDB] Support PDB-backed expressions evaluation
Summary:
This patch contains several small fixes, which makes it possible to evaluate
expressions on Windows using information from PDB. The changes are:
- several sanitize checks;
- make IRExecutionUnit::MemoryManager::getSymbolAddress to not return a magic
value on a failure, because callers wait 0 in this case;
- entry point required to be a file address, not RVA, in the ObjectFilePECOFF;
- do not crash on a debuggee second chance exception - it may be an expression
evaluation crash;
- create parameter declarations for functions in AST to make it possible to call
debugee functions from expressions;
- relax name searching rules for variables, functions, namespaces and types. Now
it works just like in the DWARF plugin;
- fix endless recursion in SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc.
Reviewers: zturner, asmith, stella.stamenova
Reviewed By: stella.stamenova, asmith
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D53759
Added:
lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest.cpp
lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest0.script
lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest1.script
lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest2.script
lldb/trunk/lit/SymbolFile/PDB/expressions.test
Modified:
lldb/trunk/source/Expression/IRExecutionUnit.cpp
lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.h
lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
Added: lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest.cpp?rev=347962&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest.cpp (added)
+++ lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest.cpp Thu Nov 29 23:12:22 2018
@@ -0,0 +1,20 @@
+namespace N0 {
+namespace N1 {
+
+char *buf0 = nullptr;
+char buf1[] = {0, 1, 2, 3, 4, 5, 6, 7};
+
+char sum(char *buf, int size) {
+ char result = 0;
+ for (int i = 0; i < size; i++)
+ result += buf[i];
+ return result;
+}
+
+} // namespace N1
+} // namespace N0
+
+int main() {
+ char result = N0::N1::sum(N0::N1::buf1, sizeof(N0::N1::buf1));
+ return 0;
+}
Added: lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest0.script
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest0.script?rev=347962&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest0.script (added)
+++ lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest0.script Thu Nov 29 23:12:22 2018
@@ -0,0 +1,7 @@
+breakpoint set --file ExpressionsTest.cpp --line 19
+run
+print result
+print N0::N1::sum(N0::N1::buf1, sizeof(N0::N1::buf1))
+print N1::sum(N1::buf1, sizeof(N1::buf1))
+print sum(buf1, sizeof(buf1))
+print sum(buf1, 1000000000)
Added: lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest1.script
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest1.script?rev=347962&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest1.script (added)
+++ lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest1.script Thu Nov 29 23:12:22 2018
@@ -0,0 +1 @@
+print sum(buf0, 1)
Added: lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest2.script
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest2.script?rev=347962&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest2.script (added)
+++ lldb/trunk/lit/SymbolFile/PDB/Inputs/ExpressionsTest2.script Thu Nov 29 23:12:22 2018
@@ -0,0 +1,2 @@
+print sum(buf0, result - 28)
+print sum(buf1 + 3, 3)
Added: lldb/trunk/lit/SymbolFile/PDB/expressions.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/PDB/expressions.test?rev=347962&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/PDB/expressions.test (added)
+++ lldb/trunk/lit/SymbolFile/PDB/expressions.test Thu Nov 29 23:12:22 2018
@@ -0,0 +1,36 @@
+REQUIRES: system-windows, msvc
+RUN: %msvc_cl /Zi /GS- /c %S/Inputs/ExpressionsTest.cpp /Fo%t.obj
+RUN: %msvc_link /debug:full /nodefaultlib /entry:main %t.obj /out:%t.exe
+RUN: %lldb -b -s %S/Inputs/ExpressionsTest0.script -s %S/Inputs/ExpressionsTest1.script -s %S/Inputs/ExpressionsTest2.script -- %t.exe 2>&1 | FileCheck %s
+
+// Check the variable value through `print`
+CHECK: (lldb) print result
+CHECK: (char) $0 = '\x1c'
+
+// Call the function just like in the code
+CHECK: (lldb) print N0::N1::sum(N0::N1::buf1, sizeof(N0::N1::buf1))
+CHECK: (char) $1 = '\x1c'
+
+// Try the relaxed namespaces search
+CHECK: (lldb) print N1::sum(N1::buf1, sizeof(N1::buf1))
+CHECK: (char) $2 = '\x1c'
+
+// Try the relaxed variables and functions search
+CHECK: (lldb) print sum(buf1, sizeof(buf1))
+CHECK: (char) $3 = '\x1c'
+
+// Make a crash during expression calculation
+CHECK: (lldb) print sum(buf1, 1000000000)
+CHECK: The process has been returned to the state before expression evaluation.
+
+// Make one more crash
+CHECK: (lldb) print sum(buf0, 1)
+CHECK: The process has been returned to the state before expression evaluation.
+
+// Check if the process state was restored succesfully
+CHECK: (lldb) print sum(buf0, result - 28)
+CHECK: (char) $4 = '\0'
+
+// Call the function with arbitrary parameters
+CHECK: (lldb) print sum(buf1 + 3, 3)
+CHECK: (char) $5 = '\f'
Modified: lldb/trunk/source/Expression/IRExecutionUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRExecutionUnit.cpp?rev=347962&r1=347961&r2=347962&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRExecutionUnit.cpp (original)
+++ lldb/trunk/source/Expression/IRExecutionUnit.cpp Thu Nov 29 23:12:22 2018
@@ -1013,7 +1013,7 @@ IRExecutionUnit::MemoryManager::getSymbo
Name.c_str());
m_parent.ReportSymbolLookupError(name_cs);
- return 0xbad0bad0;
+ return 0;
} else {
if (log)
log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
Modified: lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp?rev=347962&r1=347961&r2=347962&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp Thu Nov 29 23:12:22 2018
@@ -817,12 +817,12 @@ lldb_private::Address ObjectFilePECOFF::
return m_entry_point_address;
SectionList *section_list = GetSectionList();
- addr_t offset = m_coff_header_opt.entry;
+ addr_t file_addr = m_coff_header_opt.entry + m_coff_header_opt.image_base;
if (!section_list)
- m_entry_point_address.SetOffset(offset);
+ m_entry_point_address.SetOffset(file_addr);
else
- m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
+ m_entry_point_address.ResolveAddressUsingFileSections(file_addr, section_list);
return m_entry_point_address;
}
Modified: lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp?rev=347962&r1=347961&r2=347962&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp Thu Nov 29 23:12:22 2018
@@ -957,8 +957,9 @@ ProcessWindows::OnDebugException(bool fi
}
if (!first_chance) {
- // Any second chance exception is an application crash by definition.
- SetPrivateState(eStateCrashed);
+ // Not any second chance exception is an application crash by definition.
+ // It may be an expression evaluation crash.
+ SetPrivateState(eStateStopped);
}
ExceptionResult result = ExceptionResult::SendToApplication;
Modified: lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp?rev=347962&r1=347961&r2=347962&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp Thu Nov 29 23:12:22 2018
@@ -42,7 +42,7 @@ bool RegisterContextWindows::ReadAllRegi
lldb::DataBufferSP &data_sp) {
if (!CacheAllRegisterValues())
return false;
- if (data_sp->GetByteSize() < sizeof(m_context)) {
+ if (!data_sp || data_sp->GetByteSize() < sizeof(m_context)) {
data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0));
}
memcpy(data_sp->GetBytes(), &m_context, sizeof(m_context));
Modified: lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp?rev=347962&r1=347961&r2=347962&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp Thu Nov 29 23:12:22 2018
@@ -921,6 +921,26 @@ PDBASTParser::GetDeclForSymbol(const llv
decl_context, name.c_str(), type->GetForwardCompilerType(), storage,
func->hasInlineAttribute());
+ std::vector<clang::ParmVarDecl *> params;
+ if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) {
+ if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg>>
+ arg_enum = sig->findAllChildren<PDBSymbolTypeFunctionArg>()) {
+ while (std::unique_ptr<PDBSymbolTypeFunctionArg> arg =
+ arg_enum->getNext()) {
+ Type *arg_type = symbol_file->ResolveTypeUID(arg->getTypeId());
+ if (!arg_type)
+ continue;
+
+ clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
+ nullptr, arg_type->GetForwardCompilerType(), clang::SC_None);
+ if (param)
+ params.push_back(param);
+ }
+ }
+ }
+ if (params.size())
+ m_ast.SetFunctionParameters(decl, params.data(), params.size());
+
m_uid_to_decl[sym_id] = decl;
return decl;
@@ -1030,6 +1050,7 @@ clang::DeclContext *PDBASTParser::GetDec
curr_context);
m_parent_to_namespaces[curr_context].insert(namespace_decl);
+ m_namespaces.insert(namespace_decl);
curr_context = namespace_decl;
}
@@ -1065,18 +1086,23 @@ void PDBASTParser::ParseDeclsForDeclCont
clang::NamespaceDecl *
PDBASTParser::FindNamespaceDecl(const clang::DeclContext *parent,
llvm::StringRef name) {
- if (!parent)
- parent = m_ast.GetTranslationUnitDecl();
+ NamespacesSet *set;
+ if (parent) {
+ auto pit = m_parent_to_namespaces.find(parent);
+ if (pit == m_parent_to_namespaces.end())
+ return nullptr;
- auto it = m_parent_to_namespaces.find(parent);
- if (it == m_parent_to_namespaces.end())
- return nullptr;
+ set = &pit->second;
+ } else {
+ set = &m_namespaces;
+ }
+ assert(set);
- for (auto namespace_decl : it->second)
+ for (clang::NamespaceDecl *namespace_decl : *set)
if (namespace_decl->getName().equals(name))
return namespace_decl;
- for (auto namespace_decl : it->second)
+ for (clang::NamespaceDecl *namespace_decl : *set)
if (namespace_decl->isAnonymousNamespace())
return FindNamespaceDecl(namespace_decl, name);
Modified: lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.h?rev=347962&r1=347961&r2=347962&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.h Thu Nov 29 23:12:22 2018
@@ -69,7 +69,8 @@ private:
typedef llvm::DenseMap<clang::CXXRecordDecl *, lldb::user_id_t>
CXXRecordDeclToUidMap;
typedef llvm::DenseMap<lldb::user_id_t, clang::Decl *> UidToDeclMap;
- typedef llvm::DenseMap<clang::DeclContext *, std::set<clang::NamespaceDecl *>>
+ typedef std::set<clang::NamespaceDecl *> NamespacesSet;
+ typedef llvm::DenseMap<clang::DeclContext *, NamespacesSet>
ParentToNamespacesMap;
typedef llvm::DenseMap<clang::DeclContext *, lldb::user_id_t>
DeclContextToUidMap;
@@ -109,6 +110,7 @@ private:
CXXRecordDeclToUidMap m_forward_decl_to_uid;
UidToDeclMap m_uid_to_decl;
ParentToNamespacesMap m_parent_to_namespaces;
+ NamespacesSet m_namespaces;
DeclContextToUidMap m_decl_context_to_uid;
};
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=347962&r1=347961&r2=347962&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp Thu Nov 29 23:12:22 2018
@@ -286,6 +286,10 @@ lldb_private::Function *SymbolFilePDB::P
const PDBSymbolFunc &pdb_func, const lldb_private::SymbolContext &sc) {
lldbassert(sc.comp_unit && sc.module_sp.get());
+ if (FunctionSP result =
+ sc.comp_unit->FindFunctionByUID(pdb_func.getSymIndexId()))
+ return result.get();
+
auto file_vm_addr = pdb_func.getVirtualAddress();
if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
return nullptr;
@@ -1047,8 +1051,6 @@ uint32_t SymbolFilePDB::FindGlobalVariab
const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, lldb_private::VariableList &variables) {
- if (!parent_decl_ctx)
- parent_decl_ctx = m_tu_decl_ctx_up.get();
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
return 0;
if (name.IsEmpty())
@@ -1078,9 +1080,8 @@ uint32_t SymbolFilePDB::FindGlobalVariab
if (sc.comp_unit == nullptr)
continue;
- auto actual_parent_decl_ctx =
- GetDeclContextContainingUID(result->getSymIndexId());
- if (actual_parent_decl_ctx != *parent_decl_ctx)
+ if (parent_decl_ctx && GetDeclContextContainingUID(
+ result->getSymIndexId()) != *parent_decl_ctx)
continue;
ParseVariables(sc, *pdb_data, &variables);
@@ -1269,20 +1270,28 @@ uint32_t SymbolFilePDB::FindFunctions(
CacheFunctionNames();
std::set<uint32_t> resolved_ids;
- auto ResolveFn = [include_inlines, &name, &sc_list, &resolved_ids,
- this](UniqueCStringMap<uint32_t> &Names) {
+ auto ResolveFn = [this, &name, parent_decl_ctx, include_inlines, &sc_list,
+ &resolved_ids](UniqueCStringMap<uint32_t> &Names) {
std::vector<uint32_t> ids;
- if (Names.GetValues(name, ids)) {
- for (auto id : ids) {
- if (resolved_ids.find(id) == resolved_ids.end()) {
- if (ResolveFunction(id, include_inlines, sc_list))
- resolved_ids.insert(id);
- }
- }
+ if (!Names.GetValues(name, ids))
+ return;
+
+ for (uint32_t id : ids) {
+ if (resolved_ids.find(id) != resolved_ids.end())
+ continue;
+
+ if (parent_decl_ctx &&
+ GetDeclContextContainingUID(id) != *parent_decl_ctx)
+ continue;
+
+ if (ResolveFunction(id, include_inlines, sc_list))
+ resolved_ids.insert(id);
}
};
if (name_type_mask & eFunctionNameTypeFull) {
ResolveFn(m_func_full_names);
+ ResolveFn(m_func_base_names);
+ ResolveFn(m_func_method_names);
}
if (name_type_mask & eFunctionNameTypeBase) {
ResolveFn(m_func_base_names);
@@ -1470,8 +1479,6 @@ void SymbolFilePDB::FindTypesByName(
llvm::StringRef name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, lldb_private::TypeMap &types) {
- if (!parent_decl_ctx)
- parent_decl_ctx = m_tu_decl_ctx_up.get();
std::unique_ptr<IPDBEnumSymbols> results;
if (name.empty())
return;
@@ -1505,9 +1512,8 @@ void SymbolFilePDB::FindTypesByName(
if (!ResolveTypeUID(result->getSymIndexId()))
continue;
- auto actual_parent_decl_ctx =
- GetDeclContextContainingUID(result->getSymIndexId());
- if (actual_parent_decl_ctx != *parent_decl_ctx)
+ if (parent_decl_ctx && GetDeclContextContainingUID(
+ result->getSymIndexId()) != *parent_decl_ctx)
continue;
auto iter = m_types.find(result->getSymIndexId());
More information about the lldb-commits
mailing list