1 //===-- CommandInterpreter.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 <string> 13 #include <vector> 14 #include <stdlib.h> 15 16 #include "CommandObjectScript.h" 17 #include "lldb/Interpreter/CommandObjectRegexCommand.h" 18 19 #include "../Commands/CommandObjectApropos.h" 20 #include "../Commands/CommandObjectArgs.h" 21 #include "../Commands/CommandObjectBreakpoint.h" 22 #include "../Commands/CommandObjectDisassemble.h" 23 #include "../Commands/CommandObjectExpression.h" 24 #include "../Commands/CommandObjectFrame.h" 25 #include "../Commands/CommandObjectGUI.h" 26 #include "../Commands/CommandObjectHelp.h" 27 #include "../Commands/CommandObjectLog.h" 28 #include "../Commands/CommandObjectMemory.h" 29 #include "../Commands/CommandObjectPlatform.h" 30 #include "../Commands/CommandObjectPlugin.h" 31 #include "../Commands/CommandObjectProcess.h" 32 #include "../Commands/CommandObjectQuit.h" 33 #include "../Commands/CommandObjectRegister.h" 34 #include "../Commands/CommandObjectSettings.h" 35 #include "../Commands/CommandObjectSource.h" 36 #include "../Commands/CommandObjectCommands.h" 37 #include "../Commands/CommandObjectSyntax.h" 38 #include "../Commands/CommandObjectTarget.h" 39 #include "../Commands/CommandObjectThread.h" 40 #include "../Commands/CommandObjectType.h" 41 #include "../Commands/CommandObjectVersion.h" 42 #include "../Commands/CommandObjectWatchpoint.h" 43 44 45 #include "lldb/Core/Debugger.h" 46 #include "lldb/Core/Log.h" 47 #include "lldb/Core/State.h" 48 #include "lldb/Core/Stream.h" 49 #include "lldb/Core/StreamFile.h" 50 #include "lldb/Core/Timer.h" 51 52 #ifndef LLDB_DISABLE_LIBEDIT 53 #include "lldb/Host/Editline.h" 54 #endif 55 #include "lldb/Host/Host.h" 56 #include "lldb/Host/HostInfo.h" 57 58 #include "lldb/Interpreter/Args.h" 59 #include "lldb/Interpreter/CommandCompletions.h" 60 #include "lldb/Interpreter/CommandInterpreter.h" 61 #include "lldb/Interpreter/CommandReturnObject.h" 62 #include "lldb/Interpreter/Options.h" 63 #include "lldb/Interpreter/OptionValueProperties.h" 64 #include "lldb/Interpreter/Property.h" 65 #include "lldb/Interpreter/ScriptInterpreterNone.h" 66 #include "lldb/Interpreter/ScriptInterpreterPython.h" 67 68 69 #include "lldb/Target/Process.h" 70 #include "lldb/Target/Thread.h" 71 #include "lldb/Target/TargetList.h" 72 73 #include "lldb/Utility/CleanUp.h" 74 75 #include "llvm/ADT/SmallString.h" 76 #include "llvm/ADT/STLExtras.h" 77 #include "llvm/Support/Path.h" 78 79 using namespace lldb; 80 using namespace lldb_private; 81 82 83 static PropertyDefinition 84 g_properties[] = 85 { 86 { "expand-regex-aliases", OptionValue::eTypeBoolean, true, false, nullptr, nullptr, "If true, regular expression alias commands will show the expanded command that will be executed. This can be used to debug new regular expression alias commands." }, 87 { "prompt-on-quit", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, LLDB will prompt you before quitting if there are any live processes being debugged. If false, LLDB will quit without asking in any case." }, 88 { "stop-command-source-on-error", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, LLDB will stop running a 'command source' script upon encountering an error." }, 89 { nullptr , OptionValue::eTypeInvalid, true, 0 , nullptr, nullptr, nullptr } 90 }; 91 92 enum 93 { 94 ePropertyExpandRegexAliases = 0, 95 ePropertyPromptOnQuit = 1, 96 ePropertyStopCmdSourceOnError = 2 97 }; 98 99 ConstString & 100 CommandInterpreter::GetStaticBroadcasterClass () 101 { 102 static ConstString class_name ("lldb.commandInterpreter"); 103 return class_name; 104 } 105 106 CommandInterpreter::CommandInterpreter 107 ( 108 Debugger &debugger, 109 ScriptLanguage script_language, 110 bool synchronous_execution 111 ) : 112 Broadcaster (&debugger, "lldb.command-interpreter"), 113 Properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))), 114 IOHandlerDelegate (IOHandlerDelegate::Completion::LLDBCommand), 115 m_debugger (debugger), 116 m_synchronous_execution (synchronous_execution), 117 m_skip_lldbinit_files (false), 118 m_skip_app_init_files (false), 119 m_script_interpreter_ap (), 120 m_command_io_handler_sp (), 121 m_comment_char ('#'), 122 m_batch_command_mode (false), 123 m_truncation_warning(eNoTruncation), 124 m_command_source_depth (0), 125 m_num_errors(0), 126 m_quit_requested(false), 127 m_stopped_for_crash(false) 128 129 { 130 debugger.SetScriptLanguage (script_language); 131 SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit"); 132 SetEventName (eBroadcastBitResetPrompt, "reset-prompt"); 133 SetEventName (eBroadcastBitQuitCommandReceived, "quit"); 134 CheckInWithManager (); 135 m_collection_sp->Initialize (g_properties); 136 } 137 138 bool 139 CommandInterpreter::GetExpandRegexAliases () const 140 { 141 const uint32_t idx = ePropertyExpandRegexAliases; 142 return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0); 143 } 144 145 bool 146 CommandInterpreter::GetPromptOnQuit () const 147 { 148 const uint32_t idx = ePropertyPromptOnQuit; 149 return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0); 150 } 151 152 bool 153 CommandInterpreter::GetStopCmdSourceOnError () const 154 { 155 const uint32_t idx = ePropertyStopCmdSourceOnError; 156 return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0); 157 } 158 159 void 160 CommandInterpreter::Initialize () 161 { 162 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 163 164 CommandReturnObject result; 165 166 LoadCommandDictionary (); 167 168 // Set up some initial aliases. 169 CommandObjectSP cmd_obj_sp = GetCommandSPExact ("quit", false); 170 if (cmd_obj_sp) 171 { 172 AddAlias ("q", cmd_obj_sp); 173 AddAlias ("exit", cmd_obj_sp); 174 } 175 176 cmd_obj_sp = GetCommandSPExact ("_regexp-attach",false); 177 if (cmd_obj_sp) 178 { 179 AddAlias ("attach", cmd_obj_sp); 180 } 181 182 cmd_obj_sp = GetCommandSPExact ("process detach",false); 183 if (cmd_obj_sp) 184 { 185 AddAlias ("detach", cmd_obj_sp); 186 } 187 188 cmd_obj_sp = GetCommandSPExact ("process continue", false); 189 if (cmd_obj_sp) 190 { 191 AddAlias ("c", cmd_obj_sp); 192 AddAlias ("continue", cmd_obj_sp); 193 } 194 195 cmd_obj_sp = GetCommandSPExact ("_regexp-break",false); 196 if (cmd_obj_sp) 197 AddAlias ("b", cmd_obj_sp); 198 199 cmd_obj_sp = GetCommandSPExact ("_regexp-tbreak",false); 200 if (cmd_obj_sp) 201 AddAlias ("tbreak", cmd_obj_sp); 202 203 cmd_obj_sp = GetCommandSPExact ("thread step-inst", false); 204 if (cmd_obj_sp) 205 { 206 AddAlias ("stepi", cmd_obj_sp); 207 AddAlias ("si", cmd_obj_sp); 208 } 209 210 cmd_obj_sp = GetCommandSPExact ("thread step-inst-over", false); 211 if (cmd_obj_sp) 212 { 213 AddAlias ("nexti", cmd_obj_sp); 214 AddAlias ("ni", cmd_obj_sp); 215 } 216 217 cmd_obj_sp = GetCommandSPExact ("thread step-in", false); 218 if (cmd_obj_sp) 219 { 220 AddAlias ("s", cmd_obj_sp); 221 AddAlias ("step", cmd_obj_sp); 222 } 223 224 cmd_obj_sp = GetCommandSPExact ("thread step-over", false); 225 if (cmd_obj_sp) 226 { 227 AddAlias ("n", cmd_obj_sp); 228 AddAlias ("next", cmd_obj_sp); 229 } 230 231 cmd_obj_sp = GetCommandSPExact ("thread step-out", false); 232 if (cmd_obj_sp) 233 { 234 AddAlias ("finish", cmd_obj_sp); 235 } 236 237 cmd_obj_sp = GetCommandSPExact ("frame select", false); 238 if (cmd_obj_sp) 239 { 240 AddAlias ("f", cmd_obj_sp); 241 } 242 243 cmd_obj_sp = GetCommandSPExact ("thread select", false); 244 if (cmd_obj_sp) 245 { 246 AddAlias ("t", cmd_obj_sp); 247 } 248 249 cmd_obj_sp = GetCommandSPExact ("_regexp-jump",false); 250 if (cmd_obj_sp) 251 { 252 AddAlias ("j", cmd_obj_sp); 253 AddAlias ("jump", cmd_obj_sp); 254 } 255 256 cmd_obj_sp = GetCommandSPExact ("_regexp-list", false); 257 if (cmd_obj_sp) 258 { 259 AddAlias ("l", cmd_obj_sp); 260 AddAlias ("list", cmd_obj_sp); 261 } 262 263 cmd_obj_sp = GetCommandSPExact ("_regexp-env", false); 264 if (cmd_obj_sp) 265 { 266 AddAlias ("env", cmd_obj_sp); 267 } 268 269 cmd_obj_sp = GetCommandSPExact ("memory read", false); 270 if (cmd_obj_sp) 271 AddAlias ("x", cmd_obj_sp); 272 273 cmd_obj_sp = GetCommandSPExact ("_regexp-up", false); 274 if (cmd_obj_sp) 275 AddAlias ("up", cmd_obj_sp); 276 277 cmd_obj_sp = GetCommandSPExact ("_regexp-down", false); 278 if (cmd_obj_sp) 279 AddAlias ("down", cmd_obj_sp); 280 281 cmd_obj_sp = GetCommandSPExact ("_regexp-display", false); 282 if (cmd_obj_sp) 283 AddAlias ("display", cmd_obj_sp); 284 285 cmd_obj_sp = GetCommandSPExact ("disassemble", false); 286 if (cmd_obj_sp) 287 AddAlias ("dis", cmd_obj_sp); 288 289 cmd_obj_sp = GetCommandSPExact ("disassemble", false); 290 if (cmd_obj_sp) 291 AddAlias ("di", cmd_obj_sp); 292 293 294 295 cmd_obj_sp = GetCommandSPExact ("_regexp-undisplay", false); 296 if (cmd_obj_sp) 297 AddAlias ("undisplay", cmd_obj_sp); 298 299 cmd_obj_sp = GetCommandSPExact ("_regexp-bt", false); 300 if (cmd_obj_sp) 301 AddAlias ("bt", cmd_obj_sp); 302 303 cmd_obj_sp = GetCommandSPExact ("target create", false); 304 if (cmd_obj_sp) 305 AddAlias ("file", cmd_obj_sp); 306 307 cmd_obj_sp = GetCommandSPExact ("target modules", false); 308 if (cmd_obj_sp) 309 AddAlias ("image", cmd_obj_sp); 310 311 312 OptionArgVectorSP alias_arguments_vector_sp (new OptionArgVector); 313 314 cmd_obj_sp = GetCommandSPExact ("expression", false); 315 if (cmd_obj_sp) 316 { 317 ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp); 318 AddAlias ("p", cmd_obj_sp); 319 AddAlias ("print", cmd_obj_sp); 320 AddAlias ("call", cmd_obj_sp); 321 AddOrReplaceAliasOptions ("p", alias_arguments_vector_sp); 322 AddOrReplaceAliasOptions ("print", alias_arguments_vector_sp); 323 AddOrReplaceAliasOptions ("call", alias_arguments_vector_sp); 324 325 alias_arguments_vector_sp.reset (new OptionArgVector); 326 ProcessAliasOptionsArgs (cmd_obj_sp, "-O -- ", alias_arguments_vector_sp); 327 AddAlias ("po", cmd_obj_sp); 328 AddOrReplaceAliasOptions ("po", alias_arguments_vector_sp); 329 } 330 331 cmd_obj_sp = GetCommandSPExact ("process kill", false); 332 if (cmd_obj_sp) 333 { 334 AddAlias ("kill", cmd_obj_sp); 335 } 336 337 cmd_obj_sp = GetCommandSPExact ("process launch", false); 338 if (cmd_obj_sp) 339 { 340 alias_arguments_vector_sp.reset (new OptionArgVector); 341 #if defined (__arm__) || defined (__arm64__) || defined (__aarch64__) 342 ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp); 343 #else 344 std::string shell_option; 345 shell_option.append("--shell="); 346 shell_option.append(HostInfo::GetDefaultShell().GetPath()); 347 shell_option.append(" --"); 348 ProcessAliasOptionsArgs (cmd_obj_sp, shell_option.c_str(), alias_arguments_vector_sp); 349 #endif 350 AddAlias ("r", cmd_obj_sp); 351 AddAlias ("run", cmd_obj_sp); 352 AddOrReplaceAliasOptions ("r", alias_arguments_vector_sp); 353 AddOrReplaceAliasOptions ("run", alias_arguments_vector_sp); 354 } 355 356 cmd_obj_sp = GetCommandSPExact ("target symbols add", false); 357 if (cmd_obj_sp) 358 { 359 AddAlias ("add-dsym", cmd_obj_sp); 360 } 361 362 cmd_obj_sp = GetCommandSPExact ("breakpoint set", false); 363 if (cmd_obj_sp) 364 { 365 alias_arguments_vector_sp.reset (new OptionArgVector); 366 ProcessAliasOptionsArgs (cmd_obj_sp, "--func-regex %1", alias_arguments_vector_sp); 367 AddAlias ("rbreak", cmd_obj_sp); 368 AddOrReplaceAliasOptions("rbreak", alias_arguments_vector_sp); 369 } 370 } 371 372 void 373 CommandInterpreter::Clear() 374 { 375 m_command_io_handler_sp.reset(); 376 377 if (m_script_interpreter_ap) 378 m_script_interpreter_ap->Clear(); 379 } 380 381 const char * 382 CommandInterpreter::ProcessEmbeddedScriptCommands (const char *arg) 383 { 384 // This function has not yet been implemented. 385 386 // Look for any embedded script command 387 // If found, 388 // get interpreter object from the command dictionary, 389 // call execute_one_command on it, 390 // get the results as a string, 391 // substitute that string for current stuff. 392 393 return arg; 394 } 395 396 397 void 398 CommandInterpreter::LoadCommandDictionary () 399 { 400 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 401 402 lldb::ScriptLanguage script_language = m_debugger.GetScriptLanguage(); 403 404 m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos (*this)); 405 m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this)); 406 m_command_dict["command"] = CommandObjectSP (new CommandObjectMultiwordCommands (*this)); 407 m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this)); 408 m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this)); 409 m_command_dict["frame"] = CommandObjectSP (new CommandObjectMultiwordFrame (*this)); 410 m_command_dict["gui"] = CommandObjectSP (new CommandObjectGUI (*this)); 411 m_command_dict["help"] = CommandObjectSP (new CommandObjectHelp (*this)); 412 m_command_dict["log"] = CommandObjectSP (new CommandObjectLog (*this)); 413 m_command_dict["memory"] = CommandObjectSP (new CommandObjectMemory (*this)); 414 m_command_dict["platform"] = CommandObjectSP (new CommandObjectPlatform (*this)); 415 m_command_dict["plugin"] = CommandObjectSP (new CommandObjectPlugin (*this)); 416 m_command_dict["process"] = CommandObjectSP (new CommandObjectMultiwordProcess (*this)); 417 m_command_dict["quit"] = CommandObjectSP (new CommandObjectQuit (*this)); 418 m_command_dict["register"] = CommandObjectSP (new CommandObjectRegister (*this)); 419 m_command_dict["script"] = CommandObjectSP (new CommandObjectScript (*this, script_language)); 420 m_command_dict["settings"] = CommandObjectSP (new CommandObjectMultiwordSettings (*this)); 421 m_command_dict["source"] = CommandObjectSP (new CommandObjectMultiwordSource (*this)); 422 m_command_dict["target"] = CommandObjectSP (new CommandObjectMultiwordTarget (*this)); 423 m_command_dict["thread"] = CommandObjectSP (new CommandObjectMultiwordThread (*this)); 424 m_command_dict["type"] = CommandObjectSP (new CommandObjectType (*this)); 425 m_command_dict["version"] = CommandObjectSP (new CommandObjectVersion (*this)); 426 m_command_dict["watchpoint"]= CommandObjectSP (new CommandObjectMultiwordWatchpoint (*this)); 427 428 const char *break_regexes[][2] = {{"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2"}, 429 {"^/([^/]+)/$", "breakpoint set --source-pattern-regexp '%1'"}, 430 {"^([[:digit:]]+)[[:space:]]*$", "breakpoint set --line %1"}, 431 {"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1"}, 432 {"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"}, 433 {"^(-.*)$", "breakpoint set %1"}, 434 {"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'"}, 435 {"^\\&(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1' --skip-prologue=0"}, 436 {"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"}}; 437 438 size_t num_regexes = llvm::array_lengthof(break_regexes); 439 440 std::unique_ptr<CommandObjectRegexCommand> 441 break_regex_cmd_ap(new CommandObjectRegexCommand (*this, 442 "_regexp-break", 443 "Set a breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.", 444 "_regexp-break [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 445 2, 446 CommandCompletions::eSymbolCompletion | 447 CommandCompletions::eSourceFileCompletion, 448 false)); 449 450 if (break_regex_cmd_ap.get()) 451 { 452 bool success = true; 453 for (size_t i = 0; i < num_regexes; i++) 454 { 455 success = break_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], break_regexes[i][1]); 456 if (!success) 457 break; 458 } 459 success = break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full"); 460 461 if (success) 462 { 463 CommandObjectSP break_regex_cmd_sp(break_regex_cmd_ap.release()); 464 m_command_dict[break_regex_cmd_sp->GetCommandName ()] = break_regex_cmd_sp; 465 } 466 } 467 468 std::unique_ptr<CommandObjectRegexCommand> 469 tbreak_regex_cmd_ap(new CommandObjectRegexCommand (*this, 470 "_regexp-tbreak", 471 "Set a one shot breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.", 472 "_regexp-tbreak [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 473 2, 474 CommandCompletions::eSymbolCompletion | 475 CommandCompletions::eSourceFileCompletion, 476 false)); 477 478 if (tbreak_regex_cmd_ap.get()) 479 { 480 bool success = true; 481 for (size_t i = 0; i < num_regexes; i++) 482 { 483 // If you add a resultant command string longer than 1024 characters be sure to increase the size of this buffer. 484 char buffer[1024]; 485 int num_printed = snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o"); 486 assert (num_printed < 1024); 487 // Quiet unused variable warning for release builds. 488 (void) num_printed; 489 success = tbreak_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], buffer); 490 if (!success) 491 break; 492 } 493 success = tbreak_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full"); 494 495 if (success) 496 { 497 CommandObjectSP tbreak_regex_cmd_sp(tbreak_regex_cmd_ap.release()); 498 m_command_dict[tbreak_regex_cmd_sp->GetCommandName ()] = tbreak_regex_cmd_sp; 499 } 500 } 501 502 std::unique_ptr<CommandObjectRegexCommand> 503 attach_regex_cmd_ap(new CommandObjectRegexCommand (*this, 504 "_regexp-attach", 505 "Attach to a process id if in decimal, otherwise treat the argument as a process name to attach to.", 506 "_regexp-attach [<pid>]\n_regexp-attach [<process-name>]", 507 2, 508 0, 509 false)); 510 if (attach_regex_cmd_ap.get()) 511 { 512 if (attach_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "process attach --pid %1") && 513 attach_regex_cmd_ap->AddRegexCommand("^(-.*|.* -.*)$", "process attach %1") && // Any options that are specified get passed to 'process attach' 514 attach_regex_cmd_ap->AddRegexCommand("^(.+)$", "process attach --name '%1'") && 515 attach_regex_cmd_ap->AddRegexCommand("^$", "process attach")) 516 { 517 CommandObjectSP attach_regex_cmd_sp(attach_regex_cmd_ap.release()); 518 m_command_dict[attach_regex_cmd_sp->GetCommandName ()] = attach_regex_cmd_sp; 519 } 520 } 521 522 std::unique_ptr<CommandObjectRegexCommand> 523 down_regex_cmd_ap(new CommandObjectRegexCommand (*this, 524 "_regexp-down", 525 "Go down \"n\" frames in the stack (1 frame by default).", 526 "_regexp-down [n]", 527 2, 528 0, 529 false)); 530 if (down_regex_cmd_ap.get()) 531 { 532 if (down_regex_cmd_ap->AddRegexCommand("^$", "frame select -r -1") && 533 down_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r -%1")) 534 { 535 CommandObjectSP down_regex_cmd_sp(down_regex_cmd_ap.release()); 536 m_command_dict[down_regex_cmd_sp->GetCommandName ()] = down_regex_cmd_sp; 537 } 538 } 539 540 std::unique_ptr<CommandObjectRegexCommand> 541 up_regex_cmd_ap(new CommandObjectRegexCommand (*this, 542 "_regexp-up", 543 "Go up \"n\" frames in the stack (1 frame by default).", 544 "_regexp-up [n]", 545 2, 546 0, 547 false)); 548 if (up_regex_cmd_ap.get()) 549 { 550 if (up_regex_cmd_ap->AddRegexCommand("^$", "frame select -r 1") && 551 up_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r %1")) 552 { 553 CommandObjectSP up_regex_cmd_sp(up_regex_cmd_ap.release()); 554 m_command_dict[up_regex_cmd_sp->GetCommandName ()] = up_regex_cmd_sp; 555 } 556 } 557 558 std::unique_ptr<CommandObjectRegexCommand> 559 display_regex_cmd_ap(new CommandObjectRegexCommand (*this, 560 "_regexp-display", 561 "Add an expression evaluation stop-hook.", 562 "_regexp-display expression", 563 2, 564 0, 565 false)); 566 if (display_regex_cmd_ap.get()) 567 { 568 if (display_regex_cmd_ap->AddRegexCommand("^(.+)$", "target stop-hook add -o \"expr -- %1\"")) 569 { 570 CommandObjectSP display_regex_cmd_sp(display_regex_cmd_ap.release()); 571 m_command_dict[display_regex_cmd_sp->GetCommandName ()] = display_regex_cmd_sp; 572 } 573 } 574 575 std::unique_ptr<CommandObjectRegexCommand> 576 undisplay_regex_cmd_ap(new CommandObjectRegexCommand (*this, 577 "_regexp-undisplay", 578 "Remove an expression evaluation stop-hook.", 579 "_regexp-undisplay stop-hook-number", 580 2, 581 0, 582 false)); 583 if (undisplay_regex_cmd_ap.get()) 584 { 585 if (undisplay_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "target stop-hook delete %1")) 586 { 587 CommandObjectSP undisplay_regex_cmd_sp(undisplay_regex_cmd_ap.release()); 588 m_command_dict[undisplay_regex_cmd_sp->GetCommandName ()] = undisplay_regex_cmd_sp; 589 } 590 } 591 592 std::unique_ptr<CommandObjectRegexCommand> 593 connect_gdb_remote_cmd_ap(new CommandObjectRegexCommand (*this, 594 "gdb-remote", 595 "Connect to a remote GDB server. If no hostname is provided, localhost is assumed.", 596 "gdb-remote [<hostname>:]<portnum>", 597 2, 598 0, 599 false)); 600 if (connect_gdb_remote_cmd_ap.get()) 601 { 602 if (connect_gdb_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin gdb-remote connect://%1") && 603 connect_gdb_remote_cmd_ap->AddRegexCommand("^([[:digit:]]+)$", "process connect --plugin gdb-remote connect://localhost:%1")) 604 { 605 CommandObjectSP command_sp(connect_gdb_remote_cmd_ap.release()); 606 m_command_dict[command_sp->GetCommandName ()] = command_sp; 607 } 608 } 609 610 std::unique_ptr<CommandObjectRegexCommand> 611 connect_kdp_remote_cmd_ap(new CommandObjectRegexCommand (*this, 612 "kdp-remote", 613 "Connect to a remote KDP server. udp port 41139 is the default port number.", 614 "kdp-remote <hostname>[:<portnum>]", 615 2, 616 0, 617 false)); 618 if (connect_kdp_remote_cmd_ap.get()) 619 { 620 if (connect_kdp_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin kdp-remote udp://%1") && 621 connect_kdp_remote_cmd_ap->AddRegexCommand("^(.+)$", "process connect --plugin kdp-remote udp://%1:41139")) 622 { 623 CommandObjectSP command_sp(connect_kdp_remote_cmd_ap.release()); 624 m_command_dict[command_sp->GetCommandName ()] = command_sp; 625 } 626 } 627 628 std::unique_ptr<CommandObjectRegexCommand> 629 bt_regex_cmd_ap(new CommandObjectRegexCommand (*this, 630 "_regexp-bt", 631 "Show a backtrace. An optional argument is accepted; if that argument is a number, it specifies the number of frames to display. If that argument is 'all', full backtraces of all threads are displayed.", 632 "bt [<digit>|all]", 633 2, 634 0, 635 false)); 636 if (bt_regex_cmd_ap.get()) 637 { 638 // accept but don't document "bt -c <number>" -- before bt was a regex command if you wanted to backtrace 639 // three frames you would do "bt -c 3" but the intention is to have this emulate the gdb "bt" command and 640 // so now "bt 3" is the preferred form, in line with gdb. 641 if (bt_regex_cmd_ap->AddRegexCommand("^([[:digit:]]+)$", "thread backtrace -c %1") && 642 bt_regex_cmd_ap->AddRegexCommand("^-c ([[:digit:]]+)$", "thread backtrace -c %1") && 643 bt_regex_cmd_ap->AddRegexCommand("^all$", "thread backtrace all") && 644 bt_regex_cmd_ap->AddRegexCommand("^$", "thread backtrace")) 645 { 646 CommandObjectSP command_sp(bt_regex_cmd_ap.release()); 647 m_command_dict[command_sp->GetCommandName ()] = command_sp; 648 } 649 } 650 651 std::unique_ptr<CommandObjectRegexCommand> 652 list_regex_cmd_ap(new CommandObjectRegexCommand (*this, 653 "_regexp-list", 654 "Implements the GDB 'list' command in all of its forms except FILE:FUNCTION and maps them to the appropriate 'source list' commands.", 655 "_regexp-list [<line>]\n_regexp-list [<file>:<line>]\n_regexp-list [<file>:<line>]", 656 2, 657 CommandCompletions::eSourceFileCompletion, 658 false)); 659 if (list_regex_cmd_ap.get()) 660 { 661 if (list_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "source list --line %1") && 662 list_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "source list --file '%1' --line %2") && 663 list_regex_cmd_ap->AddRegexCommand("^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "source list --address %1") && 664 list_regex_cmd_ap->AddRegexCommand("^-[[:space:]]*$", "source list --reverse") && 665 list_regex_cmd_ap->AddRegexCommand("^-([[:digit:]]+)[[:space:]]*$", "source list --reverse --count %1") && 666 list_regex_cmd_ap->AddRegexCommand("^(.+)$", "source list --name \"%1\"") && 667 list_regex_cmd_ap->AddRegexCommand("^$", "source list")) 668 { 669 CommandObjectSP list_regex_cmd_sp(list_regex_cmd_ap.release()); 670 m_command_dict[list_regex_cmd_sp->GetCommandName ()] = list_regex_cmd_sp; 671 } 672 } 673 674 std::unique_ptr<CommandObjectRegexCommand> 675 env_regex_cmd_ap(new CommandObjectRegexCommand (*this, 676 "_regexp-env", 677 "Implements a shortcut to viewing and setting environment variables.", 678 "_regexp-env\n_regexp-env FOO=BAR", 679 2, 680 0, 681 false)); 682 if (env_regex_cmd_ap.get()) 683 { 684 if (env_regex_cmd_ap->AddRegexCommand("^$", "settings show target.env-vars") && 685 env_regex_cmd_ap->AddRegexCommand("^([A-Za-z_][A-Za-z_0-9]*=.*)$", "settings set target.env-vars %1")) 686 { 687 CommandObjectSP env_regex_cmd_sp(env_regex_cmd_ap.release()); 688 m_command_dict[env_regex_cmd_sp->GetCommandName ()] = env_regex_cmd_sp; 689 } 690 } 691 692 std::unique_ptr<CommandObjectRegexCommand> 693 jump_regex_cmd_ap(new CommandObjectRegexCommand (*this, 694 "_regexp-jump", 695 "Sets the program counter to a new address.", 696 "_regexp-jump [<line>]\n" 697 "_regexp-jump [<+-lineoffset>]\n" 698 "_regexp-jump [<file>:<line>]\n" 699 "_regexp-jump [*<addr>]\n", 700 2, 701 0, 702 false)); 703 if (jump_regex_cmd_ap.get()) 704 { 705 if (jump_regex_cmd_ap->AddRegexCommand("^\\*(.*)$", "thread jump --addr %1") && 706 jump_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "thread jump --line %1") && 707 jump_regex_cmd_ap->AddRegexCommand("^([^:]+):([0-9]+)$", "thread jump --file %1 --line %2") && 708 jump_regex_cmd_ap->AddRegexCommand("^([+\\-][0-9]+)$", "thread jump --by %1")) 709 { 710 CommandObjectSP jump_regex_cmd_sp(jump_regex_cmd_ap.release()); 711 m_command_dict[jump_regex_cmd_sp->GetCommandName ()] = jump_regex_cmd_sp; 712 } 713 } 714 715 } 716 717 int 718 CommandInterpreter::GetCommandNamesMatchingPartialString (const char *cmd_str, bool include_aliases, 719 StringList &matches) 720 { 721 CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_str, matches); 722 723 if (include_aliases) 724 { 725 CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_str, matches); 726 } 727 728 return matches.GetSize(); 729 } 730 731 CommandObjectSP 732 CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches) 733 { 734 CommandObject::CommandMap::iterator pos; 735 CommandObjectSP command_sp; 736 737 std::string cmd(cmd_cstr); 738 739 if (HasCommands()) 740 { 741 pos = m_command_dict.find(cmd); 742 if (pos != m_command_dict.end()) 743 command_sp = pos->second; 744 } 745 746 if (include_aliases && HasAliases()) 747 { 748 pos = m_alias_dict.find(cmd); 749 if (pos != m_alias_dict.end()) 750 command_sp = pos->second; 751 } 752 753 if (HasUserCommands()) 754 { 755 pos = m_user_dict.find(cmd); 756 if (pos != m_user_dict.end()) 757 command_sp = pos->second; 758 } 759 760 if (!exact && !command_sp) 761 { 762 // We will only get into here if we didn't find any exact matches. 763 764 CommandObjectSP user_match_sp, alias_match_sp, real_match_sp; 765 766 StringList local_matches; 767 if (matches == nullptr) 768 matches = &local_matches; 769 770 unsigned int num_cmd_matches = 0; 771 unsigned int num_alias_matches = 0; 772 unsigned int num_user_matches = 0; 773 774 // Look through the command dictionaries one by one, and if we get only one match from any of 775 // them in toto, then return that, otherwise return an empty CommandObjectSP and the list of matches. 776 777 if (HasCommands()) 778 { 779 num_cmd_matches = CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_cstr, *matches); 780 } 781 782 if (num_cmd_matches == 1) 783 { 784 cmd.assign(matches->GetStringAtIndex(0)); 785 pos = m_command_dict.find(cmd); 786 if (pos != m_command_dict.end()) 787 real_match_sp = pos->second; 788 } 789 790 if (include_aliases && HasAliases()) 791 { 792 num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_cstr, *matches); 793 794 } 795 796 if (num_alias_matches == 1) 797 { 798 cmd.assign(matches->GetStringAtIndex (num_cmd_matches)); 799 pos = m_alias_dict.find(cmd); 800 if (pos != m_alias_dict.end()) 801 alias_match_sp = pos->second; 802 } 803 804 if (HasUserCommands()) 805 { 806 num_user_matches = CommandObject::AddNamesMatchingPartialString (m_user_dict, cmd_cstr, *matches); 807 } 808 809 if (num_user_matches == 1) 810 { 811 cmd.assign (matches->GetStringAtIndex (num_cmd_matches + num_alias_matches)); 812 813 pos = m_user_dict.find (cmd); 814 if (pos != m_user_dict.end()) 815 user_match_sp = pos->second; 816 } 817 818 // If we got exactly one match, return that, otherwise return the match list. 819 820 if (num_user_matches + num_cmd_matches + num_alias_matches == 1) 821 { 822 if (num_cmd_matches) 823 return real_match_sp; 824 else if (num_alias_matches) 825 return alias_match_sp; 826 else 827 return user_match_sp; 828 } 829 } 830 else if (matches && command_sp) 831 { 832 matches->AppendString (cmd_cstr); 833 } 834 835 836 return command_sp; 837 } 838 839 bool 840 CommandInterpreter::AddCommand (const char *name, const lldb::CommandObjectSP &cmd_sp, bool can_replace) 841 { 842 if (name && name[0]) 843 { 844 std::string name_sstr(name); 845 bool found = (m_command_dict.find (name_sstr) != m_command_dict.end()); 846 if (found && !can_replace) 847 return false; 848 if (found && m_command_dict[name_sstr]->IsRemovable() == false) 849 return false; 850 m_command_dict[name_sstr] = cmd_sp; 851 return true; 852 } 853 return false; 854 } 855 856 bool 857 CommandInterpreter::AddUserCommand (std::string name, 858 const lldb::CommandObjectSP &cmd_sp, 859 bool can_replace) 860 { 861 if (!name.empty()) 862 { 863 864 const char* name_cstr = name.c_str(); 865 866 // do not allow replacement of internal commands 867 if (CommandExists(name_cstr)) 868 { 869 if (can_replace == false) 870 return false; 871 if (m_command_dict[name]->IsRemovable() == false) 872 return false; 873 } 874 875 if (UserCommandExists(name_cstr)) 876 { 877 if (can_replace == false) 878 return false; 879 if (m_user_dict[name]->IsRemovable() == false) 880 return false; 881 } 882 883 m_user_dict[name] = cmd_sp; 884 return true; 885 } 886 return false; 887 } 888 889 CommandObjectSP 890 CommandInterpreter::GetCommandSPExact (const char *cmd_cstr, bool include_aliases) 891 { 892 Args cmd_words (cmd_cstr); // Break up the command string into words, in case it's a multi-word command. 893 CommandObjectSP ret_val; // Possibly empty return value. 894 895 if (cmd_cstr == nullptr) 896 return ret_val; 897 898 if (cmd_words.GetArgumentCount() == 1) 899 return GetCommandSP(cmd_cstr, include_aliases, true, nullptr); 900 else 901 { 902 // We have a multi-word command (seemingly), so we need to do more work. 903 // First, get the cmd_obj_sp for the first word in the command. 904 CommandObjectSP cmd_obj_sp = GetCommandSP (cmd_words.GetArgumentAtIndex (0), include_aliases, true, nullptr); 905 if (cmd_obj_sp.get() != nullptr) 906 { 907 // Loop through the rest of the words in the command (everything passed in was supposed to be part of a 908 // command name), and find the appropriate sub-command SP for each command word.... 909 size_t end = cmd_words.GetArgumentCount(); 910 for (size_t j= 1; j < end; ++j) 911 { 912 if (cmd_obj_sp->IsMultiwordObject()) 913 { 914 cmd_obj_sp = cmd_obj_sp->GetSubcommandSP (cmd_words.GetArgumentAtIndex (j)); 915 if (cmd_obj_sp.get() == nullptr) 916 // The sub-command name was invalid. Fail and return the empty 'ret_val'. 917 return ret_val; 918 } 919 else 920 // We have more words in the command name, but we don't have a multiword object. Fail and return 921 // empty 'ret_val'. 922 return ret_val; 923 } 924 // We successfully looped through all the command words and got valid command objects for them. Assign the 925 // last object retrieved to 'ret_val'. 926 ret_val = cmd_obj_sp; 927 } 928 } 929 return ret_val; 930 } 931 932 CommandObject * 933 CommandInterpreter::GetCommandObjectExact (const char *cmd_cstr, bool include_aliases) 934 { 935 return GetCommandSPExact (cmd_cstr, include_aliases).get(); 936 } 937 938 CommandObject * 939 CommandInterpreter::GetCommandObject (const char *cmd_cstr, StringList *matches) 940 { 941 CommandObject *command_obj = GetCommandSP (cmd_cstr, false, true, matches).get(); 942 943 // If we didn't find an exact match to the command string in the commands, look in 944 // the aliases. 945 946 if (command_obj) 947 return command_obj; 948 949 command_obj = GetCommandSP (cmd_cstr, true, true, matches).get(); 950 951 if (command_obj) 952 return command_obj; 953 954 // If there wasn't an exact match then look for an inexact one in just the commands 955 command_obj = GetCommandSP(cmd_cstr, false, false, nullptr).get(); 956 957 // Finally, if there wasn't an inexact match among the commands, look for an inexact 958 // match in both the commands and aliases. 959 960 if (command_obj) 961 { 962 if (matches) 963 matches->AppendString(command_obj->GetCommandName()); 964 return command_obj; 965 } 966 967 return GetCommandSP(cmd_cstr, true, false, matches).get(); 968 } 969 970 bool 971 CommandInterpreter::CommandExists (const char *cmd) 972 { 973 return m_command_dict.find(cmd) != m_command_dict.end(); 974 } 975 976 bool 977 CommandInterpreter::ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp, 978 const char *options_args, 979 OptionArgVectorSP &option_arg_vector_sp) 980 { 981 bool success = true; 982 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 983 984 if (!options_args || (strlen (options_args) < 1)) 985 return true; 986 987 std::string options_string (options_args); 988 Args args (options_args); 989 CommandReturnObject result; 990 // Check to see if the command being aliased can take any command options. 991 Options *options = cmd_obj_sp->GetOptions (); 992 if (options) 993 { 994 // See if any options were specified as part of the alias; if so, handle them appropriately. 995 options->NotifyOptionParsingStarting (); 996 args.Unshift ("dummy_arg"); 997 args.ParseAliasOptions (*options, result, option_arg_vector, options_string); 998 args.Shift (); 999 if (result.Succeeded()) 1000 options->VerifyPartialOptions (result); 1001 if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted) 1002 { 1003 result.AppendError ("Unable to create requested alias.\n"); 1004 return false; 1005 } 1006 } 1007 1008 if (!options_string.empty()) 1009 { 1010 if (cmd_obj_sp->WantsRawCommandString ()) 1011 option_arg_vector->push_back (OptionArgPair ("<argument>", 1012 OptionArgValue (-1, 1013 options_string))); 1014 else 1015 { 1016 const size_t argc = args.GetArgumentCount(); 1017 for (size_t i = 0; i < argc; ++i) 1018 if (strcmp (args.GetArgumentAtIndex (i), "") != 0) 1019 option_arg_vector->push_back 1020 (OptionArgPair ("<argument>", 1021 OptionArgValue (-1, 1022 std::string (args.GetArgumentAtIndex (i))))); 1023 } 1024 } 1025 1026 return success; 1027 } 1028 1029 bool 1030 CommandInterpreter::GetAliasFullName (const char *cmd, std::string &full_name) 1031 { 1032 bool exact_match = (m_alias_dict.find(cmd) != m_alias_dict.end()); 1033 if (exact_match) 1034 { 1035 full_name.assign(cmd); 1036 return exact_match; 1037 } 1038 else 1039 { 1040 StringList matches; 1041 size_t num_alias_matches; 1042 num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd, matches); 1043 if (num_alias_matches == 1) 1044 { 1045 // Make sure this isn't shadowing a command in the regular command space: 1046 StringList regular_matches; 1047 const bool include_aliases = false; 1048 const bool exact = false; 1049 CommandObjectSP cmd_obj_sp(GetCommandSP (cmd, include_aliases, exact, ®ular_matches)); 1050 if (cmd_obj_sp || regular_matches.GetSize() > 0) 1051 return false; 1052 else 1053 { 1054 full_name.assign (matches.GetStringAtIndex(0)); 1055 return true; 1056 } 1057 } 1058 else 1059 return false; 1060 } 1061 } 1062 1063 bool 1064 CommandInterpreter::AliasExists (const char *cmd) 1065 { 1066 return m_alias_dict.find(cmd) != m_alias_dict.end(); 1067 } 1068 1069 bool 1070 CommandInterpreter::UserCommandExists (const char *cmd) 1071 { 1072 return m_user_dict.find(cmd) != m_user_dict.end(); 1073 } 1074 1075 void 1076 CommandInterpreter::AddAlias (const char *alias_name, CommandObjectSP& command_obj_sp) 1077 { 1078 command_obj_sp->SetIsAlias (true); 1079 m_alias_dict[alias_name] = command_obj_sp; 1080 } 1081 1082 bool 1083 CommandInterpreter::RemoveAlias (const char *alias_name) 1084 { 1085 CommandObject::CommandMap::iterator pos = m_alias_dict.find(alias_name); 1086 if (pos != m_alias_dict.end()) 1087 { 1088 m_alias_dict.erase(pos); 1089 return true; 1090 } 1091 return false; 1092 } 1093 1094 bool 1095 CommandInterpreter::RemoveCommand (const char *cmd) 1096 { 1097 auto pos = m_command_dict.find(cmd); 1098 if (pos != m_command_dict.end()) 1099 { 1100 if (pos->second->IsRemovable()) 1101 { 1102 // Only regular expression objects or python commands are removable 1103 m_command_dict.erase(pos); 1104 return true; 1105 } 1106 } 1107 return false; 1108 } 1109 bool 1110 CommandInterpreter::RemoveUser (const char *alias_name) 1111 { 1112 CommandObject::CommandMap::iterator pos = m_user_dict.find(alias_name); 1113 if (pos != m_user_dict.end()) 1114 { 1115 m_user_dict.erase(pos); 1116 return true; 1117 } 1118 return false; 1119 } 1120 1121 void 1122 CommandInterpreter::GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string) 1123 { 1124 help_string.Printf ("'%s", command_name); 1125 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); 1126 1127 if (option_arg_vector_sp) 1128 { 1129 OptionArgVector *options = option_arg_vector_sp.get(); 1130 for (size_t i = 0; i < options->size(); ++i) 1131 { 1132 OptionArgPair cur_option = (*options)[i]; 1133 std::string opt = cur_option.first; 1134 OptionArgValue value_pair = cur_option.second; 1135 std::string value = value_pair.second; 1136 if (opt.compare("<argument>") == 0) 1137 { 1138 help_string.Printf (" %s", value.c_str()); 1139 } 1140 else 1141 { 1142 help_string.Printf (" %s", opt.c_str()); 1143 if ((value.compare ("<no-argument>") != 0) 1144 && (value.compare ("<need-argument") != 0)) 1145 { 1146 help_string.Printf (" %s", value.c_str()); 1147 } 1148 } 1149 } 1150 } 1151 1152 help_string.Printf ("'"); 1153 } 1154 1155 size_t 1156 CommandInterpreter::FindLongestCommandWord (CommandObject::CommandMap &dict) 1157 { 1158 CommandObject::CommandMap::const_iterator pos; 1159 CommandObject::CommandMap::const_iterator end = dict.end(); 1160 size_t max_len = 0; 1161 1162 for (pos = dict.begin(); pos != end; ++pos) 1163 { 1164 size_t len = pos->first.size(); 1165 if (max_len < len) 1166 max_len = len; 1167 } 1168 return max_len; 1169 } 1170 1171 void 1172 CommandInterpreter::GetHelp (CommandReturnObject &result, 1173 uint32_t cmd_types) 1174 { 1175 const char * help_prologue = GetDebugger().GetIOHandlerHelpPrologue(); 1176 if (help_prologue != NULL) 1177 { 1178 OutputFormattedHelpText(result.GetOutputStream(), NULL, help_prologue); 1179 } 1180 1181 CommandObject::CommandMap::const_iterator pos; 1182 size_t max_len = FindLongestCommandWord (m_command_dict); 1183 1184 if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin ) 1185 { 1186 result.AppendMessage("Debugger commands:"); 1187 result.AppendMessage(""); 1188 1189 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) 1190 { 1191 if (!(cmd_types & eCommandTypesHidden) && (pos->first.compare(0, 1, "_") == 0)) 1192 continue; 1193 1194 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), 1195 max_len); 1196 } 1197 result.AppendMessage(""); 1198 1199 } 1200 1201 if (!m_alias_dict.empty() && ( (cmd_types & eCommandTypesAliases) == eCommandTypesAliases )) 1202 { 1203 result.AppendMessageWithFormat("Current command abbreviations " 1204 "(type '%shelp command alias' for more info):\n", 1205 GetCommandPrefix()); 1206 result.AppendMessage(""); 1207 max_len = FindLongestCommandWord (m_alias_dict); 1208 1209 for (pos = m_alias_dict.begin(); pos != m_alias_dict.end(); ++pos) 1210 { 1211 StreamString sstr; 1212 StreamString translation_and_help; 1213 std::string entry_name = pos->first; 1214 std::string second_entry = pos->second.get()->GetCommandName(); 1215 GetAliasHelp (pos->first.c_str(), pos->second->GetCommandName(), sstr); 1216 1217 translation_and_help.Printf ("(%s) %s", sstr.GetData(), pos->second->GetHelp()); 1218 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", 1219 translation_and_help.GetData(), max_len); 1220 } 1221 result.AppendMessage(""); 1222 } 1223 1224 if (!m_user_dict.empty() && ( (cmd_types & eCommandTypesUserDef) == eCommandTypesUserDef )) 1225 { 1226 result.AppendMessage ("Current user-defined commands:"); 1227 result.AppendMessage(""); 1228 max_len = FindLongestCommandWord (m_user_dict); 1229 for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos) 1230 { 1231 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), 1232 max_len); 1233 } 1234 result.AppendMessage(""); 1235 } 1236 1237 result.AppendMessageWithFormat("For more information on any command, type '%shelp <command-name>'.\n", 1238 GetCommandPrefix()); 1239 } 1240 1241 CommandObject * 1242 CommandInterpreter::GetCommandObjectForCommand (std::string &command_string) 1243 { 1244 // This function finds the final, lowest-level, alias-resolved command object whose 'Execute' function will 1245 // eventually be invoked by the given command line. 1246 1247 CommandObject *cmd_obj = nullptr; 1248 std::string white_space (" \t\v"); 1249 size_t start = command_string.find_first_not_of (white_space); 1250 size_t end = 0; 1251 bool done = false; 1252 while (!done) 1253 { 1254 if (start != std::string::npos) 1255 { 1256 // Get the next word from command_string. 1257 end = command_string.find_first_of (white_space, start); 1258 if (end == std::string::npos) 1259 end = command_string.size(); 1260 std::string cmd_word = command_string.substr (start, end - start); 1261 1262 if (cmd_obj == nullptr) 1263 // Since cmd_obj is NULL we are on our first time through this loop. Check to see if cmd_word is a valid 1264 // command or alias. 1265 cmd_obj = GetCommandObject (cmd_word.c_str()); 1266 else if (cmd_obj->IsMultiwordObject ()) 1267 { 1268 // Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object. 1269 CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (cmd_word.c_str()); 1270 if (sub_cmd_obj) 1271 cmd_obj = sub_cmd_obj; 1272 else // cmd_word was not a valid sub-command word, so we are donee 1273 done = true; 1274 } 1275 else 1276 // We have a cmd_obj and it is not a multi-word object, so we are done. 1277 done = true; 1278 1279 // If we didn't find a valid command object, or our command object is not a multi-word object, or 1280 // we are at the end of the command_string, then we are done. Otherwise, find the start of the 1281 // next word. 1282 1283 if (!cmd_obj || !cmd_obj->IsMultiwordObject() || end >= command_string.size()) 1284 done = true; 1285 else 1286 start = command_string.find_first_not_of (white_space, end); 1287 } 1288 else 1289 // Unable to find any more words. 1290 done = true; 1291 } 1292 1293 if (end == command_string.size()) 1294 command_string.clear(); 1295 else 1296 command_string = command_string.substr(end); 1297 1298 return cmd_obj; 1299 } 1300 1301 static const char *k_white_space = " \t\v"; 1302 static const char *k_valid_command_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"; 1303 static void 1304 StripLeadingSpaces (std::string &s) 1305 { 1306 if (!s.empty()) 1307 { 1308 size_t pos = s.find_first_not_of (k_white_space); 1309 if (pos == std::string::npos) 1310 s.clear(); 1311 else if (pos == 0) 1312 return; 1313 s.erase (0, pos); 1314 } 1315 } 1316 1317 static size_t 1318 FindArgumentTerminator (const std::string &s) 1319 { 1320 const size_t s_len = s.size(); 1321 size_t offset = 0; 1322 while (offset < s_len) 1323 { 1324 size_t pos = s.find ("--", offset); 1325 if (pos == std::string::npos) 1326 break; 1327 if (pos > 0) 1328 { 1329 if (isspace(s[pos-1])) 1330 { 1331 // Check if the string ends "\s--" (where \s is a space character) 1332 // or if we have "\s--\s". 1333 if ((pos + 2 >= s_len) || isspace(s[pos+2])) 1334 { 1335 return pos; 1336 } 1337 } 1338 } 1339 offset = pos + 2; 1340 } 1341 return std::string::npos; 1342 } 1343 1344 static bool 1345 ExtractCommand (std::string &command_string, std::string &command, std::string &suffix, char "e_char) 1346 { 1347 command.clear(); 1348 suffix.clear(); 1349 StripLeadingSpaces (command_string); 1350 1351 bool result = false; 1352 quote_char = '\0'; 1353 1354 if (!command_string.empty()) 1355 { 1356 const char first_char = command_string[0]; 1357 if (first_char == '\'' || first_char == '"') 1358 { 1359 quote_char = first_char; 1360 const size_t end_quote_pos = command_string.find (quote_char, 1); 1361 if (end_quote_pos == std::string::npos) 1362 { 1363 command.swap (command_string); 1364 command_string.erase (); 1365 } 1366 else 1367 { 1368 command.assign (command_string, 1, end_quote_pos - 1); 1369 if (end_quote_pos + 1 < command_string.size()) 1370 command_string.erase (0, command_string.find_first_not_of (k_white_space, end_quote_pos + 1)); 1371 else 1372 command_string.erase (); 1373 } 1374 } 1375 else 1376 { 1377 const size_t first_space_pos = command_string.find_first_of (k_white_space); 1378 if (first_space_pos == std::string::npos) 1379 { 1380 command.swap (command_string); 1381 command_string.erase(); 1382 } 1383 else 1384 { 1385 command.assign (command_string, 0, first_space_pos); 1386 command_string.erase(0, command_string.find_first_not_of (k_white_space, first_space_pos)); 1387 } 1388 } 1389 result = true; 1390 } 1391 1392 1393 if (!command.empty()) 1394 { 1395 // actual commands can't start with '-' or '_' 1396 if (command[0] != '-' && command[0] != '_') 1397 { 1398 size_t pos = command.find_first_not_of(k_valid_command_chars); 1399 if (pos > 0 && pos != std::string::npos) 1400 { 1401 suffix.assign (command.begin() + pos, command.end()); 1402 command.erase (pos); 1403 } 1404 } 1405 } 1406 1407 return result; 1408 } 1409 1410 CommandObject * 1411 CommandInterpreter::BuildAliasResult (const char *alias_name, 1412 std::string &raw_input_string, 1413 std::string &alias_result, 1414 CommandReturnObject &result) 1415 { 1416 CommandObject *alias_cmd_obj = nullptr; 1417 Args cmd_args (raw_input_string); 1418 alias_cmd_obj = GetCommandObject (alias_name); 1419 StreamString result_str; 1420 1421 if (alias_cmd_obj) 1422 { 1423 std::string alias_name_str = alias_name; 1424 if ((cmd_args.GetArgumentCount() == 0) 1425 || (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0)) 1426 cmd_args.Unshift (alias_name); 1427 1428 result_str.Printf ("%s", alias_cmd_obj->GetCommandName ()); 1429 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); 1430 1431 if (option_arg_vector_sp.get()) 1432 { 1433 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 1434 1435 for (size_t i = 0; i < option_arg_vector->size(); ++i) 1436 { 1437 OptionArgPair option_pair = (*option_arg_vector)[i]; 1438 OptionArgValue value_pair = option_pair.second; 1439 int value_type = value_pair.first; 1440 std::string option = option_pair.first; 1441 std::string value = value_pair.second; 1442 if (option.compare ("<argument>") == 0) 1443 result_str.Printf (" %s", value.c_str()); 1444 else 1445 { 1446 result_str.Printf (" %s", option.c_str()); 1447 if (value_type != OptionParser::eOptionalArgument) 1448 result_str.Printf (" "); 1449 if (value.compare ("<OptionParser::eNoArgument>") != 0) 1450 { 1451 int index = GetOptionArgumentPosition (value.c_str()); 1452 if (index == 0) 1453 result_str.Printf ("%s", value.c_str()); 1454 else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount()) 1455 { 1456 1457 result.AppendErrorWithFormat 1458 ("Not enough arguments provided; you need at least %d arguments to use this alias.\n", 1459 index); 1460 result.SetStatus (eReturnStatusFailed); 1461 return alias_cmd_obj; 1462 } 1463 else 1464 { 1465 size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index)); 1466 if (strpos != std::string::npos) 1467 raw_input_string = raw_input_string.erase (strpos, 1468 strlen (cmd_args.GetArgumentAtIndex (index))); 1469 result_str.Printf ("%s", cmd_args.GetArgumentAtIndex (index)); 1470 } 1471 } 1472 } 1473 } 1474 } 1475 1476 alias_result = result_str.GetData(); 1477 } 1478 return alias_cmd_obj; 1479 } 1480 1481 Error 1482 CommandInterpreter::PreprocessCommand (std::string &command) 1483 { 1484 // The command preprocessor needs to do things to the command 1485 // line before any parsing of arguments or anything else is done. 1486 // The only current stuff that gets proprocessed is anyting enclosed 1487 // in backtick ('`') characters is evaluated as an expression and 1488 // the result of the expression must be a scalar that can be substituted 1489 // into the command. An example would be: 1490 // (lldb) memory read `$rsp + 20` 1491 Error error; // Error for any expressions that might not evaluate 1492 size_t start_backtick; 1493 size_t pos = 0; 1494 while ((start_backtick = command.find ('`', pos)) != std::string::npos) 1495 { 1496 if (start_backtick > 0 && command[start_backtick-1] == '\\') 1497 { 1498 // The backtick was preceeded by a '\' character, remove the slash 1499 // and don't treat the backtick as the start of an expression 1500 command.erase(start_backtick-1, 1); 1501 // No need to add one to start_backtick since we just deleted a char 1502 pos = start_backtick; 1503 } 1504 else 1505 { 1506 const size_t expr_content_start = start_backtick + 1; 1507 const size_t end_backtick = command.find ('`', expr_content_start); 1508 if (end_backtick == std::string::npos) 1509 return error; 1510 else if (end_backtick == expr_content_start) 1511 { 1512 // Empty expression (two backticks in a row) 1513 command.erase (start_backtick, 2); 1514 } 1515 else 1516 { 1517 std::string expr_str (command, expr_content_start, end_backtick - expr_content_start); 1518 1519 ExecutionContext exe_ctx(GetExecutionContext()); 1520 Target *target = exe_ctx.GetTargetPtr(); 1521 // Get a dummy target to allow for calculator mode while processing backticks. 1522 // This also helps break the infinite loop caused when target is null. 1523 if (!target) 1524 target = m_debugger.GetDummyTarget(); 1525 if (target) 1526 { 1527 ValueObjectSP expr_result_valobj_sp; 1528 1529 EvaluateExpressionOptions options; 1530 options.SetCoerceToId(false); 1531 options.SetUnwindOnError(true); 1532 options.SetIgnoreBreakpoints(true); 1533 options.SetKeepInMemory(false); 1534 options.SetTryAllThreads(true); 1535 options.SetTimeoutUsec(0); 1536 1537 ExpressionResults expr_result = target->EvaluateExpression (expr_str.c_str(), 1538 exe_ctx.GetFramePtr(), 1539 expr_result_valobj_sp, 1540 options); 1541 1542 if (expr_result == eExpressionCompleted) 1543 { 1544 Scalar scalar; 1545 if (expr_result_valobj_sp) 1546 expr_result_valobj_sp = expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable(expr_result_valobj_sp->GetDynamicValueType(), true); 1547 if (expr_result_valobj_sp->ResolveValue (scalar)) 1548 { 1549 command.erase (start_backtick, end_backtick - start_backtick + 1); 1550 StreamString value_strm; 1551 const bool show_type = false; 1552 scalar.GetValue (&value_strm, show_type); 1553 size_t value_string_size = value_strm.GetSize(); 1554 if (value_string_size) 1555 { 1556 command.insert (start_backtick, value_strm.GetData(), value_string_size); 1557 pos = start_backtick + value_string_size; 1558 continue; 1559 } 1560 else 1561 { 1562 error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str()); 1563 } 1564 } 1565 else 1566 { 1567 error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str()); 1568 } 1569 } 1570 else 1571 { 1572 if (expr_result_valobj_sp) 1573 error = expr_result_valobj_sp->GetError(); 1574 if (error.Success()) 1575 { 1576 1577 switch (expr_result) 1578 { 1579 case eExpressionSetupError: 1580 error.SetErrorStringWithFormat("expression setup error for the expression '%s'", expr_str.c_str()); 1581 break; 1582 case eExpressionParseError: 1583 error.SetErrorStringWithFormat ("expression parse error for the expression '%s'", expr_str.c_str()); 1584 break; 1585 case eExpressionResultUnavailable: 1586 error.SetErrorStringWithFormat ("expression error fetching result for the expression '%s'", expr_str.c_str()); 1587 case eExpressionCompleted: 1588 break; 1589 case eExpressionDiscarded: 1590 error.SetErrorStringWithFormat("expression discarded for the expression '%s'", expr_str.c_str()); 1591 break; 1592 case eExpressionInterrupted: 1593 error.SetErrorStringWithFormat("expression interrupted for the expression '%s'", expr_str.c_str()); 1594 break; 1595 case eExpressionHitBreakpoint: 1596 error.SetErrorStringWithFormat("expression hit breakpoint for the expression '%s'", expr_str.c_str()); 1597 break; 1598 case eExpressionTimedOut: 1599 error.SetErrorStringWithFormat("expression timed out for the expression '%s'", expr_str.c_str()); 1600 break; 1601 case eExpressionStoppedForDebug: 1602 error.SetErrorStringWithFormat("expression stop at entry point for debugging for the expression '%s'", expr_str.c_str()); 1603 break; 1604 } 1605 } 1606 } 1607 } 1608 } 1609 if (error.Fail()) 1610 break; 1611 } 1612 } 1613 return error; 1614 } 1615 1616 1617 bool 1618 CommandInterpreter::HandleCommand (const char *command_line, 1619 LazyBool lazy_add_to_history, 1620 CommandReturnObject &result, 1621 ExecutionContext *override_context, 1622 bool repeat_on_empty_command, 1623 bool no_context_switching) 1624 1625 { 1626 1627 bool done = false; 1628 CommandObject *cmd_obj = nullptr; 1629 bool wants_raw_input = false; 1630 std::string command_string (command_line); 1631 std::string original_command_string (command_line); 1632 1633 Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS)); 1634 Host::SetCrashDescriptionWithFormat ("HandleCommand(command = \"%s\")", command_line); 1635 1636 // Make a scoped cleanup object that will clear the crash description string 1637 // on exit of this function. 1638 lldb_utility::CleanUp <const char *> crash_description_cleanup(nullptr, Host::SetCrashDescription); 1639 1640 if (log) 1641 log->Printf ("Processing command: %s", command_line); 1642 1643 Timer scoped_timer (__PRETTY_FUNCTION__, "Handling command: %s.", command_line); 1644 1645 if (!no_context_switching) 1646 UpdateExecutionContext (override_context); 1647 1648 bool add_to_history; 1649 if (lazy_add_to_history == eLazyBoolCalculate) 1650 add_to_history = (m_command_source_depth == 0); 1651 else 1652 add_to_history = (lazy_add_to_history == eLazyBoolYes); 1653 1654 bool empty_command = false; 1655 bool comment_command = false; 1656 if (command_string.empty()) 1657 empty_command = true; 1658 else 1659 { 1660 const char *k_space_characters = "\t\n\v\f\r "; 1661 1662 size_t non_space = command_string.find_first_not_of (k_space_characters); 1663 // Check for empty line or comment line (lines whose first 1664 // non-space character is the comment character for this interpreter) 1665 if (non_space == std::string::npos) 1666 empty_command = true; 1667 else if (command_string[non_space] == m_comment_char) 1668 comment_command = true; 1669 else if (command_string[non_space] == CommandHistory::g_repeat_char) 1670 { 1671 const char *history_string = m_command_history.FindString(command_string.c_str() + non_space); 1672 if (history_string == nullptr) 1673 { 1674 result.AppendErrorWithFormat ("Could not find entry: %s in history", command_string.c_str()); 1675 result.SetStatus(eReturnStatusFailed); 1676 return false; 1677 } 1678 add_to_history = false; 1679 command_string = history_string; 1680 original_command_string = history_string; 1681 } 1682 } 1683 1684 if (empty_command) 1685 { 1686 if (repeat_on_empty_command) 1687 { 1688 if (m_command_history.IsEmpty()) 1689 { 1690 result.AppendError ("empty command"); 1691 result.SetStatus(eReturnStatusFailed); 1692 return false; 1693 } 1694 else 1695 { 1696 command_line = m_repeat_command.c_str(); 1697 command_string = command_line; 1698 original_command_string = command_line; 1699 if (m_repeat_command.empty()) 1700 { 1701 result.AppendErrorWithFormat("No auto repeat.\n"); 1702 result.SetStatus (eReturnStatusFailed); 1703 return false; 1704 } 1705 } 1706 add_to_history = false; 1707 } 1708 else 1709 { 1710 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1711 return true; 1712 } 1713 } 1714 else if (comment_command) 1715 { 1716 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1717 return true; 1718 } 1719 1720 1721 Error error (PreprocessCommand (command_string)); 1722 1723 if (error.Fail()) 1724 { 1725 result.AppendError (error.AsCString()); 1726 result.SetStatus(eReturnStatusFailed); 1727 return false; 1728 } 1729 // Phase 1. 1730 1731 // Before we do ANY kind of argument processing, etc. we need to figure out what the real/final command object 1732 // is for the specified command, and whether or not it wants raw input. This gets complicated by the fact that 1733 // the user could have specified an alias, and in translating the alias there may also be command options and/or 1734 // even data (including raw text strings) that need to be found and inserted into the command line as part of 1735 // the translation. So this first step is plain look-up & replacement, resulting in three things: 1). the command 1736 // object whose Execute method will actually be called; 2). a revised command string, with all substitutions & 1737 // replacements taken care of; 3). whether or not the Execute function wants raw input or not. 1738 1739 StreamString revised_command_line; 1740 size_t actual_cmd_name_len = 0; 1741 std::string next_word; 1742 StringList matches; 1743 while (!done) 1744 { 1745 char quote_char = '\0'; 1746 std::string suffix; 1747 ExtractCommand (command_string, next_word, suffix, quote_char); 1748 if (cmd_obj == nullptr) 1749 { 1750 std::string full_name; 1751 if (GetAliasFullName(next_word.c_str(), full_name)) 1752 { 1753 std::string alias_result; 1754 cmd_obj = BuildAliasResult (full_name.c_str(), command_string, alias_result, result); 1755 revised_command_line.Printf ("%s", alias_result.c_str()); 1756 if (cmd_obj) 1757 { 1758 wants_raw_input = cmd_obj->WantsRawCommandString (); 1759 actual_cmd_name_len = strlen (cmd_obj->GetCommandName()); 1760 } 1761 } 1762 else 1763 { 1764 cmd_obj = GetCommandObject (next_word.c_str(), &matches); 1765 if (cmd_obj) 1766 { 1767 actual_cmd_name_len += next_word.length(); 1768 revised_command_line.Printf ("%s", next_word.c_str()); 1769 wants_raw_input = cmd_obj->WantsRawCommandString (); 1770 } 1771 else 1772 { 1773 revised_command_line.Printf ("%s", next_word.c_str()); 1774 } 1775 } 1776 } 1777 else 1778 { 1779 if (cmd_obj->IsMultiwordObject ()) 1780 { 1781 CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (next_word.c_str()); 1782 if (sub_cmd_obj) 1783 { 1784 actual_cmd_name_len += next_word.length() + 1; 1785 revised_command_line.Printf (" %s", next_word.c_str()); 1786 cmd_obj = sub_cmd_obj; 1787 wants_raw_input = cmd_obj->WantsRawCommandString (); 1788 } 1789 else 1790 { 1791 if (quote_char) 1792 revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char); 1793 else 1794 revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str()); 1795 done = true; 1796 } 1797 } 1798 else 1799 { 1800 if (quote_char) 1801 revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char); 1802 else 1803 revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str()); 1804 done = true; 1805 } 1806 } 1807 1808 if (cmd_obj == nullptr) 1809 { 1810 const size_t num_matches = matches.GetSize(); 1811 if (matches.GetSize() > 1) { 1812 StreamString error_msg; 1813 error_msg.Printf ("Ambiguous command '%s'. Possible matches:\n", next_word.c_str()); 1814 1815 for (uint32_t i = 0; i < num_matches; ++i) { 1816 error_msg.Printf ("\t%s\n", matches.GetStringAtIndex(i)); 1817 } 1818 result.AppendRawError (error_msg.GetString().c_str()); 1819 } else { 1820 // We didn't have only one match, otherwise we wouldn't get here. 1821 assert(num_matches == 0); 1822 result.AppendErrorWithFormat ("'%s' is not a valid command.\n", next_word.c_str()); 1823 } 1824 result.SetStatus (eReturnStatusFailed); 1825 return false; 1826 } 1827 1828 if (cmd_obj->IsMultiwordObject ()) 1829 { 1830 if (!suffix.empty()) 1831 { 1832 1833 result.AppendErrorWithFormat ("command '%s' did not recognize '%s%s%s' as valid (subcommand might be invalid).\n", 1834 cmd_obj->GetCommandName(), 1835 next_word.empty() ? "" : next_word.c_str(), 1836 next_word.empty() ? " -- " : " ", 1837 suffix.c_str()); 1838 result.SetStatus (eReturnStatusFailed); 1839 return false; 1840 } 1841 } 1842 else 1843 { 1844 // If we found a normal command, we are done 1845 done = true; 1846 if (!suffix.empty()) 1847 { 1848 switch (suffix[0]) 1849 { 1850 case '/': 1851 // GDB format suffixes 1852 { 1853 Options *command_options = cmd_obj->GetOptions(); 1854 if (command_options && command_options->SupportsLongOption("gdb-format")) 1855 { 1856 std::string gdb_format_option ("--gdb-format="); 1857 gdb_format_option += (suffix.c_str() + 1); 1858 1859 bool inserted = false; 1860 std::string &cmd = revised_command_line.GetString(); 1861 size_t arg_terminator_idx = FindArgumentTerminator (cmd); 1862 if (arg_terminator_idx != std::string::npos) 1863 { 1864 // Insert the gdb format option before the "--" that terminates options 1865 gdb_format_option.append(1,' '); 1866 cmd.insert(arg_terminator_idx, gdb_format_option); 1867 inserted = true; 1868 } 1869 1870 if (!inserted) 1871 revised_command_line.Printf (" %s", gdb_format_option.c_str()); 1872 1873 if (wants_raw_input && FindArgumentTerminator(cmd) == std::string::npos) 1874 revised_command_line.PutCString (" --"); 1875 } 1876 else 1877 { 1878 result.AppendErrorWithFormat ("the '%s' command doesn't support the --gdb-format option\n", 1879 cmd_obj->GetCommandName()); 1880 result.SetStatus (eReturnStatusFailed); 1881 return false; 1882 } 1883 } 1884 break; 1885 1886 default: 1887 result.AppendErrorWithFormat ("unknown command shorthand suffix: '%s'\n", 1888 suffix.c_str()); 1889 result.SetStatus (eReturnStatusFailed); 1890 return false; 1891 1892 } 1893 } 1894 } 1895 if (command_string.length() == 0) 1896 done = true; 1897 1898 } 1899 1900 if (!command_string.empty()) 1901 revised_command_line.Printf (" %s", command_string.c_str()); 1902 1903 // End of Phase 1. 1904 // At this point cmd_obj should contain the CommandObject whose Execute method will be called, if the command 1905 // specified was valid; revised_command_line contains the complete command line (including command name(s)), 1906 // fully translated with all substitutions & translations taken care of (still in raw text format); and 1907 // wants_raw_input specifies whether the Execute method expects raw input or not. 1908 1909 1910 if (log) 1911 { 1912 log->Printf ("HandleCommand, cmd_obj : '%s'", cmd_obj ? cmd_obj->GetCommandName() : "<not found>"); 1913 log->Printf ("HandleCommand, revised_command_line: '%s'", revised_command_line.GetData()); 1914 log->Printf ("HandleCommand, wants_raw_input:'%s'", wants_raw_input ? "True" : "False"); 1915 } 1916 1917 // Phase 2. 1918 // Take care of things like setting up the history command & calling the appropriate Execute method on the 1919 // CommandObject, with the appropriate arguments. 1920 1921 if (cmd_obj != nullptr) 1922 { 1923 if (add_to_history) 1924 { 1925 Args command_args (revised_command_line.GetData()); 1926 const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0); 1927 if (repeat_command != nullptr) 1928 m_repeat_command.assign(repeat_command); 1929 else 1930 m_repeat_command.assign(original_command_string.c_str()); 1931 1932 m_command_history.AppendString (original_command_string); 1933 } 1934 1935 command_string = revised_command_line.GetData(); 1936 std::string command_name (cmd_obj->GetCommandName()); 1937 std::string remainder; 1938 if (actual_cmd_name_len < command_string.length()) 1939 remainder = command_string.substr (actual_cmd_name_len); // Note: 'actual_cmd_name_len' may be considerably shorter 1940 // than cmd_obj->GetCommandName(), because name completion 1941 // allows users to enter short versions of the names, 1942 // e.g. 'br s' for 'breakpoint set'. 1943 1944 // Remove any initial spaces 1945 std::string white_space (" \t\v"); 1946 size_t pos = remainder.find_first_not_of (white_space); 1947 if (pos != 0 && pos != std::string::npos) 1948 remainder.erase(0, pos); 1949 1950 if (log) 1951 log->Printf ("HandleCommand, command line after removing command name(s): '%s'", remainder.c_str()); 1952 1953 cmd_obj->Execute (remainder.c_str(), result); 1954 } 1955 else 1956 { 1957 // We didn't find the first command object, so complete the first argument. 1958 Args command_args (revised_command_line.GetData()); 1959 StringList matches; 1960 int num_matches; 1961 int cursor_index = 0; 1962 int cursor_char_position = strlen (command_args.GetArgumentAtIndex(0)); 1963 bool word_complete; 1964 num_matches = HandleCompletionMatches (command_args, 1965 cursor_index, 1966 cursor_char_position, 1967 0, 1968 -1, 1969 word_complete, 1970 matches); 1971 1972 if (num_matches > 0) 1973 { 1974 std::string error_msg; 1975 error_msg.assign ("ambiguous command '"); 1976 error_msg.append(command_args.GetArgumentAtIndex(0)); 1977 error_msg.append ("'."); 1978 1979 error_msg.append (" Possible completions:"); 1980 for (int i = 0; i < num_matches; i++) 1981 { 1982 error_msg.append ("\n\t"); 1983 error_msg.append (matches.GetStringAtIndex (i)); 1984 } 1985 error_msg.append ("\n"); 1986 result.AppendRawError (error_msg.c_str()); 1987 } 1988 else 1989 result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0)); 1990 1991 result.SetStatus (eReturnStatusFailed); 1992 } 1993 1994 if (log) 1995 log->Printf ("HandleCommand, command %s", (result.Succeeded() ? "succeeded" : "did not succeed")); 1996 1997 return result.Succeeded(); 1998 } 1999 2000 int 2001 CommandInterpreter::HandleCompletionMatches (Args &parsed_line, 2002 int &cursor_index, 2003 int &cursor_char_position, 2004 int match_start_point, 2005 int max_return_elements, 2006 bool &word_complete, 2007 StringList &matches) 2008 { 2009 int num_command_matches = 0; 2010 bool look_for_subcommand = false; 2011 2012 // For any of the command completions a unique match will be a complete word. 2013 word_complete = true; 2014 2015 if (cursor_index == -1) 2016 { 2017 // We got nothing on the command line, so return the list of commands 2018 bool include_aliases = true; 2019 num_command_matches = GetCommandNamesMatchingPartialString ("", include_aliases, matches); 2020 } 2021 else if (cursor_index == 0) 2022 { 2023 // The cursor is in the first argument, so just do a lookup in the dictionary. 2024 CommandObject *cmd_obj = GetCommandObject (parsed_line.GetArgumentAtIndex(0), &matches); 2025 num_command_matches = matches.GetSize(); 2026 2027 if (num_command_matches == 1 2028 && cmd_obj && cmd_obj->IsMultiwordObject() 2029 && matches.GetStringAtIndex(0) != nullptr 2030 && strcmp (parsed_line.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0) 2031 { 2032 if (parsed_line.GetArgumentCount() == 1) 2033 { 2034 word_complete = true; 2035 } 2036 else 2037 { 2038 look_for_subcommand = true; 2039 num_command_matches = 0; 2040 matches.DeleteStringAtIndex(0); 2041 parsed_line.AppendArgument (""); 2042 cursor_index++; 2043 cursor_char_position = 0; 2044 } 2045 } 2046 } 2047 2048 if (cursor_index > 0 || look_for_subcommand) 2049 { 2050 // We are completing further on into a commands arguments, so find the command and tell it 2051 // to complete the command. 2052 // First see if there is a matching initial command: 2053 CommandObject *command_object = GetCommandObject (parsed_line.GetArgumentAtIndex(0)); 2054 if (command_object == nullptr) 2055 { 2056 return 0; 2057 } 2058 else 2059 { 2060 parsed_line.Shift(); 2061 cursor_index--; 2062 num_command_matches = command_object->HandleCompletion (parsed_line, 2063 cursor_index, 2064 cursor_char_position, 2065 match_start_point, 2066 max_return_elements, 2067 word_complete, 2068 matches); 2069 } 2070 } 2071 2072 return num_command_matches; 2073 2074 } 2075 2076 int 2077 CommandInterpreter::HandleCompletion (const char *current_line, 2078 const char *cursor, 2079 const char *last_char, 2080 int match_start_point, 2081 int max_return_elements, 2082 StringList &matches) 2083 { 2084 // We parse the argument up to the cursor, so the last argument in parsed_line is 2085 // the one containing the cursor, and the cursor is after the last character. 2086 2087 Args parsed_line(llvm::StringRef(current_line, last_char - current_line)); 2088 Args partial_parsed_line(llvm::StringRef(current_line, cursor - current_line)); 2089 2090 // Don't complete comments, and if the line we are completing is just the history repeat character, 2091 // substitute the appropriate history line. 2092 const char *first_arg = parsed_line.GetArgumentAtIndex(0); 2093 if (first_arg) 2094 { 2095 if (first_arg[0] == m_comment_char) 2096 return 0; 2097 else if (first_arg[0] == CommandHistory::g_repeat_char) 2098 { 2099 const char *history_string = m_command_history.FindString (first_arg); 2100 if (history_string != nullptr) 2101 { 2102 matches.Clear(); 2103 matches.InsertStringAtIndex(0, history_string); 2104 return -2; 2105 } 2106 else 2107 return 0; 2108 2109 } 2110 } 2111 2112 2113 int num_args = partial_parsed_line.GetArgumentCount(); 2114 int cursor_index = partial_parsed_line.GetArgumentCount() - 1; 2115 int cursor_char_position; 2116 2117 if (cursor_index == -1) 2118 cursor_char_position = 0; 2119 else 2120 cursor_char_position = strlen (partial_parsed_line.GetArgumentAtIndex(cursor_index)); 2121 2122 if (cursor > current_line && cursor[-1] == ' ') 2123 { 2124 // We are just after a space. If we are in an argument, then we will continue 2125 // parsing, but if we are between arguments, then we have to complete whatever the next 2126 // element would be. 2127 // We can distinguish the two cases because if we are in an argument (e.g. because the space is 2128 // protected by a quote) then the space will also be in the parsed argument... 2129 2130 const char *current_elem = partial_parsed_line.GetArgumentAtIndex(cursor_index); 2131 if (cursor_char_position == 0 || current_elem[cursor_char_position - 1] != ' ') 2132 { 2133 parsed_line.InsertArgumentAtIndex(cursor_index + 1, "", '\0'); 2134 cursor_index++; 2135 cursor_char_position = 0; 2136 } 2137 } 2138 2139 int num_command_matches; 2140 2141 matches.Clear(); 2142 2143 // Only max_return_elements == -1 is supported at present: 2144 assert (max_return_elements == -1); 2145 bool word_complete; 2146 num_command_matches = HandleCompletionMatches (parsed_line, 2147 cursor_index, 2148 cursor_char_position, 2149 match_start_point, 2150 max_return_elements, 2151 word_complete, 2152 matches); 2153 2154 if (num_command_matches <= 0) 2155 return num_command_matches; 2156 2157 if (num_args == 0) 2158 { 2159 // If we got an empty string, insert nothing. 2160 matches.InsertStringAtIndex(0, ""); 2161 } 2162 else 2163 { 2164 // Now figure out if there is a common substring, and if so put that in element 0, otherwise 2165 // put an empty string in element 0. 2166 std::string command_partial_str; 2167 if (cursor_index >= 0) 2168 command_partial_str.assign(parsed_line.GetArgumentAtIndex(cursor_index), 2169 parsed_line.GetArgumentAtIndex(cursor_index) + cursor_char_position); 2170 2171 std::string common_prefix; 2172 matches.LongestCommonPrefix (common_prefix); 2173 const size_t partial_name_len = command_partial_str.size(); 2174 2175 // If we matched a unique single command, add a space... 2176 // Only do this if the completer told us this was a complete word, however... 2177 if (num_command_matches == 1 && word_complete) 2178 { 2179 char quote_char = parsed_line.GetArgumentQuoteCharAtIndex(cursor_index); 2180 if (quote_char != '\0') 2181 common_prefix.push_back(quote_char); 2182 2183 common_prefix.push_back(' '); 2184 } 2185 common_prefix.erase (0, partial_name_len); 2186 matches.InsertStringAtIndex(0, common_prefix.c_str()); 2187 } 2188 return num_command_matches; 2189 } 2190 2191 2192 CommandInterpreter::~CommandInterpreter () 2193 { 2194 } 2195 2196 void 2197 CommandInterpreter::UpdatePrompt (const char *new_prompt) 2198 { 2199 EventSP prompt_change_event_sp (new Event(eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));; 2200 BroadcastEvent (prompt_change_event_sp); 2201 if (m_command_io_handler_sp) 2202 m_command_io_handler_sp->SetPrompt(new_prompt); 2203 } 2204 2205 2206 bool 2207 CommandInterpreter::Confirm (const char *message, bool default_answer) 2208 { 2209 // Check AutoConfirm first: 2210 if (m_debugger.GetAutoConfirm()) 2211 return default_answer; 2212 2213 IOHandlerConfirm *confirm = new IOHandlerConfirm(m_debugger, 2214 message, 2215 default_answer); 2216 IOHandlerSP io_handler_sp (confirm); 2217 m_debugger.RunIOHandler (io_handler_sp); 2218 return confirm->GetResponse(); 2219 } 2220 2221 OptionArgVectorSP 2222 CommandInterpreter::GetAliasOptions (const char *alias_name) 2223 { 2224 OptionArgMap::iterator pos; 2225 OptionArgVectorSP ret_val; 2226 2227 std::string alias (alias_name); 2228 2229 if (HasAliasOptions()) 2230 { 2231 pos = m_alias_options.find (alias); 2232 if (pos != m_alias_options.end()) 2233 ret_val = pos->second; 2234 } 2235 2236 return ret_val; 2237 } 2238 2239 void 2240 CommandInterpreter::RemoveAliasOptions (const char *alias_name) 2241 { 2242 OptionArgMap::iterator pos = m_alias_options.find(alias_name); 2243 if (pos != m_alias_options.end()) 2244 { 2245 m_alias_options.erase (pos); 2246 } 2247 } 2248 2249 void 2250 CommandInterpreter::AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp) 2251 { 2252 m_alias_options[alias_name] = option_arg_vector_sp; 2253 } 2254 2255 bool 2256 CommandInterpreter::HasCommands () 2257 { 2258 return (!m_command_dict.empty()); 2259 } 2260 2261 bool 2262 CommandInterpreter::HasAliases () 2263 { 2264 return (!m_alias_dict.empty()); 2265 } 2266 2267 bool 2268 CommandInterpreter::HasUserCommands () 2269 { 2270 return (!m_user_dict.empty()); 2271 } 2272 2273 bool 2274 CommandInterpreter::HasAliasOptions () 2275 { 2276 return (!m_alias_options.empty()); 2277 } 2278 2279 void 2280 CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj, 2281 const char *alias_name, 2282 Args &cmd_args, 2283 std::string &raw_input_string, 2284 CommandReturnObject &result) 2285 { 2286 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); 2287 2288 bool wants_raw_input = alias_cmd_obj->WantsRawCommandString(); 2289 2290 // Make sure that the alias name is the 0th element in cmd_args 2291 std::string alias_name_str = alias_name; 2292 if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0) 2293 cmd_args.Unshift (alias_name); 2294 2295 Args new_args (alias_cmd_obj->GetCommandName()); 2296 if (new_args.GetArgumentCount() == 2) 2297 new_args.Shift(); 2298 2299 if (option_arg_vector_sp.get()) 2300 { 2301 if (wants_raw_input) 2302 { 2303 // We have a command that both has command options and takes raw input. Make *sure* it has a 2304 // " -- " in the right place in the raw_input_string. 2305 size_t pos = raw_input_string.find(" -- "); 2306 if (pos == std::string::npos) 2307 { 2308 // None found; assume it goes at the beginning of the raw input string 2309 raw_input_string.insert (0, " -- "); 2310 } 2311 } 2312 2313 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 2314 const size_t old_size = cmd_args.GetArgumentCount(); 2315 std::vector<bool> used (old_size + 1, false); 2316 2317 used[0] = true; 2318 2319 for (size_t i = 0; i < option_arg_vector->size(); ++i) 2320 { 2321 OptionArgPair option_pair = (*option_arg_vector)[i]; 2322 OptionArgValue value_pair = option_pair.second; 2323 int value_type = value_pair.first; 2324 std::string option = option_pair.first; 2325 std::string value = value_pair.second; 2326 if (option.compare ("<argument>") == 0) 2327 { 2328 if (!wants_raw_input 2329 || (value.compare("--") != 0)) // Since we inserted this above, make sure we don't insert it twice 2330 new_args.AppendArgument (value.c_str()); 2331 } 2332 else 2333 { 2334 if (value_type != OptionParser::eOptionalArgument) 2335 new_args.AppendArgument (option.c_str()); 2336 if (value.compare ("<no-argument>") != 0) 2337 { 2338 int index = GetOptionArgumentPosition (value.c_str()); 2339 if (index == 0) 2340 { 2341 // value was NOT a positional argument; must be a real value 2342 if (value_type != OptionParser::eOptionalArgument) 2343 new_args.AppendArgument (value.c_str()); 2344 else 2345 { 2346 char buffer[255]; 2347 ::snprintf (buffer, sizeof (buffer), "%s%s", option.c_str(), value.c_str()); 2348 new_args.AppendArgument (buffer); 2349 } 2350 2351 } 2352 else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount()) 2353 { 2354 result.AppendErrorWithFormat 2355 ("Not enough arguments provided; you need at least %d arguments to use this alias.\n", 2356 index); 2357 result.SetStatus (eReturnStatusFailed); 2358 return; 2359 } 2360 else 2361 { 2362 // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string 2363 size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index)); 2364 if (strpos != std::string::npos) 2365 { 2366 raw_input_string = raw_input_string.erase (strpos, strlen (cmd_args.GetArgumentAtIndex (index))); 2367 } 2368 2369 if (value_type != OptionParser::eOptionalArgument) 2370 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index)); 2371 else 2372 { 2373 char buffer[255]; 2374 ::snprintf (buffer, sizeof(buffer), "%s%s", option.c_str(), 2375 cmd_args.GetArgumentAtIndex (index)); 2376 new_args.AppendArgument (buffer); 2377 } 2378 used[index] = true; 2379 } 2380 } 2381 } 2382 } 2383 2384 for (size_t j = 0; j < cmd_args.GetArgumentCount(); ++j) 2385 { 2386 if (!used[j] && !wants_raw_input) 2387 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (j)); 2388 } 2389 2390 cmd_args.Clear(); 2391 cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector()); 2392 } 2393 else 2394 { 2395 result.SetStatus (eReturnStatusSuccessFinishNoResult); 2396 // This alias was not created with any options; nothing further needs to be done, unless it is a command that 2397 // wants raw input, in which case we need to clear the rest of the data from cmd_args, since its in the raw 2398 // input string. 2399 if (wants_raw_input) 2400 { 2401 cmd_args.Clear(); 2402 cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector()); 2403 } 2404 return; 2405 } 2406 2407 result.SetStatus (eReturnStatusSuccessFinishNoResult); 2408 return; 2409 } 2410 2411 2412 int 2413 CommandInterpreter::GetOptionArgumentPosition (const char *in_string) 2414 { 2415 int position = 0; // Any string that isn't an argument position, i.e. '%' followed by an integer, gets a position 2416 // of zero. 2417 2418 char *cptr = (char *) in_string; 2419 2420 // Does it start with '%' 2421 if (cptr[0] == '%') 2422 { 2423 ++cptr; 2424 2425 // Is the rest of it entirely digits? 2426 if (isdigit (cptr[0])) 2427 { 2428 const char *start = cptr; 2429 while (isdigit (cptr[0])) 2430 ++cptr; 2431 2432 // We've gotten to the end of the digits; are we at the end of the string? 2433 if (cptr[0] == '\0') 2434 position = atoi (start); 2435 } 2436 } 2437 2438 return position; 2439 } 2440 2441 void 2442 CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result) 2443 { 2444 FileSpec init_file; 2445 if (in_cwd) 2446 { 2447 // In the current working directory we don't load any program specific 2448 // .lldbinit files, we only look for a "./.lldbinit" file. 2449 if (m_skip_lldbinit_files) 2450 return; 2451 2452 init_file.SetFile ("./.lldbinit", true); 2453 } 2454 else 2455 { 2456 // If we aren't looking in the current working directory we are looking 2457 // in the home directory. We will first see if there is an application 2458 // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a 2459 // "-" and the name of the program. If this file doesn't exist, we fall 2460 // back to just the "~/.lldbinit" file. We also obey any requests to not 2461 // load the init files. 2462 llvm::SmallString<64> home_dir_path; 2463 llvm::sys::path::home_directory(home_dir_path); 2464 FileSpec profilePath(home_dir_path.c_str(), false); 2465 profilePath.AppendPathComponent(".lldbinit"); 2466 std::string init_file_path = profilePath.GetPath(); 2467 2468 if (m_skip_app_init_files == false) 2469 { 2470 FileSpec program_file_spec(HostInfo::GetProgramFileSpec()); 2471 const char *program_name = program_file_spec.GetFilename().AsCString(); 2472 2473 if (program_name) 2474 { 2475 char program_init_file_name[PATH_MAX]; 2476 ::snprintf (program_init_file_name, sizeof(program_init_file_name), "%s-%s", init_file_path.c_str(), program_name); 2477 init_file.SetFile (program_init_file_name, true); 2478 if (!init_file.Exists()) 2479 init_file.Clear(); 2480 } 2481 } 2482 2483 if (!init_file && !m_skip_lldbinit_files) 2484 init_file.SetFile (init_file_path.c_str(), false); 2485 } 2486 2487 // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting 2488 // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details). 2489 2490 if (init_file.Exists()) 2491 { 2492 const bool saved_batch = SetBatchCommandMode (true); 2493 CommandInterpreterRunOptions options; 2494 options.SetSilent (true); 2495 options.SetStopOnError (false); 2496 options.SetStopOnContinue (true); 2497 2498 HandleCommandsFromFile (init_file, 2499 nullptr, // Execution context 2500 options, 2501 result); 2502 SetBatchCommandMode (saved_batch); 2503 } 2504 else 2505 { 2506 // nothing to be done if the file doesn't exist 2507 result.SetStatus(eReturnStatusSuccessFinishNoResult); 2508 } 2509 } 2510 2511 const char * 2512 CommandInterpreter::GetCommandPrefix() 2513 { 2514 const char * prefix = GetDebugger().GetIOHandlerCommandPrefix(); 2515 return prefix == NULL ? "" : prefix; 2516 } 2517 2518 PlatformSP 2519 CommandInterpreter::GetPlatform (bool prefer_target_platform) 2520 { 2521 PlatformSP platform_sp; 2522 if (prefer_target_platform) 2523 { 2524 ExecutionContext exe_ctx(GetExecutionContext()); 2525 Target *target = exe_ctx.GetTargetPtr(); 2526 if (target) 2527 platform_sp = target->GetPlatform(); 2528 } 2529 2530 if (!platform_sp) 2531 platform_sp = m_debugger.GetPlatformList().GetSelectedPlatform(); 2532 return platform_sp; 2533 } 2534 2535 void 2536 CommandInterpreter::HandleCommands (const StringList &commands, 2537 ExecutionContext *override_context, 2538 CommandInterpreterRunOptions &options, 2539 CommandReturnObject &result) 2540 { 2541 size_t num_lines = commands.GetSize(); 2542 2543 // If we are going to continue past a "continue" then we need to run the commands synchronously. 2544 // Make sure you reset this value anywhere you return from the function. 2545 2546 bool old_async_execution = m_debugger.GetAsyncExecution(); 2547 2548 // If we've been given an execution context, set it at the start, but don't keep resetting it or we will 2549 // cause series of commands that change the context, then do an operation that relies on that context to fail. 2550 2551 if (override_context != nullptr) 2552 UpdateExecutionContext (override_context); 2553 2554 if (!options.GetStopOnContinue()) 2555 { 2556 m_debugger.SetAsyncExecution (false); 2557 } 2558 2559 for (size_t idx = 0; idx < num_lines; idx++) 2560 { 2561 const char *cmd = commands.GetStringAtIndex(idx); 2562 if (cmd[0] == '\0') 2563 continue; 2564 2565 if (options.GetEchoCommands()) 2566 { 2567 result.AppendMessageWithFormat ("%s %s\n", 2568 m_debugger.GetPrompt(), 2569 cmd); 2570 } 2571 2572 CommandReturnObject tmp_result; 2573 // If override_context is not NULL, pass no_context_switching = true for 2574 // HandleCommand() since we updated our context already. 2575 2576 // We might call into a regex or alias command, in which case the add_to_history will get lost. This 2577 // m_command_source_depth dingus is the way we turn off adding to the history in that case, so set it up here. 2578 if (!options.GetAddToHistory()) 2579 m_command_source_depth++; 2580 bool success = HandleCommand(cmd, options.m_add_to_history, tmp_result, 2581 nullptr, /* override_context */ 2582 true, /* repeat_on_empty_command */ 2583 override_context != nullptr /* no_context_switching */); 2584 if (!options.GetAddToHistory()) 2585 m_command_source_depth--; 2586 2587 if (options.GetPrintResults()) 2588 { 2589 if (tmp_result.Succeeded()) 2590 result.AppendMessageWithFormat("%s", tmp_result.GetOutputData()); 2591 } 2592 2593 if (!success || !tmp_result.Succeeded()) 2594 { 2595 const char *error_msg = tmp_result.GetErrorData(); 2596 if (error_msg == nullptr || error_msg[0] == '\0') 2597 error_msg = "<unknown error>.\n"; 2598 if (options.GetStopOnError()) 2599 { 2600 result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' failed with %s", 2601 (uint64_t)idx, cmd, error_msg); 2602 result.SetStatus (eReturnStatusFailed); 2603 m_debugger.SetAsyncExecution (old_async_execution); 2604 return; 2605 } 2606 else if (options.GetPrintResults()) 2607 { 2608 result.AppendMessageWithFormat ("Command #%" PRIu64 " '%s' failed with %s", 2609 (uint64_t)idx + 1, 2610 cmd, 2611 error_msg); 2612 } 2613 } 2614 2615 if (result.GetImmediateOutputStream()) 2616 result.GetImmediateOutputStream()->Flush(); 2617 2618 if (result.GetImmediateErrorStream()) 2619 result.GetImmediateErrorStream()->Flush(); 2620 2621 // N.B. Can't depend on DidChangeProcessState, because the state coming into the command execution 2622 // could be running (for instance in Breakpoint Commands. 2623 // So we check the return value to see if it is has running in it. 2624 if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult) 2625 || (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult)) 2626 { 2627 if (options.GetStopOnContinue()) 2628 { 2629 // If we caused the target to proceed, and we're going to stop in that case, set the 2630 // status in our real result before returning. This is an error if the continue was not the 2631 // last command in the set of commands to be run. 2632 if (idx != num_lines - 1) 2633 result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' continued the target.\n", 2634 (uint64_t)idx + 1, cmd); 2635 else 2636 result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' continued the target.\n", (uint64_t)idx + 1, cmd); 2637 2638 result.SetStatus(tmp_result.GetStatus()); 2639 m_debugger.SetAsyncExecution (old_async_execution); 2640 2641 return; 2642 } 2643 } 2644 2645 // Also check for "stop on crash here: 2646 bool should_stop = false; 2647 if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash()) 2648 { 2649 TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget()); 2650 if (target_sp) 2651 { 2652 ProcessSP process_sp (target_sp->GetProcessSP()); 2653 if (process_sp) 2654 { 2655 for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) 2656 { 2657 StopReason reason = thread_sp->GetStopReason(); 2658 if (reason == eStopReasonSignal || reason == eStopReasonException || reason == eStopReasonInstrumentation) 2659 { 2660 should_stop = true; 2661 break; 2662 } 2663 } 2664 } 2665 } 2666 if (should_stop) 2667 { 2668 if (idx != num_lines - 1) 2669 result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' stopped with a signal or exception.\n", 2670 (uint64_t)idx + 1, cmd); 2671 else 2672 result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' stopped with a signal or exception.\n", (uint64_t)idx + 1, cmd); 2673 2674 result.SetStatus(tmp_result.GetStatus()); 2675 m_debugger.SetAsyncExecution (old_async_execution); 2676 2677 return; 2678 } 2679 } 2680 2681 } 2682 2683 result.SetStatus (eReturnStatusSuccessFinishResult); 2684 m_debugger.SetAsyncExecution (old_async_execution); 2685 2686 return; 2687 } 2688 2689 // Make flags that we can pass into the IOHandler so our delegates can do the right thing 2690 enum { 2691 eHandleCommandFlagStopOnContinue = (1u << 0), 2692 eHandleCommandFlagStopOnError = (1u << 1), 2693 eHandleCommandFlagEchoCommand = (1u << 2), 2694 eHandleCommandFlagPrintResult = (1u << 3), 2695 eHandleCommandFlagStopOnCrash = (1u << 4) 2696 }; 2697 2698 void 2699 CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file, 2700 ExecutionContext *context, 2701 CommandInterpreterRunOptions &options, 2702 CommandReturnObject &result) 2703 { 2704 if (cmd_file.Exists()) 2705 { 2706 StreamFileSP input_file_sp (new StreamFile()); 2707 2708 std::string cmd_file_path = cmd_file.GetPath(); 2709 Error error = input_file_sp->GetFile().Open(cmd_file_path.c_str(), File::eOpenOptionRead); 2710 2711 if (error.Success()) 2712 { 2713 Debugger &debugger = GetDebugger(); 2714 2715 uint32_t flags = 0; 2716 2717 if (options.m_stop_on_continue == eLazyBoolCalculate) 2718 { 2719 if (m_command_source_flags.empty()) 2720 { 2721 // Stop on continue by default 2722 flags |= eHandleCommandFlagStopOnContinue; 2723 } 2724 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnContinue) 2725 { 2726 flags |= eHandleCommandFlagStopOnContinue; 2727 } 2728 } 2729 else if (options.m_stop_on_continue == eLazyBoolYes) 2730 { 2731 flags |= eHandleCommandFlagStopOnContinue; 2732 } 2733 2734 if (options.m_stop_on_error == eLazyBoolCalculate) 2735 { 2736 if (m_command_source_flags.empty()) 2737 { 2738 if (GetStopCmdSourceOnError()) 2739 flags |= eHandleCommandFlagStopOnError; 2740 } 2741 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnError) 2742 { 2743 flags |= eHandleCommandFlagStopOnError; 2744 } 2745 } 2746 else if (options.m_stop_on_error == eLazyBoolYes) 2747 { 2748 flags |= eHandleCommandFlagStopOnError; 2749 } 2750 2751 if (options.GetStopOnCrash()) 2752 { 2753 if (m_command_source_flags.empty()) 2754 { 2755 // Echo command by default 2756 flags |= eHandleCommandFlagStopOnCrash; 2757 } 2758 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnCrash) 2759 { 2760 flags |= eHandleCommandFlagStopOnCrash; 2761 } 2762 } 2763 2764 if (options.m_echo_commands == eLazyBoolCalculate) 2765 { 2766 if (m_command_source_flags.empty()) 2767 { 2768 // Echo command by default 2769 flags |= eHandleCommandFlagEchoCommand; 2770 } 2771 else if (m_command_source_flags.back() & eHandleCommandFlagEchoCommand) 2772 { 2773 flags |= eHandleCommandFlagEchoCommand; 2774 } 2775 } 2776 else if (options.m_echo_commands == eLazyBoolYes) 2777 { 2778 flags |= eHandleCommandFlagEchoCommand; 2779 } 2780 2781 if (options.m_print_results == eLazyBoolCalculate) 2782 { 2783 if (m_command_source_flags.empty()) 2784 { 2785 // Print output by default 2786 flags |= eHandleCommandFlagPrintResult; 2787 } 2788 else if (m_command_source_flags.back() & eHandleCommandFlagPrintResult) 2789 { 2790 flags |= eHandleCommandFlagPrintResult; 2791 } 2792 } 2793 else if (options.m_print_results == eLazyBoolYes) 2794 { 2795 flags |= eHandleCommandFlagPrintResult; 2796 } 2797 2798 if (flags & eHandleCommandFlagPrintResult) 2799 { 2800 debugger.GetOutputFile()->Printf("Executing commands in '%s'.\n", cmd_file_path.c_str()); 2801 } 2802 2803 // Used for inheriting the right settings when "command source" might have 2804 // nested "command source" commands 2805 lldb::StreamFileSP empty_stream_sp; 2806 m_command_source_flags.push_back(flags); 2807 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, 2808 IOHandler::Type::CommandInterpreter, 2809 input_file_sp, 2810 empty_stream_sp, // Pass in an empty stream so we inherit the top input reader output stream 2811 empty_stream_sp, // Pass in an empty stream so we inherit the top input reader error stream 2812 flags, 2813 nullptr, // Pass in NULL for "editline_name" so no history is saved, or written 2814 debugger.GetPrompt(), 2815 NULL, 2816 false, // Not multi-line 2817 debugger.GetUseColor(), 2818 0, 2819 *this)); 2820 const bool old_async_execution = debugger.GetAsyncExecution(); 2821 2822 // Set synchronous execution if we are not stopping on continue 2823 if ((flags & eHandleCommandFlagStopOnContinue) == 0) 2824 debugger.SetAsyncExecution (false); 2825 2826 m_command_source_depth++; 2827 2828 debugger.RunIOHandler(io_handler_sp); 2829 if (!m_command_source_flags.empty()) 2830 m_command_source_flags.pop_back(); 2831 m_command_source_depth--; 2832 result.SetStatus (eReturnStatusSuccessFinishNoResult); 2833 debugger.SetAsyncExecution (old_async_execution); 2834 } 2835 else 2836 { 2837 result.AppendErrorWithFormat ("error: an error occurred read file '%s': %s\n", cmd_file_path.c_str(), error.AsCString()); 2838 result.SetStatus (eReturnStatusFailed); 2839 } 2840 2841 2842 } 2843 else 2844 { 2845 result.AppendErrorWithFormat ("Error reading commands from file %s - file not found.\n", 2846 cmd_file.GetFilename().AsCString("<Unknown>")); 2847 result.SetStatus (eReturnStatusFailed); 2848 return; 2849 } 2850 } 2851 2852 ScriptInterpreter * 2853 CommandInterpreter::GetScriptInterpreter (bool can_create) 2854 { 2855 if (m_script_interpreter_ap.get() != nullptr) 2856 return m_script_interpreter_ap.get(); 2857 2858 if (!can_create) 2859 return nullptr; 2860 2861 // <rdar://problem/11751427> 2862 // we need to protect the initialization of the script interpreter 2863 // otherwise we could end up with two threads both trying to create 2864 // their instance of it, and for some languages (e.g. Python) 2865 // this is a bulletproof recipe for disaster! 2866 // this needs to be a function-level static because multiple Debugger instances living in the same process 2867 // still need to be isolated and not try to initialize Python concurrently 2868 static Mutex g_interpreter_mutex(Mutex::eMutexTypeRecursive); 2869 Mutex::Locker interpreter_lock(g_interpreter_mutex); 2870 2871 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 2872 if (log) 2873 log->Printf("Initializing the ScriptInterpreter now\n"); 2874 2875 lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage(); 2876 switch (script_lang) 2877 { 2878 case eScriptLanguagePython: 2879 #ifndef LLDB_DISABLE_PYTHON 2880 m_script_interpreter_ap.reset (new ScriptInterpreterPython (*this)); 2881 break; 2882 #else 2883 // Fall through to the None case when python is disabled 2884 #endif 2885 case eScriptLanguageNone: 2886 m_script_interpreter_ap.reset (new ScriptInterpreterNone (*this)); 2887 break; 2888 }; 2889 2890 return m_script_interpreter_ap.get(); 2891 } 2892 2893 2894 2895 bool 2896 CommandInterpreter::GetSynchronous () 2897 { 2898 return m_synchronous_execution; 2899 } 2900 2901 void 2902 CommandInterpreter::SetSynchronous (bool value) 2903 { 2904 m_synchronous_execution = value; 2905 } 2906 2907 void 2908 CommandInterpreter::OutputFormattedHelpText (Stream &strm, 2909 const char *prefix, 2910 const char *help_text) 2911 { 2912 const uint32_t max_columns = m_debugger.GetTerminalWidth(); 2913 if (prefix == NULL) 2914 prefix = ""; 2915 2916 size_t prefix_width = strlen(prefix); 2917 size_t line_width_max = max_columns - prefix_width; 2918 const char *help_text_end = help_text + strlen(help_text); 2919 const char *line_start = help_text; 2920 if (line_width_max < 16) 2921 line_width_max = help_text_end - help_text + prefix_width; 2922 2923 strm.IndentMore (prefix_width); 2924 while (line_start < help_text_end) 2925 { 2926 // Break each line at the first newline or last space/tab before 2927 // the maximum number of characters that fit on a line. Lines with no 2928 // natural break are left unbroken to wrap. 2929 const char *line_end = help_text_end; 2930 const char *line_scan = line_start; 2931 const char *line_scan_end = help_text_end; 2932 while (line_scan < line_scan_end) 2933 { 2934 char next = *line_scan; 2935 if (next == '\t' || next == ' ') 2936 { 2937 line_end = line_scan; 2938 line_scan_end = line_start + line_width_max; 2939 } 2940 else if (next == '\n' || next == '\0') 2941 { 2942 line_end = line_scan; 2943 break; 2944 } 2945 ++line_scan; 2946 } 2947 2948 // Prefix the first line, indent subsequent lines to line up 2949 if (line_start == help_text) 2950 strm.Write (prefix, prefix_width); 2951 else 2952 strm.Indent(); 2953 strm.Write (line_start, line_end - line_start); 2954 strm.EOL(); 2955 2956 // When a line breaks at whitespace consume it before continuing 2957 line_start = line_end; 2958 char next = *line_start; 2959 if (next == '\n') 2960 ++line_start; 2961 else while (next == ' ' || next == '\t') 2962 next = *(++line_start); 2963 } 2964 strm.IndentLess (prefix_width); 2965 } 2966 2967 void 2968 CommandInterpreter::OutputFormattedHelpText (Stream &strm, 2969 const char *word_text, 2970 const char *separator, 2971 const char *help_text, 2972 size_t max_word_len) 2973 { 2974 StreamString prefix_stream; 2975 prefix_stream.Printf (" %-*s %s ", (int)max_word_len, word_text, separator); 2976 OutputFormattedHelpText (strm, prefix_stream.GetData(), help_text); 2977 } 2978 2979 void 2980 CommandInterpreter::OutputHelpText (Stream &strm, 2981 const char *word_text, 2982 const char *separator, 2983 const char *help_text, 2984 uint32_t max_word_len) 2985 { 2986 int indent_size = max_word_len + strlen (separator) + 2; 2987 2988 strm.IndentMore (indent_size); 2989 2990 StreamString text_strm; 2991 text_strm.Printf ("%-*s %s %s", max_word_len, word_text, separator, help_text); 2992 2993 const uint32_t max_columns = m_debugger.GetTerminalWidth(); 2994 2995 size_t len = text_strm.GetSize(); 2996 const char *text = text_strm.GetData(); 2997 2998 uint32_t chars_left = max_columns; 2999 3000 for (uint32_t i = 0; i < len; i++) 3001 { 3002 if ((text[i] == ' ' && ::strchr((text+i+1), ' ') && chars_left < ::strchr((text+i+1), ' ')-(text+i)) || text[i] == '\n') 3003 { 3004 chars_left = max_columns - indent_size; 3005 strm.EOL(); 3006 strm.Indent(); 3007 } 3008 else 3009 { 3010 strm.PutChar(text[i]); 3011 chars_left--; 3012 } 3013 3014 } 3015 3016 strm.EOL(); 3017 strm.IndentLess(indent_size); 3018 } 3019 3020 void 3021 CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found, 3022 StringList &commands_help, bool search_builtin_commands, bool search_user_commands) 3023 { 3024 CommandObject::CommandMap::const_iterator pos; 3025 3026 if (search_builtin_commands) 3027 { 3028 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) 3029 { 3030 const char *command_name = pos->first.c_str(); 3031 CommandObject *cmd_obj = pos->second.get(); 3032 3033 if (cmd_obj->HelpTextContainsWord (search_word)) 3034 { 3035 commands_found.AppendString (command_name); 3036 commands_help.AppendString (cmd_obj->GetHelp()); 3037 } 3038 3039 if (cmd_obj->IsMultiwordObject()) 3040 cmd_obj->AproposAllSubCommands (command_name, 3041 search_word, 3042 commands_found, 3043 commands_help); 3044 3045 } 3046 } 3047 3048 if (search_user_commands) 3049 { 3050 for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos) 3051 { 3052 const char *command_name = pos->first.c_str(); 3053 CommandObject *cmd_obj = pos->second.get(); 3054 3055 if (cmd_obj->HelpTextContainsWord (search_word)) 3056 { 3057 commands_found.AppendString (command_name); 3058 commands_help.AppendString (cmd_obj->GetHelp()); 3059 } 3060 3061 if (cmd_obj->IsMultiwordObject()) 3062 cmd_obj->AproposAllSubCommands (command_name, 3063 search_word, 3064 commands_found, 3065 commands_help); 3066 3067 } 3068 } 3069 } 3070 3071 void 3072 CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context) 3073 { 3074 if (override_context != nullptr) 3075 { 3076 m_exe_ctx_ref = *override_context; 3077 } 3078 else 3079 { 3080 const bool adopt_selected = true; 3081 m_exe_ctx_ref.SetTargetPtr (m_debugger.GetSelectedTarget().get(), adopt_selected); 3082 } 3083 } 3084 3085 3086 size_t 3087 CommandInterpreter::GetProcessOutput () 3088 { 3089 // The process has stuff waiting for stderr; get it and write it out to the appropriate place. 3090 char stdio_buffer[1024]; 3091 size_t len; 3092 size_t total_bytes = 0; 3093 Error error; 3094 TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget()); 3095 if (target_sp) 3096 { 3097 ProcessSP process_sp (target_sp->GetProcessSP()); 3098 if (process_sp) 3099 { 3100 while ((len = process_sp->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 3101 { 3102 size_t bytes_written = len; 3103 m_debugger.GetOutputFile()->Write (stdio_buffer, bytes_written); 3104 total_bytes += len; 3105 } 3106 while ((len = process_sp->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 3107 { 3108 size_t bytes_written = len; 3109 m_debugger.GetErrorFile()->Write (stdio_buffer, bytes_written); 3110 total_bytes += len; 3111 } 3112 } 3113 } 3114 return total_bytes; 3115 } 3116 3117 void 3118 CommandInterpreter::IOHandlerInputComplete (IOHandler &io_handler, std::string &line) 3119 { 3120 const bool is_interactive = io_handler.GetIsInteractive(); 3121 if (is_interactive == false) 3122 { 3123 // When we are not interactive, don't execute blank lines. This will happen 3124 // sourcing a commands file. We don't want blank lines to repeat the previous 3125 // command and cause any errors to occur (like redefining an alias, get an error 3126 // and stop parsing the commands file). 3127 if (line.empty()) 3128 return; 3129 3130 // When using a non-interactive file handle (like when sourcing commands from a file) 3131 // we need to echo the command out so we don't just see the command output and no 3132 // command... 3133 if (io_handler.GetFlags().Test(eHandleCommandFlagEchoCommand)) 3134 io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(), line.c_str()); 3135 } 3136 3137 lldb_private::CommandReturnObject result; 3138 HandleCommand(line.c_str(), eLazyBoolCalculate, result); 3139 3140 // Now emit the command output text from the command we just executed 3141 if (io_handler.GetFlags().Test(eHandleCommandFlagPrintResult)) 3142 { 3143 // Display any STDOUT/STDERR _prior_ to emitting the command result text 3144 GetProcessOutput (); 3145 3146 if (!result.GetImmediateOutputStream()) 3147 { 3148 const char *output = result.GetOutputData(); 3149 if (output && output[0]) 3150 io_handler.GetOutputStreamFile()->PutCString(output); 3151 } 3152 3153 // Now emit the command error text from the command we just executed 3154 if (!result.GetImmediateErrorStream()) 3155 { 3156 const char *error = result.GetErrorData(); 3157 if (error && error[0]) 3158 io_handler.GetErrorStreamFile()->PutCString(error); 3159 } 3160 } 3161 3162 switch (result.GetStatus()) 3163 { 3164 case eReturnStatusInvalid: 3165 case eReturnStatusSuccessFinishNoResult: 3166 case eReturnStatusSuccessFinishResult: 3167 case eReturnStatusStarted: 3168 break; 3169 3170 case eReturnStatusSuccessContinuingNoResult: 3171 case eReturnStatusSuccessContinuingResult: 3172 if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnContinue)) 3173 io_handler.SetIsDone(true); 3174 break; 3175 3176 case eReturnStatusFailed: 3177 m_num_errors++; 3178 if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError)) 3179 io_handler.SetIsDone(true); 3180 break; 3181 3182 case eReturnStatusQuit: 3183 m_quit_requested = true; 3184 io_handler.SetIsDone(true); 3185 break; 3186 } 3187 3188 // Finally, if we're going to stop on crash, check that here: 3189 if (!m_quit_requested 3190 && result.GetDidChangeProcessState() 3191 && io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash)) 3192 { 3193 bool should_stop = false; 3194 TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget()); 3195 if (target_sp) 3196 { 3197 ProcessSP process_sp (target_sp->GetProcessSP()); 3198 if (process_sp) 3199 { 3200 for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) 3201 { 3202 StopReason reason = thread_sp->GetStopReason(); 3203 if (reason == eStopReasonSignal || reason == eStopReasonException || reason == eStopReasonInstrumentation) 3204 { 3205 should_stop = true; 3206 break; 3207 } 3208 } 3209 } 3210 } 3211 if (should_stop) 3212 { 3213 io_handler.SetIsDone(true); 3214 m_stopped_for_crash = true; 3215 } 3216 } 3217 } 3218 3219 bool 3220 CommandInterpreter::IOHandlerInterrupt (IOHandler &io_handler) 3221 { 3222 ExecutionContext exe_ctx (GetExecutionContext()); 3223 Process *process = exe_ctx.GetProcessPtr(); 3224 3225 if (process) 3226 { 3227 StateType state = process->GetState(); 3228 if (StateIsRunningState(state)) 3229 { 3230 process->Halt(); 3231 return true; // Don't do any updating when we are running 3232 } 3233 } 3234 3235 ScriptInterpreter *script_interpreter = GetScriptInterpreter (false); 3236 if (script_interpreter) 3237 { 3238 if (script_interpreter->Interrupt()) 3239 return true; 3240 } 3241 return false; 3242 } 3243 3244 void 3245 CommandInterpreter::GetLLDBCommandsFromIOHandler (const char *prompt, 3246 IOHandlerDelegate &delegate, 3247 bool asynchronously, 3248 void *baton) 3249 { 3250 Debugger &debugger = GetDebugger(); 3251 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, 3252 IOHandler::Type::CommandList, 3253 "lldb", // Name of input reader for history 3254 prompt, // Prompt 3255 NULL, // Continuation prompt 3256 true, // Get multiple lines 3257 debugger.GetUseColor(), 3258 0, // Don't show line numbers 3259 delegate)); // IOHandlerDelegate 3260 3261 if (io_handler_sp) 3262 { 3263 io_handler_sp->SetUserData (baton); 3264 if (asynchronously) 3265 debugger.PushIOHandler(io_handler_sp); 3266 else 3267 debugger.RunIOHandler(io_handler_sp); 3268 } 3269 3270 } 3271 3272 3273 void 3274 CommandInterpreter::GetPythonCommandsFromIOHandler (const char *prompt, 3275 IOHandlerDelegate &delegate, 3276 bool asynchronously, 3277 void *baton) 3278 { 3279 Debugger &debugger = GetDebugger(); 3280 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, 3281 IOHandler::Type::PythonCode, 3282 "lldb-python", // Name of input reader for history 3283 prompt, // Prompt 3284 NULL, // Continuation prompt 3285 true, // Get multiple lines 3286 debugger.GetUseColor(), 3287 0, // Don't show line numbers 3288 delegate)); // IOHandlerDelegate 3289 3290 if (io_handler_sp) 3291 { 3292 io_handler_sp->SetUserData (baton); 3293 if (asynchronously) 3294 debugger.PushIOHandler(io_handler_sp); 3295 else 3296 debugger.RunIOHandler(io_handler_sp); 3297 } 3298 3299 } 3300 3301 bool 3302 CommandInterpreter::IsActive () 3303 { 3304 return m_debugger.IsTopIOHandler (m_command_io_handler_sp); 3305 } 3306 3307 lldb::IOHandlerSP 3308 CommandInterpreter::GetIOHandler(bool force_create, CommandInterpreterRunOptions *options) 3309 { 3310 // Always re-create the IOHandlerEditline in case the input 3311 // changed. The old instance might have had a non-interactive 3312 // input and now it does or vice versa. 3313 if (force_create || !m_command_io_handler_sp) 3314 { 3315 // Always re-create the IOHandlerEditline in case the input 3316 // changed. The old instance might have had a non-interactive 3317 // input and now it does or vice versa. 3318 uint32_t flags = 0; 3319 3320 if (options) 3321 { 3322 if (options->m_stop_on_continue == eLazyBoolYes) 3323 flags |= eHandleCommandFlagStopOnContinue; 3324 if (options->m_stop_on_error == eLazyBoolYes) 3325 flags |= eHandleCommandFlagStopOnError; 3326 if (options->m_stop_on_crash == eLazyBoolYes) 3327 flags |= eHandleCommandFlagStopOnCrash; 3328 if (options->m_echo_commands != eLazyBoolNo) 3329 flags |= eHandleCommandFlagEchoCommand; 3330 if (options->m_print_results != eLazyBoolNo) 3331 flags |= eHandleCommandFlagPrintResult; 3332 } 3333 else 3334 { 3335 flags = eHandleCommandFlagEchoCommand | eHandleCommandFlagPrintResult; 3336 } 3337 3338 m_command_io_handler_sp.reset(new IOHandlerEditline (m_debugger, 3339 IOHandler::Type::CommandInterpreter, 3340 m_debugger.GetInputFile(), 3341 m_debugger.GetOutputFile(), 3342 m_debugger.GetErrorFile(), 3343 flags, 3344 "lldb", 3345 m_debugger.GetPrompt(), 3346 NULL, // Continuation prompt 3347 false, // Don't enable multiple line input, just single line commands 3348 m_debugger.GetUseColor(), 3349 0, // Don't show line numbers 3350 *this)); 3351 } 3352 return m_command_io_handler_sp; 3353 } 3354 3355 void 3356 CommandInterpreter::RunCommandInterpreter(bool auto_handle_events, 3357 bool spawn_thread, 3358 CommandInterpreterRunOptions &options) 3359 { 3360 // Always re-create the command intepreter when we run it in case 3361 // any file handles have changed. 3362 bool force_create = true; 3363 m_debugger.PushIOHandler(GetIOHandler(force_create, &options)); 3364 m_stopped_for_crash = false; 3365 3366 if (auto_handle_events) 3367 m_debugger.StartEventHandlerThread(); 3368 3369 if (spawn_thread) 3370 { 3371 m_debugger.StartIOHandlerThread(); 3372 } 3373 else 3374 { 3375 m_debugger.ExecuteIOHandlers(); 3376 3377 if (auto_handle_events) 3378 m_debugger.StopEventHandlerThread(); 3379 } 3380 3381 } 3382 3383