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