1 //===-- BreakpointResolverScripted.cpp ---------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Breakpoint/BreakpointResolverScripted.h" 11 12 13 #include "lldb/Breakpoint/BreakpointLocation.h" 14 #include "lldb/Core/Debugger.h" 15 #include "lldb/Core/Module.h" 16 #include "lldb/Core/Section.h" 17 #include "lldb/Core/StructuredDataImpl.h" 18 #include "lldb/Interpreter/CommandInterpreter.h" 19 #include "lldb/Interpreter/ScriptInterpreter.h" 20 #include "lldb/Target/Process.h" 21 #include "lldb/Target/Target.h" 22 #include "lldb/Utility/Log.h" 23 #include "lldb/Utility/StreamString.h" 24 25 using namespace lldb; 26 using namespace lldb_private; 27 28 //---------------------------------------------------------------------- 29 // BreakpointResolverScripted: 30 //---------------------------------------------------------------------- 31 BreakpointResolverScripted::BreakpointResolverScripted( 32 Breakpoint *bkpt, 33 const llvm::StringRef class_name, 34 lldb::SearchDepth depth, 35 StructuredDataImpl *args_data, 36 ScriptInterpreter &script_interp) 37 : BreakpointResolver(bkpt, BreakpointResolver::PythonResolver), 38 m_class_name(class_name), m_depth(depth), m_args_ptr(args_data) { 39 CreateImplementationIfNeeded(); 40 } 41 42 void BreakpointResolverScripted::CreateImplementationIfNeeded() { 43 if (m_implementation_sp) 44 return; 45 46 if (m_class_name.empty()) 47 return; 48 49 if (m_breakpoint) { 50 TargetSP target_sp = m_breakpoint->GetTargetSP(); 51 ScriptInterpreter *script_interp = target_sp->GetDebugger() 52 .GetCommandInterpreter() 53 .GetScriptInterpreter(); 54 if (!script_interp) 55 return; 56 lldb::BreakpointSP bkpt_sp(m_breakpoint->shared_from_this()); 57 m_implementation_sp = script_interp->CreateScriptedBreakpointResolver( 58 m_class_name.c_str(), m_args_ptr, bkpt_sp); 59 } 60 } 61 62 void BreakpointResolverScripted::NotifyBreakpointSet() { 63 CreateImplementationIfNeeded(); 64 } 65 66 BreakpointResolverScripted::~BreakpointResolverScripted() {} 67 68 BreakpointResolver * 69 BreakpointResolverScripted::CreateFromStructuredData( 70 Breakpoint *bkpt, const StructuredData::Dictionary &options_dict, 71 Status &error) { 72 llvm::StringRef class_name; 73 bool success; 74 75 if (!bkpt) 76 return nullptr; 77 78 success = options_dict.GetValueForKeyAsString( 79 GetKey(OptionNames::PythonClassName), class_name); 80 if (!success) { 81 error.SetErrorString("BRFL::CFSD: Couldn't find class name entry."); 82 return nullptr; 83 } 84 lldb::SearchDepth depth; 85 int depth_as_int; 86 success = options_dict.GetValueForKeyAsInteger( 87 GetKey(OptionNames::SearchDepth), depth_as_int); 88 if (!success) { 89 error.SetErrorString("BRFL::CFSD: Couldn't find class name entry."); 90 return nullptr; 91 } 92 if (depth_as_int >= (int) OptionNames::LastOptionName) { 93 error.SetErrorString("BRFL::CFSD: Invalid value for search depth."); 94 return nullptr; 95 } 96 depth = (lldb::SearchDepth) depth_as_int; 97 98 StructuredDataImpl *args_data_impl = new StructuredDataImpl(); 99 StructuredData::Dictionary *args_dict = new StructuredData::Dictionary(); 100 success = options_dict.GetValueForKeyAsDictionary( 101 GetKey(OptionNames::ScriptArgs), args_dict); 102 if (success) { 103 // FIXME: The resolver needs a copy of the ARGS dict that it can own, 104 // so I need to make a copy constructor for the Dictionary so I can pass 105 // that to it here. For now the args are empty. 106 //StructuredData::Dictionary *dict_copy = new StructuredData::Dictionary(args_dict); 107 108 } 109 ScriptInterpreter *script_interp = bkpt->GetTarget() 110 .GetDebugger() 111 .GetCommandInterpreter() 112 .GetScriptInterpreter(); 113 return new BreakpointResolverScripted(bkpt, class_name, depth, args_data_impl, 114 *script_interp); 115 } 116 117 StructuredData::ObjectSP 118 BreakpointResolverScripted::SerializeToStructuredData() { 119 StructuredData::DictionarySP options_dict_sp( 120 new StructuredData::Dictionary()); 121 122 options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName), 123 m_class_name); 124 return WrapOptionsDict(options_dict_sp); 125 } 126 127 ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() { 128 return m_breakpoint->GetTarget().GetDebugger().GetCommandInterpreter() 129 .GetScriptInterpreter(); 130 } 131 132 Searcher::CallbackReturn 133 BreakpointResolverScripted::SearchCallback(SearchFilter &filter, 134 SymbolContext &context, Address *addr, 135 bool containing) { 136 assert(m_breakpoint != NULL); 137 bool should_continue = true; 138 if (!m_implementation_sp) 139 return Searcher::eCallbackReturnStop; 140 141 ScriptInterpreter *interp = GetScriptInterpreter(); 142 should_continue = interp->ScriptedBreakpointResolverSearchCallback( 143 m_implementation_sp, 144 &context); 145 if (should_continue) 146 return Searcher::eCallbackReturnContinue; 147 else 148 return Searcher::eCallbackReturnStop; 149 } 150 151 lldb::SearchDepth 152 BreakpointResolverScripted::GetDepth() { 153 assert(m_breakpoint != NULL); 154 lldb::SearchDepth depth = lldb::eSearchDepthModule; 155 if (m_implementation_sp) { 156 ScriptInterpreter *interp = GetScriptInterpreter(); 157 depth = interp->ScriptedBreakpointResolverSearchDepth( 158 m_implementation_sp); 159 } 160 return depth; 161 } 162 163 void BreakpointResolverScripted::GetDescription(Stream *s) { 164 StructuredData::GenericSP generic_sp; 165 std::string short_help; 166 167 if (m_implementation_sp) { 168 ScriptInterpreter *interp = GetScriptInterpreter(); 169 interp->GetShortHelpForCommandObject(m_implementation_sp, 170 short_help); 171 } 172 if (!short_help.empty()) 173 s->PutCString(short_help.c_str()); 174 else 175 s->Printf("python class = %s", m_class_name.c_str()); 176 } 177 178 void BreakpointResolverScripted::Dump(Stream *s) const {} 179 180 lldb::BreakpointResolverSP 181 BreakpointResolverScripted::CopyForBreakpoint(Breakpoint &breakpoint) { 182 ScriptInterpreter *script_interp = GetScriptInterpreter(); 183 // FIXME: Have to make a copy of the arguments from the m_args_ptr and then 184 // pass that to the new resolver. 185 lldb::BreakpointResolverSP ret_sp( 186 new BreakpointResolverScripted(&breakpoint, m_class_name, 187 m_depth, nullptr, *script_interp)); 188 return ret_sp; 189 } 190