Author: jingham Date: Thu Sep 13 14:59:16 2018 New Revision: 342190 URL: http://llvm.org/viewvc/llvm-project?rev=342190&view=rev Log: svn add the new files...
I started from a clean slate to do the checkin, but forgot to svn add the new files. Do that now. Also add the one new source file to CMakeLists.txt Added: lldb/trunk/include/lldb/Breakpoint/BreakpointResolverScripted.h lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/Makefile lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/main.c lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/resolver.py lldb/trunk/source/Breakpoint/BreakpointResolverScripted.cpp Modified: lldb/trunk/source/Breakpoint/CMakeLists.txt Added: lldb/trunk/include/lldb/Breakpoint/BreakpointResolverScripted.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolverScripted.h?rev=342190&view=auto ============================================================================== --- lldb/trunk/include/lldb/Breakpoint/BreakpointResolverScripted.h (added) +++ lldb/trunk/include/lldb/Breakpoint/BreakpointResolverScripted.h Thu Sep 13 14:59:16 2018 @@ -0,0 +1,85 @@ +//===-- BreakpointResolverScripted.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointResolverScripted_h_ +#define liblldb_BreakpointResolverScripted_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-forward.h" +#include "lldb/Breakpoint/BreakpointResolver.h" +#include "lldb/Core/ModuleSpec.h" + + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class BreakpointResolverScripted BreakpointResolverScripted.h +/// "lldb/Breakpoint/BreakpointResolverScripted.h" This class sets breakpoints +/// on a given Address. This breakpoint only takes once, and then it won't +/// attempt to reset itself. +//---------------------------------------------------------------------- + +class BreakpointResolverScripted : public BreakpointResolver { +public: + BreakpointResolverScripted(Breakpoint *bkpt, + const llvm::StringRef class_name, + lldb::SearchDepth depth, + StructuredDataImpl *args_data, + ScriptInterpreter &script_interp); + + ~BreakpointResolverScripted() override; + + static BreakpointResolver * + CreateFromStructuredData(Breakpoint *bkpt, + const StructuredData::Dictionary &options_dict, + Status &error); + + StructuredData::ObjectSP SerializeToStructuredData() override; + + Searcher::CallbackReturn SearchCallback(SearchFilter &filter, + SymbolContext &context, Address *addr, + bool containing) override; + + lldb::SearchDepth GetDepth() override; + + void GetDescription(Stream *s) override; + + void Dump(Stream *s) const override; + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const BreakpointResolverScripted *) { return true; } + static inline bool classof(const BreakpointResolver *V) { + return V->getResolverID() == BreakpointResolver::PythonResolver; + } + + lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override; + +protected: + void NotifyBreakpointSet() override; +private: + void CreateImplementationIfNeeded(); + ScriptInterpreter *GetScriptInterpreter(); + + std::string m_class_name; + lldb::SearchDepth m_depth; + StructuredDataImpl *m_args_ptr; // We own this, but the implementation + // has to manage the UP (since that is + // how it gets stored in the + // SBStructuredData). + StructuredData::GenericSP m_implementation_sp; + + DISALLOW_COPY_AND_ASSIGN(BreakpointResolverScripted); +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointResolverScripted_h_ Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/Makefile?rev=342190&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/Makefile (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/Makefile Thu Sep 13 14:59:16 2018 @@ -0,0 +1,6 @@ +LEVEL = ../../../make + +C_SOURCES := main.c +CFLAGS_EXTRAS += -std=c99 + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py?rev=342190&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py Thu Sep 13 14:59:16 2018 @@ -0,0 +1,171 @@ +""" +Test setting breakpoints using a scripted resolver +""" + +from __future__ import print_function + + +import os +import time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + + +class TestScriptedResolver(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + NO_DEBUG_INFO_TESTCASE = True + + def test_scripted_resolver(self): + """Use a scripted resolver to set a by symbol name breakpoint""" + self.build() + self.do_test() + + def test_search_depths(self): + """ Make sure we are called at the right depths depending on what we return + from __get_depth__""" + self.build() + self.do_test_depths() + + def test_command_line(self): + """ Make sure we are called at the right depths depending on what we return + from __get_depth__""" + self.build() + self.do_test_cli() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + def make_target_and_import(self): + target = lldbutil.run_to_breakpoint_make_target(self) + interp = self.dbg.GetCommandInterpreter() + error = lldb.SBError() + + script_name = os.path.join(self.getSourceDir(), "resolver.py") + source_name = os.path.join(self.getSourceDir(), "main.c") + + command = "command script import " + script_name + result = lldb.SBCommandReturnObject() + interp.HandleCommand(command, result) + self.assertTrue(result.Succeeded(), "com scr imp failed: %s"%(result.GetError())) + return target + + def make_extra_args(self): + json_string = '{"symbol":"break_on_me", "test1": "value1"}' + json_stream = lldb.SBStream() + json_stream.Print(json_string) + extra_args = lldb.SBStructuredData() + error = extra_args.SetFromJSON(json_stream) + self.assertTrue(error.Success(), "Error making SBStructuredData: %s"%(error.GetCString())) + return extra_args + + def do_test(self): + """This reads in a python file and sets a breakpoint using it.""" + + target = self.make_target_and_import() + extra_args = self.make_extra_args() + + file_list = lldb.SBFileSpecList() + module_list = lldb.SBFileSpecList() + + # Make breakpoints with this resolver using different filters, first ones that will take: + right = [] + # one with no file or module spec - this one should fire: + right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) + + # one with the right source file and no module - should also fire: + file_list.Append(lldb.SBFileSpec("main.c")) + right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) + # Make sure the help text shows up in the "break list" output: + self.expect("break list", substrs=["I am a python breakpoint resolver"], msg="Help is listed in break list") + + # one with the right source file and right module - should also fire: + module_list.Append(lldb.SBFileSpec("a.out")) + right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) + + # And one with no source file but the right module: + file_list.Clear() + right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) + + # Make sure these all got locations: + for i in range (0, len(right)): + self.assertTrue(right[i].GetNumLocations() >= 1, "Breakpoint %d has no locations."%(i)) + + # Now some ones that won't take: + + module_list.Clear() + file_list.Clear() + wrong = [] + + # one with the wrong module - should not fire: + module_list.Append(lldb.SBFileSpec("noSuchModule")) + wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) + + # one with the wrong file - also should not fire: + module_list.Clear() + file_list.Append(lldb.SBFileSpec("noFileOfThisName.xxx")) + wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", 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)) + + # Now run to main and ensure we hit the breakpoints we should have: + + lldbutil.run_to_breakpoint_do_run(self, target, right[0]) + + # Test the hit counts: + for i in range(0, len(right)): + self.assertEqual(right[i].GetHitCount(), 1, "Breakpoint %d has the wrong hit count"%(i)) + + for i in range(0, len(wrong)): + self.assertEqual(wrong[i].GetHitCount(), 0, "Breakpoint %d has the wrong hit count"%(i)) + + def do_test_depths(self): + """This test uses a class variable in resolver.Resolver which gets set to 1 if we saw + compile unit and 2 if we only saw modules. If the search depth is module, you get passed just + the modules with no comp_unit. If the depth is comp_unit you get comp_units. So we can use + this to test that our callback gets called at the right depth.""" + + target = self.make_target_and_import() + extra_args = self.make_extra_args() + + file_list = lldb.SBFileSpecList() + module_list = lldb.SBFileSpecList() + module_list.Append(lldb.SBFileSpec("a.out")) + + # Make a breakpoint that has no __get_depth__, check that that is converted to eSearchDepthModule: + bkpt = target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list) + self.assertTrue(bkpt.GetNumLocations() > 0, "Resolver got no locations.") + self.expect("script print resolver.Resolver.got_files", substrs=["2"], msg="Was only passed modules") + + # Make a breakpoint that asks for modules, check that we didn't get any files: + bkpt = target.BreakpointCreateFromScript("resolver.ResolverModuleDepth", extra_args, module_list, file_list) + self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverModuleDepth got no locations.") + self.expect("script print resolver.Resolver.got_files", substrs=["2"], msg="Was only passed modules") + + # Make a breakpoint that asks for compile units, check that we didn't get any files: + bkpt = target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list) + self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverCUDepth got no locations.") + self.expect("script print resolver.Resolver.got_files", substrs=["1"], msg="Was passed compile units") + + # Make a breakpoint that returns a bad value - we should convert that to "modules" so check that: + bkpt = target.BreakpointCreateFromScript("resolver.ResolverBadDepth", extra_args, module_list, file_list) + 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") + + def do_test_cli(self): + target = self.make_target_and_import() + + lldbutil.run_break_set_by_script(self, "resolver.Resolver", extra_options="-k symbol -v break_on_me") Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/main.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/main.c?rev=342190&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/main.c (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/main.c Thu Sep 13 14:59:16 2018 @@ -0,0 +1,21 @@ +#include <stdio.h> + +int +test_func() +{ + return printf("I am a test function."); +} + +void +break_on_me() +{ + printf("I was called.\n"); +} + +int +main() +{ + break_on_me(); + test_func(); + return 0; +} Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/resolver.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/resolver.py?rev=342190&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/resolver.py (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/resolver.py Thu Sep 13 14:59:16 2018 @@ -0,0 +1,55 @@ +import lldb + +class Resolver: + got_files = 0 + func_list = [] + + def __init__(self, bkpt, extra_args, dict): + self.bkpt = bkpt + self.extra_args = extra_args + Resolver.func_list = [] + Resolver.got_files = 0 + + def __callback__(self, sym_ctx): + sym_name = "not_a_real_function_name" + sym_item = self.extra_args.GetValueForKey("symbol") + if sym_item.IsValid(): + sym_name = sym_item.GetStringValue(1000) + + if sym_ctx.compile_unit.IsValid(): + Resolver.got_files = 1 + else: + Resolver.got_files = 2 + + 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()) + return + + if sym_ctx.module.IsValid(): + sym = sym_ctx.module.FindSymbol(sym_name, lldb.eSymbolTypeCode) + if sym.IsValid(): + self.bkpt.AddLocation(sym.GetStartAddress()) + + def get_short_help(self): + return "I am a python breakpoint resolver" + +class ResolverModuleDepth(Resolver): + def __get_depth__ (self): + return lldb.eSearchDepthModule + +class ResolverCUDepth(Resolver): + def __get_depth__ (self): + return lldb.eSearchDepthCompUnit + +class ResolverFuncDepth(Resolver): + def __get_depth__ (self): + return lldb.eSearchDepthFunction + +class ResolverBadDepth(Resolver): + def __get_depth__ (self): + return lldb.kLastSearchDepthKind + 1 Added: lldb/trunk/source/Breakpoint/BreakpointResolverScripted.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverScripted.cpp?rev=342190&view=auto ============================================================================== --- lldb/trunk/source/Breakpoint/BreakpointResolverScripted.cpp (added) +++ lldb/trunk/source/Breakpoint/BreakpointResolverScripted.cpp Thu Sep 13 14:59:16 2018 @@ -0,0 +1,193 @@ +//===-- BreakpointResolverScripted.cpp ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Breakpoint/BreakpointResolverScripted.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// BreakpointResolverScripted: +//---------------------------------------------------------------------- +BreakpointResolverScripted::BreakpointResolverScripted( + Breakpoint *bkpt, + const llvm::StringRef class_name, + lldb::SearchDepth depth, + StructuredDataImpl *args_data, + ScriptInterpreter &script_interp) + : BreakpointResolver(bkpt, BreakpointResolver::PythonResolver), + m_class_name(class_name), m_depth(depth), m_args_ptr(args_data) { + CreateImplementationIfNeeded(); +} + +void BreakpointResolverScripted::CreateImplementationIfNeeded() { + if (m_implementation_sp) + return; + + if (m_class_name.empty()) + return; + + if (m_breakpoint) { + TargetSP target_sp = m_breakpoint->GetTargetSP(); + ScriptInterpreter *script_interp = target_sp->GetDebugger() + .GetCommandInterpreter() + .GetScriptInterpreter(); + if (!script_interp) + return; + lldb::BreakpointSP bkpt_sp(m_breakpoint->shared_from_this()); + m_implementation_sp = script_interp->CreateScriptedBreakpointResolver( + m_class_name.c_str(), m_args_ptr, bkpt_sp); + } +} + +void BreakpointResolverScripted::NotifyBreakpointSet() { + CreateImplementationIfNeeded(); +} + +BreakpointResolverScripted::~BreakpointResolverScripted() {} + +BreakpointResolver * +BreakpointResolverScripted::CreateFromStructuredData( + Breakpoint *bkpt, const StructuredData::Dictionary &options_dict, + Status &error) { + llvm::StringRef class_name; + bool success; + + if (!bkpt) + return nullptr; + + success = options_dict.GetValueForKeyAsString( + GetKey(OptionNames::PythonClassName), class_name); + if (!success) { + error.SetErrorString("BRFL::CFSD: Couldn't find class name entry."); + return nullptr; + } + lldb::SearchDepth depth; + int depth_as_int; + success = options_dict.GetValueForKeyAsInteger( + GetKey(OptionNames::SearchDepth), depth_as_int); + if (!success) { + error.SetErrorString("BRFL::CFSD: Couldn't find class name entry."); + return nullptr; + } + if (depth_as_int >= (int) OptionNames::LastOptionName) { + error.SetErrorString("BRFL::CFSD: Invalid value for search depth."); + return nullptr; + } + depth = (lldb::SearchDepth) depth_as_int; + + StructuredDataImpl *args_data_impl = new StructuredDataImpl(); + StructuredData::Dictionary *args_dict = new StructuredData::Dictionary(); + success = options_dict.GetValueForKeyAsDictionary( + GetKey(OptionNames::ScriptArgs), args_dict); + if (success) { + // FIXME: The resolver needs a copy of the ARGS dict that it can own, + // so I need to make a copy constructor for the Dictionary so I can pass + // that to it here. For now the args are empty. + //StructuredData::Dictionary *dict_copy = new StructuredData::Dictionary(args_dict); + + } + ScriptInterpreter *script_interp = bkpt->GetTarget() + .GetDebugger() + .GetCommandInterpreter() + .GetScriptInterpreter(); + return new BreakpointResolverScripted(bkpt, class_name, depth, args_data_impl, + *script_interp); +} + +StructuredData::ObjectSP +BreakpointResolverScripted::SerializeToStructuredData() { + StructuredData::DictionarySP options_dict_sp( + new StructuredData::Dictionary()); + + options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName), + m_class_name); + return WrapOptionsDict(options_dict_sp); +} + +ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() { + return m_breakpoint->GetTarget().GetDebugger().GetCommandInterpreter() + .GetScriptInterpreter(); +} + +Searcher::CallbackReturn +BreakpointResolverScripted::SearchCallback(SearchFilter &filter, + SymbolContext &context, Address *addr, + bool containing) { + assert(m_breakpoint != NULL); + bool should_continue = true; + if (!m_implementation_sp) + return Searcher::eCallbackReturnStop; + + ScriptInterpreter *interp = GetScriptInterpreter(); + should_continue = interp->ScriptedBreakpointResolverSearchCallback( + m_implementation_sp, + &context); + if (should_continue) + return Searcher::eCallbackReturnContinue; + else + return Searcher::eCallbackReturnStop; +} + +lldb::SearchDepth +BreakpointResolverScripted::GetDepth() { + assert(m_breakpoint != NULL); + lldb::SearchDepth depth = lldb::eSearchDepthModule; + if (m_implementation_sp) { + ScriptInterpreter *interp = GetScriptInterpreter(); + depth = interp->ScriptedBreakpointResolverSearchDepth( + m_implementation_sp); + } + return depth; +} + +void BreakpointResolverScripted::GetDescription(Stream *s) { + StructuredData::GenericSP generic_sp; + std::string short_help; + + if (m_implementation_sp) { + ScriptInterpreter *interp = GetScriptInterpreter(); + interp->GetShortHelpForCommandObject(m_implementation_sp, + short_help); + } + if (!short_help.empty()) + s->PutCString(short_help.c_str()); + else + s->Printf("python class = %s", m_class_name.c_str()); +} + +void BreakpointResolverScripted::Dump(Stream *s) const {} + +lldb::BreakpointResolverSP +BreakpointResolverScripted::CopyForBreakpoint(Breakpoint &breakpoint) { + ScriptInterpreter *script_interp = GetScriptInterpreter(); + // FIXME: Have to make a copy of the arguments from the m_args_ptr and then + // pass that to the new resolver. + lldb::BreakpointResolverSP ret_sp( + new BreakpointResolverScripted(&breakpoint, m_class_name, + m_depth, nullptr, *script_interp)); + return ret_sp; +} Modified: lldb/trunk/source/Breakpoint/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/CMakeLists.txt?rev=342190&r1=342189&r2=342190&view=diff ============================================================================== --- lldb/trunk/source/Breakpoint/CMakeLists.txt (original) +++ lldb/trunk/source/Breakpoint/CMakeLists.txt Thu Sep 13 14:59:16 2018 @@ -13,6 +13,7 @@ add_lldb_library(lldbBreakpoint BreakpointResolverFileLine.cpp BreakpointResolverFileRegex.cpp BreakpointResolverName.cpp + BreakpointResolverScripted.cpp BreakpointSite.cpp BreakpointSiteList.cpp Stoppoint.cpp _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits