1 //===-- SBCommandInterpreter.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/lldb-python.h" 11 12 #include "lldb/lldb-types.h" 13 #include "lldb/Core/SourceManager.h" 14 #include "lldb/Core/Listener.h" 15 #include "lldb/Interpreter/CommandInterpreter.h" 16 #include "lldb/Interpreter/CommandObjectMultiword.h" 17 #include "lldb/Interpreter/CommandReturnObject.h" 18 #include "lldb/Target/Target.h" 19 20 #include "lldb/API/SBBroadcaster.h" 21 #include "lldb/API/SBCommandReturnObject.h" 22 #include "lldb/API/SBCommandInterpreter.h" 23 #include "lldb/API/SBProcess.h" 24 #include "lldb/API/SBTarget.h" 25 #include "lldb/API/SBListener.h" 26 #include "lldb/API/SBStream.h" 27 #include "lldb/API/SBStringList.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 32 class CommandPluginInterfaceImplementation : public CommandObjectParsed 33 { 34 public: 35 CommandPluginInterfaceImplementation (CommandInterpreter &interpreter, 36 const char *name, 37 lldb::SBCommandPluginInterface* backend, 38 const char *help = NULL, 39 const char *syntax = NULL, 40 uint32_t flags = 0) : 41 CommandObjectParsed (interpreter, name, help, syntax, flags), 42 m_backend(backend) {} 43 44 virtual bool 45 IsRemovable() const { return true; } 46 47 protected: 48 virtual bool 49 DoExecute (Args& command, CommandReturnObject &result) 50 { 51 SBCommandReturnObject sb_return(&result); 52 SBCommandInterpreter sb_interpreter(&m_interpreter); 53 SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this()); 54 bool ret = m_backend->DoExecute (debugger_sb,(char**)command.GetArgumentVector(), sb_return); 55 sb_return.Release(); 56 return ret; 57 } 58 lldb::SBCommandPluginInterface* m_backend; 59 }; 60 61 SBCommandInterpreter::SBCommandInterpreter (CommandInterpreter *interpreter) : 62 m_opaque_ptr (interpreter) 63 { 64 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 65 66 if (log) 67 log->Printf ("SBCommandInterpreter::SBCommandInterpreter (interpreter=%p)" 68 " => SBCommandInterpreter(%p)", interpreter, m_opaque_ptr); 69 } 70 71 SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs) : 72 m_opaque_ptr (rhs.m_opaque_ptr) 73 { 74 } 75 76 const SBCommandInterpreter & 77 SBCommandInterpreter::operator = (const SBCommandInterpreter &rhs) 78 { 79 m_opaque_ptr = rhs.m_opaque_ptr; 80 return *this; 81 } 82 83 SBCommandInterpreter::~SBCommandInterpreter () 84 { 85 } 86 87 bool 88 SBCommandInterpreter::IsValid() const 89 { 90 return m_opaque_ptr != NULL; 91 } 92 93 94 bool 95 SBCommandInterpreter::CommandExists (const char *cmd) 96 { 97 if (cmd && m_opaque_ptr) 98 return m_opaque_ptr->CommandExists (cmd); 99 return false; 100 } 101 102 bool 103 SBCommandInterpreter::AliasExists (const char *cmd) 104 { 105 if (cmd && m_opaque_ptr) 106 return m_opaque_ptr->AliasExists (cmd); 107 return false; 108 } 109 110 lldb::ReturnStatus 111 SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnObject &result, bool add_to_history) 112 { 113 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 114 115 if (log) 116 log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p), add_to_history=%i)", 117 m_opaque_ptr, command_line, result.get(), add_to_history); 118 119 result.Clear(); 120 if (command_line && m_opaque_ptr) 121 { 122 m_opaque_ptr->HandleCommand (command_line, add_to_history ? eLazyBoolYes : eLazyBoolNo, result.ref()); 123 } 124 else 125 { 126 result->AppendError ("SBCommandInterpreter or the command line is not valid"); 127 result->SetStatus (eReturnStatusFailed); 128 } 129 130 // We need to get the value again, in case the command disabled the log! 131 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 132 if (log) 133 { 134 SBStream sstr; 135 result.GetDescription (sstr); 136 log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p): %s, add_to_history=%i) => %i", 137 m_opaque_ptr, command_line, result.get(), sstr.GetData(), add_to_history, result.GetStatus()); 138 } 139 140 return result.GetStatus(); 141 } 142 143 int 144 SBCommandInterpreter::HandleCompletion (const char *current_line, 145 const char *cursor, 146 const char *last_char, 147 int match_start_point, 148 int max_return_elements, 149 SBStringList &matches) 150 { 151 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 152 int num_completions = 0; 153 154 // Sanity check the arguments that are passed in: 155 // cursor & last_char have to be within the current_line. 156 if (current_line == NULL || cursor == NULL || last_char == NULL) 157 return 0; 158 159 if (cursor < current_line || last_char < current_line) 160 return 0; 161 162 size_t current_line_size = strlen (current_line); 163 if (cursor - current_line > current_line_size || last_char - current_line > current_line_size) 164 return 0; 165 166 if (log) 167 log->Printf ("SBCommandInterpreter(%p)::HandleCompletion (current_line=\"%s\", cursor at: %" PRId64 ", last char at: %" PRId64 ", match_start_point: %d, max_return_elements: %d)", 168 m_opaque_ptr, current_line, (uint64_t) (cursor - current_line), (uint64_t) (last_char - current_line), match_start_point, max_return_elements); 169 170 if (m_opaque_ptr) 171 { 172 lldb_private::StringList lldb_matches; 173 num_completions = m_opaque_ptr->HandleCompletion (current_line, cursor, last_char, match_start_point, 174 max_return_elements, lldb_matches); 175 176 SBStringList temp_list (&lldb_matches); 177 matches.AppendList (temp_list); 178 } 179 if (log) 180 log->Printf ("SBCommandInterpreter(%p)::HandleCompletion - Found %d completions.", m_opaque_ptr, num_completions); 181 182 return num_completions; 183 } 184 185 int 186 SBCommandInterpreter::HandleCompletion (const char *current_line, 187 uint32_t cursor_pos, 188 int match_start_point, 189 int max_return_elements, 190 lldb::SBStringList &matches) 191 { 192 const char *cursor = current_line + cursor_pos; 193 const char *last_char = current_line + strlen (current_line); 194 return HandleCompletion (current_line, cursor, last_char, match_start_point, max_return_elements, matches); 195 } 196 197 bool 198 SBCommandInterpreter::HasCommands () 199 { 200 if (m_opaque_ptr) 201 return m_opaque_ptr->HasCommands(); 202 return false; 203 } 204 205 bool 206 SBCommandInterpreter::HasAliases () 207 { 208 if (m_opaque_ptr) 209 return m_opaque_ptr->HasAliases(); 210 return false; 211 } 212 213 bool 214 SBCommandInterpreter::HasAliasOptions () 215 { 216 if (m_opaque_ptr) 217 return m_opaque_ptr->HasAliasOptions (); 218 return false; 219 } 220 221 SBProcess 222 SBCommandInterpreter::GetProcess () 223 { 224 SBProcess sb_process; 225 ProcessSP process_sp; 226 if (m_opaque_ptr) 227 { 228 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 229 if (target_sp) 230 { 231 Mutex::Locker api_locker(target_sp->GetAPIMutex()); 232 process_sp = target_sp->GetProcessSP(); 233 sb_process.SetSP(process_sp); 234 } 235 } 236 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 237 238 if (log) 239 log->Printf ("SBCommandInterpreter(%p)::GetProcess () => SBProcess(%p)", 240 m_opaque_ptr, process_sp.get()); 241 242 243 return sb_process; 244 } 245 246 SBDebugger 247 SBCommandInterpreter::GetDebugger () 248 { 249 SBDebugger sb_debugger; 250 if (m_opaque_ptr) 251 sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this()); 252 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 253 254 if (log) 255 log->Printf ("SBCommandInterpreter(%p)::GetDebugger () => SBDebugger(%p)", 256 m_opaque_ptr, sb_debugger.get()); 257 258 259 return sb_debugger; 260 } 261 262 CommandInterpreter * 263 SBCommandInterpreter::get () 264 { 265 return m_opaque_ptr; 266 } 267 268 CommandInterpreter & 269 SBCommandInterpreter::ref () 270 { 271 assert (m_opaque_ptr); 272 return *m_opaque_ptr; 273 } 274 275 void 276 SBCommandInterpreter::reset (lldb_private::CommandInterpreter *interpreter) 277 { 278 m_opaque_ptr = interpreter; 279 } 280 281 void 282 SBCommandInterpreter::SourceInitFileInHomeDirectory (SBCommandReturnObject &result) 283 { 284 result.Clear(); 285 if (m_opaque_ptr) 286 { 287 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 288 Mutex::Locker api_locker; 289 if (target_sp) 290 api_locker.Lock(target_sp->GetAPIMutex()); 291 m_opaque_ptr->SourceInitFile (false, result.ref()); 292 } 293 else 294 { 295 result->AppendError ("SBCommandInterpreter is not valid"); 296 result->SetStatus (eReturnStatusFailed); 297 } 298 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 299 300 if (log) 301 log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInHomeDirectory (&SBCommandReturnObject(%p))", 302 m_opaque_ptr, result.get()); 303 304 } 305 306 void 307 SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory (SBCommandReturnObject &result) 308 { 309 result.Clear(); 310 if (m_opaque_ptr) 311 { 312 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 313 Mutex::Locker api_locker; 314 if (target_sp) 315 api_locker.Lock(target_sp->GetAPIMutex()); 316 m_opaque_ptr->SourceInitFile (true, result.ref()); 317 } 318 else 319 { 320 result->AppendError ("SBCommandInterpreter is not valid"); 321 result->SetStatus (eReturnStatusFailed); 322 } 323 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 324 325 if (log) 326 log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInCurrentWorkingDirectory (&SBCommandReturnObject(%p))", 327 m_opaque_ptr, result.get()); 328 } 329 330 SBBroadcaster 331 SBCommandInterpreter::GetBroadcaster () 332 { 333 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 334 335 SBBroadcaster broadcaster (m_opaque_ptr, false); 336 337 if (log) 338 log->Printf ("SBCommandInterpreter(%p)::GetBroadcaster() => SBBroadcaster(%p)", 339 m_opaque_ptr, broadcaster.get()); 340 341 return broadcaster; 342 } 343 344 const char * 345 SBCommandInterpreter::GetBroadcasterClass () 346 { 347 return Communication::GetStaticBroadcasterClass().AsCString(); 348 } 349 350 const char * 351 SBCommandInterpreter::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type) 352 { 353 return CommandObject::GetArgumentTypeAsCString (arg_type); 354 } 355 356 const char * 357 SBCommandInterpreter::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type) 358 { 359 return CommandObject::GetArgumentDescriptionAsCString (arg_type); 360 } 361 362 bool 363 SBCommandInterpreter::SetCommandOverrideCallback (const char *command_name, 364 lldb::CommandOverrideCallback callback, 365 void *baton) 366 { 367 if (command_name && command_name[0] && m_opaque_ptr) 368 { 369 std::string command_name_str (command_name); 370 CommandObject *cmd_obj = m_opaque_ptr->GetCommandObjectForCommand(command_name_str); 371 if (cmd_obj) 372 { 373 assert(command_name_str.empty()); 374 cmd_obj->SetOverrideCallback (callback, baton); 375 return true; 376 } 377 } 378 return false; 379 } 380 381 #ifndef LLDB_DISABLE_PYTHON 382 383 // Defined in the SWIG source file 384 extern "C" void 385 init_lldb(void); 386 387 // these are the Pythonic implementations of the required callbacks 388 // these are scripting-language specific, which is why they belong here 389 // we still need to use function pointers to them instead of relying 390 // on linkage-time resolution because the SWIG stuff and this file 391 // get built at different times 392 extern "C" bool 393 LLDBSwigPythonBreakpointCallbackFunction (const char *python_function_name, 394 const char *session_dictionary_name, 395 const lldb::StackFrameSP& sb_frame, 396 const lldb::BreakpointLocationSP& sb_bp_loc); 397 398 extern "C" bool 399 LLDBSwigPythonWatchpointCallbackFunction (const char *python_function_name, 400 const char *session_dictionary_name, 401 const lldb::StackFrameSP& sb_frame, 402 const lldb::WatchpointSP& sb_wp); 403 404 extern "C" bool 405 LLDBSwigPythonCallTypeScript (const char *python_function_name, 406 void *session_dictionary, 407 const lldb::ValueObjectSP& valobj_sp, 408 void** pyfunct_wrapper, 409 std::string& retval); 410 411 extern "C" void* 412 LLDBSwigPythonCreateSyntheticProvider (const char *python_class_name, 413 const char *session_dictionary_name, 414 const lldb::ValueObjectSP& valobj_sp); 415 416 417 extern "C" uint32_t 418 LLDBSwigPython_CalculateNumChildren (void *implementor); 419 420 extern "C" void * 421 LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx); 422 423 extern "C" int 424 LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name); 425 426 extern "C" void * 427 LLDBSWIGPython_CastPyObjectToSBValue (void* data); 428 429 extern lldb::ValueObjectSP 430 LLDBSWIGPython_GetValueObjectSPFromSBValue (void* data); 431 432 extern "C" bool 433 LLDBSwigPython_UpdateSynthProviderInstance (void* implementor); 434 435 extern "C" bool 436 LLDBSwigPython_MightHaveChildrenSynthProviderInstance (void* implementor); 437 438 extern "C" bool 439 LLDBSwigPythonCallCommand (const char *python_function_name, 440 const char *session_dictionary_name, 441 lldb::DebuggerSP& debugger, 442 const char* args, 443 lldb_private::CommandReturnObject &cmd_retobj); 444 445 extern "C" bool 446 LLDBSwigPythonCallModuleInit (const char *python_module_name, 447 const char *session_dictionary_name, 448 lldb::DebuggerSP& debugger); 449 450 extern "C" void* 451 LLDBSWIGPythonCreateOSPlugin (const char *python_class_name, 452 const char *session_dictionary_name, 453 const lldb::ProcessSP& process_sp); 454 455 extern "C" bool 456 LLDBSWIGPythonRunScriptKeywordProcess (const char* python_function_name, 457 const char* session_dictionary_name, 458 lldb::ProcessSP& process, 459 std::string& output); 460 461 extern "C" bool 462 LLDBSWIGPythonRunScriptKeywordThread (const char* python_function_name, 463 const char* session_dictionary_name, 464 lldb::ThreadSP& thread, 465 std::string& output); 466 467 extern "C" bool 468 LLDBSWIGPythonRunScriptKeywordTarget (const char* python_function_name, 469 const char* session_dictionary_name, 470 lldb::TargetSP& target, 471 std::string& output); 472 473 extern "C" bool 474 LLDBSWIGPythonRunScriptKeywordFrame (const char* python_function_name, 475 const char* session_dictionary_name, 476 lldb::StackFrameSP& frame, 477 std::string& output); 478 479 extern "C" void* 480 LLDBSWIGPython_GetDynamicSetting (void* module, 481 const char* setting, 482 const lldb::TargetSP& target_sp); 483 484 485 #endif 486 487 void 488 SBCommandInterpreter::InitializeSWIG () 489 { 490 static bool g_initialized = false; 491 if (!g_initialized) 492 { 493 g_initialized = true; 494 #ifndef LLDB_DISABLE_PYTHON 495 ScriptInterpreter::InitializeInterpreter (init_lldb, 496 LLDBSwigPythonBreakpointCallbackFunction, 497 LLDBSwigPythonWatchpointCallbackFunction, 498 LLDBSwigPythonCallTypeScript, 499 LLDBSwigPythonCreateSyntheticProvider, 500 LLDBSwigPython_CalculateNumChildren, 501 LLDBSwigPython_GetChildAtIndex, 502 LLDBSwigPython_GetIndexOfChildWithName, 503 LLDBSWIGPython_CastPyObjectToSBValue, 504 LLDBSWIGPython_GetValueObjectSPFromSBValue, 505 LLDBSwigPython_UpdateSynthProviderInstance, 506 LLDBSwigPython_MightHaveChildrenSynthProviderInstance, 507 LLDBSwigPythonCallCommand, 508 LLDBSwigPythonCallModuleInit, 509 LLDBSWIGPythonCreateOSPlugin, 510 LLDBSWIGPythonRunScriptKeywordProcess, 511 LLDBSWIGPythonRunScriptKeywordThread, 512 LLDBSWIGPythonRunScriptKeywordTarget, 513 LLDBSWIGPythonRunScriptKeywordFrame, 514 LLDBSWIGPython_GetDynamicSetting); 515 #endif 516 } 517 } 518 519 lldb::SBCommand 520 SBCommandInterpreter::AddMultiwordCommand (const char* name, const char* help) 521 { 522 CommandObjectMultiword *new_command = new CommandObjectMultiword(*m_opaque_ptr,name,help); 523 new_command->SetRemovable (true); 524 lldb::CommandObjectSP new_command_sp(new_command); 525 if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) 526 return lldb::SBCommand(new_command_sp); 527 return lldb::SBCommand(); 528 } 529 530 lldb::SBCommand 531 SBCommandInterpreter::AddCommand (const char* name, lldb::SBCommandPluginInterface* impl, const char* help) 532 { 533 lldb::CommandObjectSP new_command_sp; 534 new_command_sp.reset(new CommandPluginInterfaceImplementation(*m_opaque_ptr,name,impl,help)); 535 536 if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) 537 return lldb::SBCommand(new_command_sp); 538 return lldb::SBCommand(); 539 } 540 541 SBCommand::SBCommand () 542 {} 543 544 SBCommand::SBCommand (lldb::CommandObjectSP cmd_sp) : m_opaque_sp (cmd_sp) 545 {} 546 547 bool 548 SBCommand::IsValid () 549 { 550 return (bool)m_opaque_sp; 551 } 552 553 const char* 554 SBCommand::GetName () 555 { 556 if (IsValid ()) 557 return m_opaque_sp->GetCommandName (); 558 return NULL; 559 } 560 561 const char* 562 SBCommand::GetHelp () 563 { 564 if (IsValid ()) 565 return m_opaque_sp->GetHelp (); 566 return NULL; 567 } 568 569 lldb::SBCommand 570 SBCommand::AddMultiwordCommand (const char* name, const char* help) 571 { 572 if (!IsValid ()) 573 return lldb::SBCommand(); 574 if (m_opaque_sp->IsMultiwordObject() == false) 575 return lldb::SBCommand(); 576 CommandObjectMultiword *new_command = new CommandObjectMultiword(m_opaque_sp->GetCommandInterpreter(),name,help); 577 new_command->SetRemovable (true); 578 lldb::CommandObjectSP new_command_sp(new_command); 579 if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp)) 580 return lldb::SBCommand(new_command_sp); 581 return lldb::SBCommand(); 582 } 583 584 lldb::SBCommand 585 SBCommand::AddCommand (const char* name, lldb::SBCommandPluginInterface *impl, const char* help) 586 { 587 if (!IsValid ()) 588 return lldb::SBCommand(); 589 if (m_opaque_sp->IsMultiwordObject() == false) 590 return lldb::SBCommand(); 591 lldb::CommandObjectSP new_command_sp; 592 new_command_sp.reset(new CommandPluginInterfaceImplementation(m_opaque_sp->GetCommandInterpreter(),name,impl,help)); 593 if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp)) 594 return lldb::SBCommand(new_command_sp); 595 return lldb::SBCommand(); 596 } 597 598