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