From 19a5f6202c2f4fb2929f31f81e49539a558c5f19 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Fri, 14 Sep 2018 18:41:40 +0000 Subject: [PATCH] Make the eSearchDepthFunction searches work, add tests using the scripted breakpoint resolver. Differential Revision: https://reviews.llvm.org/D52111 llvm-svn: 342259 --- lldb/include/lldb/Core/SearchFilter.h | 12 +++++++ .../scripted_bkpt/TestScriptedResolver.py | 36 ++++++++++++++++---- .../breakpoint/scripted_bkpt/resolver.py | 3 +- lldb/source/Core/SearchFilter.cpp | 39 ++++++++++++++++++++-- 4 files changed, 80 insertions(+), 10 deletions(-) diff --git a/lldb/include/lldb/Core/SearchFilter.h b/lldb/include/lldb/Core/SearchFilter.h index 08d4b95..57b3831 100644 --- a/lldb/include/lldb/Core/SearchFilter.h +++ b/lldb/include/lldb/Core/SearchFilter.h @@ -184,6 +184,18 @@ public: virtual bool CompUnitPasses(CompileUnit &compUnit); //------------------------------------------------------------------ + /// Call this method with a Function to see if \a function passes the + /// filter. + /// + /// @param[in] function + /// The Functions to check against the filter. + /// + /// @return + /// \b true if \a function passes, and \b false otherwise. + //------------------------------------------------------------------ + virtual bool FunctionPasses(Function &function); + + //------------------------------------------------------------------ /// Call this method to do the search using the Searcher. /// /// @param[in] searcher diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py index 9f4c180..62f756b 100644 --- a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py @@ -106,10 +106,35 @@ class TestScriptedResolver(TestBase): wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) # one with the wrong file - also should not fire: + file_list.Clear() module_list.Clear() file_list.Append(lldb.SBFileSpec("noFileOfThisName.xxx")) wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) + # Now make sure the CU level iteration obeys the file filters: + file_list.Clear() + module_list.Clear() + file_list.Append(lldb.SBFileSpec("no_such_file.xxx")) + wrong.append(target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list)) + + # And the Module filters: + file_list.Clear() + module_list.Clear() + module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib")) + wrong.append(target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list)) + + # Now make sure the Function level iteration obeys the file filters: + file_list.Clear() + module_list.Clear() + file_list.Append(lldb.SBFileSpec("no_such_file.xxx")) + wrong.append(target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list)) + + # And the Module filters: + file_list.Clear() + module_list.Clear() + module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib")) + wrong.append(target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list)) + # Make sure these didn't get locations: for i in range(0, len(wrong)): self.assertEqual(wrong[i].GetNumLocations(), 0, "Breakpoint %d has locations."%(i)) @@ -158,12 +183,11 @@ class TestScriptedResolver(TestBase): self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverBadDepth got no locations.") self.expect("script print resolver.Resolver.got_files", substrs=["2"], msg="Was only passed modules") - # Make a breakpoint that searches at function depth - FIXME: uncomment this when I fix the function - # depth search. - #bkpt = target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list) - #self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverFuncDepth got no locations.") - #self.expect("script print resolver.Resolver.got_files", substrs=["3"], msg="Was only passed modules") - #self.expect("script print resolver.Resolver.func_list", substrs=["break_on_me", "main", "test_func"], msg="Saw all the functions") + # Make a breakpoint that searches at function depth: + bkpt = target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list) + self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverFuncDepth got no locations.") + self.expect("script print resolver.Resolver.got_files", substrs=["3"], msg="Was only passed modules") + self.expect("script print resolver.Resolver.func_list", substrs=["break_on_me", "main", "test_func"], msg="Saw all the functions") def do_test_cli(self): target = self.make_target_and_import() diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/resolver.py b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/resolver.py index 5e068d6..61f5f2d 100644 --- a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/resolver.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/resolver.py @@ -24,10 +24,9 @@ class Resolver: if sym_ctx.function.IsValid(): Resolver.got_files = 3 func_name = sym_ctx.function.GetName() - print("got called with: ", func_name) Resolver.func_list.append(func_name) if sym_name == func_name: - self.bkpt.AddLocations(func.GetStartAddress()) + self.bkpt.AddLocation(sym_ctx.function.GetStartAddress()) return if sym_ctx.module.IsValid(): diff --git a/lldb/source/Core/SearchFilter.cpp b/lldb/source/Core/SearchFilter.cpp index 50c006c..baef7b0 100644 --- a/lldb/source/Core/SearchFilter.cpp +++ b/lldb/source/Core/SearchFilter.cpp @@ -14,6 +14,7 @@ #include "lldb/Core/ModuleList.h" // for ModuleList #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/SymbolContext.h" // for SymbolContext +#include "lldb/Symbol/SymbolVendor.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ConstString.h" // for ConstString #include "lldb/Utility/Status.h" // for Status @@ -147,6 +148,15 @@ bool SearchFilter::CompUnitPasses(FileSpec &fileSpec) { return true; } bool SearchFilter::CompUnitPasses(CompileUnit &compUnit) { return true; } +bool SearchFilter::FunctionPasses(Function &function) { + // This is a slightly cheesy job, but since we don't have finer grained + // filters yet, just checking that the start address passes is probably + // good enough for the base class behavior. + Address addr = function.GetAddressRange().GetBaseAddress(); + return AddressPasses(addr); +} + + uint32_t SearchFilter::GetFilterRequiredItems() { return (lldb::SymbolContextItem)0; } @@ -311,8 +321,33 @@ SearchFilter::DoCUIteration(const ModuleSP &module_sp, return Searcher::eCallbackReturnContinue; else if (shouldContinue == Searcher::eCallbackReturnStop) return shouldContinue; - } else if (searcher.GetDepth() == lldb::eSearchDepthFunction) { - // FIXME Descend to block. + } else { + // First make sure this compile unit's functions are parsed + // since CompUnit::ForeachFunction only iterates over already + // parsed functions. + SymbolVendor *sym_vendor = module_sp->GetSymbolVendor(); + if (!sym_vendor) + continue; + SymbolContext sym_ctx; + cu_sp->CalculateSymbolContext(&sym_ctx); + if (!sym_vendor->ParseCompileUnitFunctions(sym_ctx)) + continue; + // If we got any functions, use ForeachFunction to do the iteration. + cu_sp->ForeachFunction([&](const FunctionSP &func_sp) { + if (!FunctionPasses(*func_sp.get())) + return false; // Didn't pass the filter, just keep going. + if (searcher.GetDepth() == lldb::eSearchDepthFunction) { + SymbolContext matchingContext(m_target_sp, module_sp, + cu_sp.get(), func_sp.get()); + shouldContinue = searcher.SearchCallback(*this, + matchingContext, + nullptr, false); + } else { + shouldContinue = DoFunctionIteration(func_sp.get(), context, + searcher); + } + return shouldContinue != Searcher::eCallbackReturnContinue; + }); } } } -- 2.7.4