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 CommandObject::CommandMap::const_iterator pos; 1174 size_t max_len = FindLongestCommandWord (m_command_dict); 1175 1176 if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin ) 1177 { 1178 1179 result.AppendMessage("The following is a list of built-in, permanent debugger commands:"); 1180 result.AppendMessage(""); 1181 1182 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) 1183 { 1184 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), 1185 max_len); 1186 } 1187 result.AppendMessage(""); 1188 1189 } 1190 1191 if (!m_alias_dict.empty() && ( (cmd_types & eCommandTypesAliases) == eCommandTypesAliases )) 1192 { 1193 result.AppendMessage("The following is a list of your current command abbreviations " 1194 "(see 'help command alias' for more info):"); 1195 result.AppendMessage(""); 1196 max_len = FindLongestCommandWord (m_alias_dict); 1197 1198 for (pos = m_alias_dict.begin(); pos != m_alias_dict.end(); ++pos) 1199 { 1200 StreamString sstr; 1201 StreamString translation_and_help; 1202 std::string entry_name = pos->first; 1203 std::string second_entry = pos->second.get()->GetCommandName(); 1204 GetAliasHelp (pos->first.c_str(), pos->second->GetCommandName(), sstr); 1205 1206 translation_and_help.Printf ("(%s) %s", sstr.GetData(), pos->second->GetHelp()); 1207 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", 1208 translation_and_help.GetData(), max_len); 1209 } 1210 result.AppendMessage(""); 1211 } 1212 1213 if (!m_user_dict.empty() && ( (cmd_types & eCommandTypesUserDef) == eCommandTypesUserDef )) 1214 { 1215 result.AppendMessage ("The following is a list of your current user-defined commands:"); 1216 result.AppendMessage(""); 1217 max_len = FindLongestCommandWord (m_user_dict); 1218 for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos) 1219 { 1220 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), 1221 max_len); 1222 } 1223 result.AppendMessage(""); 1224 } 1225 1226 result.AppendMessage("For more information on any particular command, try 'help <command-name>'."); 1227 } 1228 1229 CommandObject * 1230 CommandInterpreter::GetCommandObjectForCommand (std::string &command_string) 1231 { 1232 // This function finds the final, lowest-level, alias-resolved command object whose 'Execute' function will 1233 // eventually be invoked by the given command line. 1234 1235 CommandObject *cmd_obj = nullptr; 1236 std::string white_space (" \t\v"); 1237 size_t start = command_string.find_first_not_of (white_space); 1238 size_t end = 0; 1239 bool done = false; 1240 while (!done) 1241 { 1242 if (start != std::string::npos) 1243 { 1244 // Get the next word from command_string. 1245 end = command_string.find_first_of (white_space, start); 1246 if (end == std::string::npos) 1247 end = command_string.size(); 1248 std::string cmd_word = command_string.substr (start, end - start); 1249 1250 if (cmd_obj == nullptr) 1251 // Since cmd_obj is NULL we are on our first time through this loop. Check to see if cmd_word is a valid 1252 // command or alias. 1253 cmd_obj = GetCommandObject (cmd_word.c_str()); 1254 else if (cmd_obj->IsMultiwordObject ()) 1255 { 1256 // Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object. 1257 CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (cmd_word.c_str()); 1258 if (sub_cmd_obj) 1259 cmd_obj = sub_cmd_obj; 1260 else // cmd_word was not a valid sub-command word, so we are donee 1261 done = true; 1262 } 1263 else 1264 // We have a cmd_obj and it is not a multi-word object, so we are done. 1265 done = true; 1266 1267 // If we didn't find a valid command object, or our command object is not a multi-word object, or 1268 // we are at the end of the command_string, then we are done. Otherwise, find the start of the 1269 // next word. 1270 1271 if (!cmd_obj || !cmd_obj->IsMultiwordObject() || end >= command_string.size()) 1272 done = true; 1273 else 1274 start = command_string.find_first_not_of (white_space, end); 1275 } 1276 else 1277 // Unable to find any more words. 1278 done = true; 1279 } 1280 1281 if (end == command_string.size()) 1282 command_string.clear(); 1283 else 1284 command_string = command_string.substr(end); 1285 1286 return cmd_obj; 1287 } 1288 1289 static const char *k_white_space = " \t\v"; 1290 static const char *k_valid_command_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"; 1291 static void 1292 StripLeadingSpaces (std::string &s) 1293 { 1294 if (!s.empty()) 1295 { 1296 size_t pos = s.find_first_not_of (k_white_space); 1297 if (pos == std::string::npos) 1298 s.clear(); 1299 else if (pos == 0) 1300 return; 1301 s.erase (0, pos); 1302 } 1303 } 1304 1305 static size_t 1306 FindArgumentTerminator (const std::string &s) 1307 { 1308 const size_t s_len = s.size(); 1309 size_t offset = 0; 1310 while (offset < s_len) 1311 { 1312 size_t pos = s.find ("--", offset); 1313 if (pos == std::string::npos) 1314 break; 1315 if (pos > 0) 1316 { 1317 if (isspace(s[pos-1])) 1318 { 1319 // Check if the string ends "\s--" (where \s is a space character) 1320 // or if we have "\s--\s". 1321 if ((pos + 2 >= s_len) || isspace(s[pos+2])) 1322 { 1323 return pos; 1324 } 1325 } 1326 } 1327 offset = pos + 2; 1328 } 1329 return std::string::npos; 1330 } 1331 1332 static bool 1333 ExtractCommand (std::string &command_string, std::string &command, std::string &suffix, char "e_char) 1334 { 1335 command.clear(); 1336 suffix.clear(); 1337 StripLeadingSpaces (command_string); 1338 1339 bool result = false; 1340 quote_char = '\0'; 1341 1342 if (!command_string.empty()) 1343 { 1344 const char first_char = command_string[0]; 1345 if (first_char == '\'' || first_char == '"') 1346 { 1347 quote_char = first_char; 1348 const size_t end_quote_pos = command_string.find (quote_char, 1); 1349 if (end_quote_pos == std::string::npos) 1350 { 1351 command.swap (command_string); 1352 command_string.erase (); 1353 } 1354 else 1355 { 1356 command.assign (command_string, 1, end_quote_pos - 1); 1357 if (end_quote_pos + 1 < command_string.size()) 1358 command_string.erase (0, command_string.find_first_not_of (k_white_space, end_quote_pos + 1)); 1359 else 1360 command_string.erase (); 1361 } 1362 } 1363 else 1364 { 1365 const size_t first_space_pos = command_string.find_first_of (k_white_space); 1366 if (first_space_pos == std::string::npos) 1367 { 1368 command.swap (command_string); 1369 command_string.erase(); 1370 } 1371 else 1372 { 1373 command.assign (command_string, 0, first_space_pos); 1374 command_string.erase(0, command_string.find_first_not_of (k_white_space, first_space_pos)); 1375 } 1376 } 1377 result = true; 1378 } 1379 1380 1381 if (!command.empty()) 1382 { 1383 // actual commands can't start with '-' or '_' 1384 if (command[0] != '-' && command[0] != '_') 1385 { 1386 size_t pos = command.find_first_not_of(k_valid_command_chars); 1387 if (pos > 0 && pos != std::string::npos) 1388 { 1389 suffix.assign (command.begin() + pos, command.end()); 1390 command.erase (pos); 1391 } 1392 } 1393 } 1394 1395 return result; 1396 } 1397 1398 CommandObject * 1399 CommandInterpreter::BuildAliasResult (const char *alias_name, 1400 std::string &raw_input_string, 1401 std::string &alias_result, 1402 CommandReturnObject &result) 1403 { 1404 CommandObject *alias_cmd_obj = nullptr; 1405 Args cmd_args (raw_input_string.c_str()); 1406 alias_cmd_obj = GetCommandObject (alias_name); 1407 StreamString result_str; 1408 1409 if (alias_cmd_obj) 1410 { 1411 std::string alias_name_str = alias_name; 1412 if ((cmd_args.GetArgumentCount() == 0) 1413 || (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0)) 1414 cmd_args.Unshift (alias_name); 1415 1416 result_str.Printf ("%s", alias_cmd_obj->GetCommandName ()); 1417 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); 1418 1419 if (option_arg_vector_sp.get()) 1420 { 1421 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 1422 1423 for (size_t i = 0; i < option_arg_vector->size(); ++i) 1424 { 1425 OptionArgPair option_pair = (*option_arg_vector)[i]; 1426 OptionArgValue value_pair = option_pair.second; 1427 int value_type = value_pair.first; 1428 std::string option = option_pair.first; 1429 std::string value = value_pair.second; 1430 if (option.compare ("<argument>") == 0) 1431 result_str.Printf (" %s", value.c_str()); 1432 else 1433 { 1434 result_str.Printf (" %s", option.c_str()); 1435 if (value_type != OptionParser::eOptionalArgument) 1436 result_str.Printf (" "); 1437 if (value.compare ("<OptionParser::eNoArgument>") != 0) 1438 { 1439 int index = GetOptionArgumentPosition (value.c_str()); 1440 if (index == 0) 1441 result_str.Printf ("%s", value.c_str()); 1442 else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount()) 1443 { 1444 1445 result.AppendErrorWithFormat 1446 ("Not enough arguments provided; you need at least %d arguments to use this alias.\n", 1447 index); 1448 result.SetStatus (eReturnStatusFailed); 1449 return alias_cmd_obj; 1450 } 1451 else 1452 { 1453 size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index)); 1454 if (strpos != std::string::npos) 1455 raw_input_string = raw_input_string.erase (strpos, 1456 strlen (cmd_args.GetArgumentAtIndex (index))); 1457 result_str.Printf ("%s", cmd_args.GetArgumentAtIndex (index)); 1458 } 1459 } 1460 } 1461 } 1462 } 1463 1464 alias_result = result_str.GetData(); 1465 } 1466 return alias_cmd_obj; 1467 } 1468 1469 Error 1470 CommandInterpreter::PreprocessCommand (std::string &command) 1471 { 1472 // The command preprocessor needs to do things to the command 1473 // line before any parsing of arguments or anything else is done. 1474 // The only current stuff that gets proprocessed is anyting enclosed 1475 // in backtick ('`') characters is evaluated as an expression and 1476 // the result of the expression must be a scalar that can be substituted 1477 // into the command. An example would be: 1478 // (lldb) memory read `$rsp + 20` 1479 Error error; // Error for any expressions that might not evaluate 1480 size_t start_backtick; 1481 size_t pos = 0; 1482 while ((start_backtick = command.find ('`', pos)) != std::string::npos) 1483 { 1484 if (start_backtick > 0 && command[start_backtick-1] == '\\') 1485 { 1486 // The backtick was preceeded by a '\' character, remove the slash 1487 // and don't treat the backtick as the start of an expression 1488 command.erase(start_backtick-1, 1); 1489 // No need to add one to start_backtick since we just deleted a char 1490 pos = start_backtick; 1491 } 1492 else 1493 { 1494 const size_t expr_content_start = start_backtick + 1; 1495 const size_t end_backtick = command.find ('`', expr_content_start); 1496 if (end_backtick == std::string::npos) 1497 return error; 1498 else if (end_backtick == expr_content_start) 1499 { 1500 // Empty expression (two backticks in a row) 1501 command.erase (start_backtick, 2); 1502 } 1503 else 1504 { 1505 std::string expr_str (command, expr_content_start, end_backtick - expr_content_start); 1506 1507 ExecutionContext exe_ctx(GetExecutionContext()); 1508 Target *target = exe_ctx.GetTargetPtr(); 1509 // Get a dummy target to allow for calculator mode while processing backticks. 1510 // This also helps break the infinite loop caused when target is null. 1511 if (!target) 1512 target = m_debugger.GetDummyTarget(); 1513 if (target) 1514 { 1515 ValueObjectSP expr_result_valobj_sp; 1516 1517 EvaluateExpressionOptions options; 1518 options.SetCoerceToId(false); 1519 options.SetUnwindOnError(true); 1520 options.SetIgnoreBreakpoints(true); 1521 options.SetKeepInMemory(false); 1522 options.SetTryAllThreads(true); 1523 options.SetTimeoutUsec(0); 1524 1525 ExpressionResults expr_result = target->EvaluateExpression (expr_str.c_str(), 1526 exe_ctx.GetFramePtr(), 1527 expr_result_valobj_sp, 1528 options); 1529 1530 if (expr_result == eExpressionCompleted) 1531 { 1532 Scalar scalar; 1533 if (expr_result_valobj_sp) 1534 expr_result_valobj_sp = expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable(expr_result_valobj_sp->GetDynamicValueType(), true); 1535 if (expr_result_valobj_sp->ResolveValue (scalar)) 1536 { 1537 command.erase (start_backtick, end_backtick - start_backtick + 1); 1538 StreamString value_strm; 1539 const bool show_type = false; 1540 scalar.GetValue (&value_strm, show_type); 1541 size_t value_string_size = value_strm.GetSize(); 1542 if (value_string_size) 1543 { 1544 command.insert (start_backtick, value_strm.GetData(), value_string_size); 1545 pos = start_backtick + value_string_size; 1546 continue; 1547 } 1548 else 1549 { 1550 error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str()); 1551 } 1552 } 1553 else 1554 { 1555 error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str()); 1556 } 1557 } 1558 else 1559 { 1560 if (expr_result_valobj_sp) 1561 error = expr_result_valobj_sp->GetError(); 1562 if (error.Success()) 1563 { 1564 1565 switch (expr_result) 1566 { 1567 case eExpressionSetupError: 1568 error.SetErrorStringWithFormat("expression setup error for the expression '%s'", expr_str.c_str()); 1569 break; 1570 case eExpressionParseError: 1571 error.SetErrorStringWithFormat ("expression parse error for the expression '%s'", expr_str.c_str()); 1572 break; 1573 case eExpressionResultUnavailable: 1574 error.SetErrorStringWithFormat ("expression error fetching result for the expression '%s'", expr_str.c_str()); 1575 case eExpressionCompleted: 1576 break; 1577 case eExpressionDiscarded: 1578 error.SetErrorStringWithFormat("expression discarded for the expression '%s'", expr_str.c_str()); 1579 break; 1580 case eExpressionInterrupted: 1581 error.SetErrorStringWithFormat("expression interrupted for the expression '%s'", expr_str.c_str()); 1582 break; 1583 case eExpressionHitBreakpoint: 1584 error.SetErrorStringWithFormat("expression hit breakpoint for the expression '%s'", expr_str.c_str()); 1585 break; 1586 case eExpressionTimedOut: 1587 error.SetErrorStringWithFormat("expression timed out for the expression '%s'", expr_str.c_str()); 1588 break; 1589 case eExpressionStoppedForDebug: 1590 error.SetErrorStringWithFormat("expression stop at entry point for debugging for the expression '%s'", expr_str.c_str()); 1591 break; 1592 } 1593 } 1594 } 1595 } 1596 } 1597 if (error.Fail()) 1598 break; 1599 } 1600 } 1601 return error; 1602 } 1603 1604 1605 bool 1606 CommandInterpreter::HandleCommand (const char *command_line, 1607 LazyBool lazy_add_to_history, 1608 CommandReturnObject &result, 1609 ExecutionContext *override_context, 1610 bool repeat_on_empty_command, 1611 bool no_context_switching) 1612 1613 { 1614 1615 bool done = false; 1616 CommandObject *cmd_obj = nullptr; 1617 bool wants_raw_input = false; 1618 std::string command_string (command_line); 1619 std::string original_command_string (command_line); 1620 1621 Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS)); 1622 Host::SetCrashDescriptionWithFormat ("HandleCommand(command = \"%s\")", command_line); 1623 1624 // Make a scoped cleanup object that will clear the crash description string 1625 // on exit of this function. 1626 lldb_utility::CleanUp <const char *> crash_description_cleanup(nullptr, Host::SetCrashDescription); 1627 1628 if (log) 1629 log->Printf ("Processing command: %s", command_line); 1630 1631 Timer scoped_timer (__PRETTY_FUNCTION__, "Handling command: %s.", command_line); 1632 1633 if (!no_context_switching) 1634 UpdateExecutionContext (override_context); 1635 1636 bool add_to_history; 1637 if (lazy_add_to_history == eLazyBoolCalculate) 1638 add_to_history = (m_command_source_depth == 0); 1639 else 1640 add_to_history = (lazy_add_to_history == eLazyBoolYes); 1641 1642 bool empty_command = false; 1643 bool comment_command = false; 1644 if (command_string.empty()) 1645 empty_command = true; 1646 else 1647 { 1648 const char *k_space_characters = "\t\n\v\f\r "; 1649 1650 size_t non_space = command_string.find_first_not_of (k_space_characters); 1651 // Check for empty line or comment line (lines whose first 1652 // non-space character is the comment character for this interpreter) 1653 if (non_space == std::string::npos) 1654 empty_command = true; 1655 else if (command_string[non_space] == m_comment_char) 1656 comment_command = true; 1657 else if (command_string[non_space] == CommandHistory::g_repeat_char) 1658 { 1659 const char *history_string = m_command_history.FindString(command_string.c_str() + non_space); 1660 if (history_string == nullptr) 1661 { 1662 result.AppendErrorWithFormat ("Could not find entry: %s in history", command_string.c_str()); 1663 result.SetStatus(eReturnStatusFailed); 1664 return false; 1665 } 1666 add_to_history = false; 1667 command_string = history_string; 1668 original_command_string = history_string; 1669 } 1670 } 1671 1672 if (empty_command) 1673 { 1674 if (repeat_on_empty_command) 1675 { 1676 if (m_command_history.IsEmpty()) 1677 { 1678 result.AppendError ("empty command"); 1679 result.SetStatus(eReturnStatusFailed); 1680 return false; 1681 } 1682 else 1683 { 1684 command_line = m_repeat_command.c_str(); 1685 command_string = command_line; 1686 original_command_string = command_line; 1687 if (m_repeat_command.empty()) 1688 { 1689 result.AppendErrorWithFormat("No auto repeat.\n"); 1690 result.SetStatus (eReturnStatusFailed); 1691 return false; 1692 } 1693 } 1694 add_to_history = false; 1695 } 1696 else 1697 { 1698 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1699 return true; 1700 } 1701 } 1702 else if (comment_command) 1703 { 1704 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1705 return true; 1706 } 1707 1708 1709 Error error (PreprocessCommand (command_string)); 1710 1711 if (error.Fail()) 1712 { 1713 result.AppendError (error.AsCString()); 1714 result.SetStatus(eReturnStatusFailed); 1715 return false; 1716 } 1717 // Phase 1. 1718 1719 // Before we do ANY kind of argument processing, etc. we need to figure out what the real/final command object 1720 // is for the specified command, and whether or not it wants raw input. This gets complicated by the fact that 1721 // the user could have specified an alias, and in translating the alias there may also be command options and/or 1722 // even data (including raw text strings) that need to be found and inserted into the command line as part of 1723 // the translation. So this first step is plain look-up & replacement, resulting in three things: 1). the command 1724 // object whose Execute method will actually be called; 2). a revised command string, with all substitutions & 1725 // replacements taken care of; 3). whether or not the Execute function wants raw input or not. 1726 1727 StreamString revised_command_line; 1728 size_t actual_cmd_name_len = 0; 1729 std::string next_word; 1730 StringList matches; 1731 while (!done) 1732 { 1733 char quote_char = '\0'; 1734 std::string suffix; 1735 ExtractCommand (command_string, next_word, suffix, quote_char); 1736 if (cmd_obj == nullptr) 1737 { 1738 std::string full_name; 1739 if (GetAliasFullName(next_word.c_str(), full_name)) 1740 { 1741 std::string alias_result; 1742 cmd_obj = BuildAliasResult (full_name.c_str(), command_string, alias_result, result); 1743 revised_command_line.Printf ("%s", alias_result.c_str()); 1744 if (cmd_obj) 1745 { 1746 wants_raw_input = cmd_obj->WantsRawCommandString (); 1747 actual_cmd_name_len = strlen (cmd_obj->GetCommandName()); 1748 } 1749 } 1750 else 1751 { 1752 cmd_obj = GetCommandObject (next_word.c_str(), &matches); 1753 if (cmd_obj) 1754 { 1755 actual_cmd_name_len += next_word.length(); 1756 revised_command_line.Printf ("%s", next_word.c_str()); 1757 wants_raw_input = cmd_obj->WantsRawCommandString (); 1758 } 1759 else 1760 { 1761 revised_command_line.Printf ("%s", next_word.c_str()); 1762 } 1763 } 1764 } 1765 else 1766 { 1767 if (cmd_obj->IsMultiwordObject ()) 1768 { 1769 CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (next_word.c_str()); 1770 if (sub_cmd_obj) 1771 { 1772 actual_cmd_name_len += next_word.length() + 1; 1773 revised_command_line.Printf (" %s", next_word.c_str()); 1774 cmd_obj = sub_cmd_obj; 1775 wants_raw_input = cmd_obj->WantsRawCommandString (); 1776 } 1777 else 1778 { 1779 if (quote_char) 1780 revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char); 1781 else 1782 revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str()); 1783 done = true; 1784 } 1785 } 1786 else 1787 { 1788 if (quote_char) 1789 revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char); 1790 else 1791 revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str()); 1792 done = true; 1793 } 1794 } 1795 1796 if (cmd_obj == nullptr) 1797 { 1798 const size_t num_matches = matches.GetSize(); 1799 if (matches.GetSize() > 1) { 1800 StreamString error_msg; 1801 error_msg.Printf ("Ambiguous command '%s'. Possible matches:\n", next_word.c_str()); 1802 1803 for (uint32_t i = 0; i < num_matches; ++i) { 1804 error_msg.Printf ("\t%s\n", matches.GetStringAtIndex(i)); 1805 } 1806 result.AppendRawError (error_msg.GetString().c_str()); 1807 } else { 1808 // We didn't have only one match, otherwise we wouldn't get here. 1809 assert(num_matches == 0); 1810 result.AppendErrorWithFormat ("'%s' is not a valid command.\n", next_word.c_str()); 1811 } 1812 result.SetStatus (eReturnStatusFailed); 1813 return false; 1814 } 1815 1816 if (cmd_obj->IsMultiwordObject ()) 1817 { 1818 if (!suffix.empty()) 1819 { 1820 1821 result.AppendErrorWithFormat ("command '%s' did not recognize '%s%s%s' as valid (subcommand might be invalid).\n", 1822 cmd_obj->GetCommandName(), 1823 next_word.empty() ? "" : next_word.c_str(), 1824 next_word.empty() ? " -- " : " ", 1825 suffix.c_str()); 1826 result.SetStatus (eReturnStatusFailed); 1827 return false; 1828 } 1829 } 1830 else 1831 { 1832 // If we found a normal command, we are done 1833 done = true; 1834 if (!suffix.empty()) 1835 { 1836 switch (suffix[0]) 1837 { 1838 case '/': 1839 // GDB format suffixes 1840 { 1841 Options *command_options = cmd_obj->GetOptions(); 1842 if (command_options && command_options->SupportsLongOption("gdb-format")) 1843 { 1844 std::string gdb_format_option ("--gdb-format="); 1845 gdb_format_option += (suffix.c_str() + 1); 1846 1847 bool inserted = false; 1848 std::string &cmd = revised_command_line.GetString(); 1849 size_t arg_terminator_idx = FindArgumentTerminator (cmd); 1850 if (arg_terminator_idx != std::string::npos) 1851 { 1852 // Insert the gdb format option before the "--" that terminates options 1853 gdb_format_option.append(1,' '); 1854 cmd.insert(arg_terminator_idx, gdb_format_option); 1855 inserted = true; 1856 } 1857 1858 if (!inserted) 1859 revised_command_line.Printf (" %s", gdb_format_option.c_str()); 1860 1861 if (wants_raw_input && FindArgumentTerminator(cmd) == std::string::npos) 1862 revised_command_line.PutCString (" --"); 1863 } 1864 else 1865 { 1866 result.AppendErrorWithFormat ("the '%s' command doesn't support the --gdb-format option\n", 1867 cmd_obj->GetCommandName()); 1868 result.SetStatus (eReturnStatusFailed); 1869 return false; 1870 } 1871 } 1872 break; 1873 1874 default: 1875 result.AppendErrorWithFormat ("unknown command shorthand suffix: '%s'\n", 1876 suffix.c_str()); 1877 result.SetStatus (eReturnStatusFailed); 1878 return false; 1879 1880 } 1881 } 1882 } 1883 if (command_string.length() == 0) 1884 done = true; 1885 1886 } 1887 1888 if (!command_string.empty()) 1889 revised_command_line.Printf (" %s", command_string.c_str()); 1890 1891 // End of Phase 1. 1892 // At this point cmd_obj should contain the CommandObject whose Execute method will be called, if the command 1893 // specified was valid; revised_command_line contains the complete command line (including command name(s)), 1894 // fully translated with all substitutions & translations taken care of (still in raw text format); and 1895 // wants_raw_input specifies whether the Execute method expects raw input or not. 1896 1897 1898 if (log) 1899 { 1900 log->Printf ("HandleCommand, cmd_obj : '%s'", cmd_obj ? cmd_obj->GetCommandName() : "<not found>"); 1901 log->Printf ("HandleCommand, revised_command_line: '%s'", revised_command_line.GetData()); 1902 log->Printf ("HandleCommand, wants_raw_input:'%s'", wants_raw_input ? "True" : "False"); 1903 } 1904 1905 // Phase 2. 1906 // Take care of things like setting up the history command & calling the appropriate Execute method on the 1907 // CommandObject, with the appropriate arguments. 1908 1909 if (cmd_obj != nullptr) 1910 { 1911 if (add_to_history) 1912 { 1913 Args command_args (revised_command_line.GetData()); 1914 const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0); 1915 if (repeat_command != nullptr) 1916 m_repeat_command.assign(repeat_command); 1917 else 1918 m_repeat_command.assign(original_command_string.c_str()); 1919 1920 m_command_history.AppendString (original_command_string); 1921 } 1922 1923 command_string = revised_command_line.GetData(); 1924 std::string command_name (cmd_obj->GetCommandName()); 1925 std::string remainder; 1926 if (actual_cmd_name_len < command_string.length()) 1927 remainder = command_string.substr (actual_cmd_name_len); // Note: 'actual_cmd_name_len' may be considerably shorter 1928 // than cmd_obj->GetCommandName(), because name completion 1929 // allows users to enter short versions of the names, 1930 // e.g. 'br s' for 'breakpoint set'. 1931 1932 // Remove any initial spaces 1933 std::string white_space (" \t\v"); 1934 size_t pos = remainder.find_first_not_of (white_space); 1935 if (pos != 0 && pos != std::string::npos) 1936 remainder.erase(0, pos); 1937 1938 if (log) 1939 log->Printf ("HandleCommand, command line after removing command name(s): '%s'", remainder.c_str()); 1940 1941 cmd_obj->Execute (remainder.c_str(), result); 1942 } 1943 else 1944 { 1945 // We didn't find the first command object, so complete the first argument. 1946 Args command_args (revised_command_line.GetData()); 1947 StringList matches; 1948 int num_matches; 1949 int cursor_index = 0; 1950 int cursor_char_position = strlen (command_args.GetArgumentAtIndex(0)); 1951 bool word_complete; 1952 num_matches = HandleCompletionMatches (command_args, 1953 cursor_index, 1954 cursor_char_position, 1955 0, 1956 -1, 1957 word_complete, 1958 matches); 1959 1960 if (num_matches > 0) 1961 { 1962 std::string error_msg; 1963 error_msg.assign ("ambiguous command '"); 1964 error_msg.append(command_args.GetArgumentAtIndex(0)); 1965 error_msg.append ("'."); 1966 1967 error_msg.append (" Possible completions:"); 1968 for (int i = 0; i < num_matches; i++) 1969 { 1970 error_msg.append ("\n\t"); 1971 error_msg.append (matches.GetStringAtIndex (i)); 1972 } 1973 error_msg.append ("\n"); 1974 result.AppendRawError (error_msg.c_str()); 1975 } 1976 else 1977 result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0)); 1978 1979 result.SetStatus (eReturnStatusFailed); 1980 } 1981 1982 if (log) 1983 log->Printf ("HandleCommand, command %s", (result.Succeeded() ? "succeeded" : "did not succeed")); 1984 1985 return result.Succeeded(); 1986 } 1987 1988 int 1989 CommandInterpreter::HandleCompletionMatches (Args &parsed_line, 1990 int &cursor_index, 1991 int &cursor_char_position, 1992 int match_start_point, 1993 int max_return_elements, 1994 bool &word_complete, 1995 StringList &matches) 1996 { 1997 int num_command_matches = 0; 1998 bool look_for_subcommand = false; 1999 2000 // For any of the command completions a unique match will be a complete word. 2001 word_complete = true; 2002 2003 if (cursor_index == -1) 2004 { 2005 // We got nothing on the command line, so return the list of commands 2006 bool include_aliases = true; 2007 num_command_matches = GetCommandNamesMatchingPartialString ("", include_aliases, matches); 2008 } 2009 else if (cursor_index == 0) 2010 { 2011 // The cursor is in the first argument, so just do a lookup in the dictionary. 2012 CommandObject *cmd_obj = GetCommandObject (parsed_line.GetArgumentAtIndex(0), &matches); 2013 num_command_matches = matches.GetSize(); 2014 2015 if (num_command_matches == 1 2016 && cmd_obj && cmd_obj->IsMultiwordObject() 2017 && matches.GetStringAtIndex(0) != nullptr 2018 && strcmp (parsed_line.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0) 2019 { 2020 if (parsed_line.GetArgumentCount() == 1) 2021 { 2022 word_complete = true; 2023 } 2024 else 2025 { 2026 look_for_subcommand = true; 2027 num_command_matches = 0; 2028 matches.DeleteStringAtIndex(0); 2029 parsed_line.AppendArgument (""); 2030 cursor_index++; 2031 cursor_char_position = 0; 2032 } 2033 } 2034 } 2035 2036 if (cursor_index > 0 || look_for_subcommand) 2037 { 2038 // We are completing further on into a commands arguments, so find the command and tell it 2039 // to complete the command. 2040 // First see if there is a matching initial command: 2041 CommandObject *command_object = GetCommandObject (parsed_line.GetArgumentAtIndex(0)); 2042 if (command_object == nullptr) 2043 { 2044 return 0; 2045 } 2046 else 2047 { 2048 parsed_line.Shift(); 2049 cursor_index--; 2050 num_command_matches = command_object->HandleCompletion (parsed_line, 2051 cursor_index, 2052 cursor_char_position, 2053 match_start_point, 2054 max_return_elements, 2055 word_complete, 2056 matches); 2057 } 2058 } 2059 2060 return num_command_matches; 2061 2062 } 2063 2064 int 2065 CommandInterpreter::HandleCompletion (const char *current_line, 2066 const char *cursor, 2067 const char *last_char, 2068 int match_start_point, 2069 int max_return_elements, 2070 StringList &matches) 2071 { 2072 // We parse the argument up to the cursor, so the last argument in parsed_line is 2073 // the one containing the cursor, and the cursor is after the last character. 2074 2075 Args parsed_line(current_line, last_char - current_line); 2076 Args partial_parsed_line(current_line, cursor - current_line); 2077 2078 // Don't complete comments, and if the line we are completing is just the history repeat character, 2079 // substitute the appropriate history line. 2080 const char *first_arg = parsed_line.GetArgumentAtIndex(0); 2081 if (first_arg) 2082 { 2083 if (first_arg[0] == m_comment_char) 2084 return 0; 2085 else if (first_arg[0] == CommandHistory::g_repeat_char) 2086 { 2087 const char *history_string = m_command_history.FindString (first_arg); 2088 if (history_string != nullptr) 2089 { 2090 matches.Clear(); 2091 matches.InsertStringAtIndex(0, history_string); 2092 return -2; 2093 } 2094 else 2095 return 0; 2096 2097 } 2098 } 2099 2100 2101 int num_args = partial_parsed_line.GetArgumentCount(); 2102 int cursor_index = partial_parsed_line.GetArgumentCount() - 1; 2103 int cursor_char_position; 2104 2105 if (cursor_index == -1) 2106 cursor_char_position = 0; 2107 else 2108 cursor_char_position = strlen (partial_parsed_line.GetArgumentAtIndex(cursor_index)); 2109 2110 if (cursor > current_line && cursor[-1] == ' ') 2111 { 2112 // We are just after a space. If we are in an argument, then we will continue 2113 // parsing, but if we are between arguments, then we have to complete whatever the next 2114 // element would be. 2115 // We can distinguish the two cases because if we are in an argument (e.g. because the space is 2116 // protected by a quote) then the space will also be in the parsed argument... 2117 2118 const char *current_elem = partial_parsed_line.GetArgumentAtIndex(cursor_index); 2119 if (cursor_char_position == 0 || current_elem[cursor_char_position - 1] != ' ') 2120 { 2121 parsed_line.InsertArgumentAtIndex(cursor_index + 1, "", '\0'); 2122 cursor_index++; 2123 cursor_char_position = 0; 2124 } 2125 } 2126 2127 int num_command_matches; 2128 2129 matches.Clear(); 2130 2131 // Only max_return_elements == -1 is supported at present: 2132 assert (max_return_elements == -1); 2133 bool word_complete; 2134 num_command_matches = HandleCompletionMatches (parsed_line, 2135 cursor_index, 2136 cursor_char_position, 2137 match_start_point, 2138 max_return_elements, 2139 word_complete, 2140 matches); 2141 2142 if (num_command_matches <= 0) 2143 return num_command_matches; 2144 2145 if (num_args == 0) 2146 { 2147 // If we got an empty string, insert nothing. 2148 matches.InsertStringAtIndex(0, ""); 2149 } 2150 else 2151 { 2152 // Now figure out if there is a common substring, and if so put that in element 0, otherwise 2153 // put an empty string in element 0. 2154 std::string command_partial_str; 2155 if (cursor_index >= 0) 2156 command_partial_str.assign(parsed_line.GetArgumentAtIndex(cursor_index), 2157 parsed_line.GetArgumentAtIndex(cursor_index) + cursor_char_position); 2158 2159 std::string common_prefix; 2160 matches.LongestCommonPrefix (common_prefix); 2161 const size_t partial_name_len = command_partial_str.size(); 2162 2163 // If we matched a unique single command, add a space... 2164 // Only do this if the completer told us this was a complete word, however... 2165 if (num_command_matches == 1 && word_complete) 2166 { 2167 char quote_char = parsed_line.GetArgumentQuoteCharAtIndex(cursor_index); 2168 if (quote_char != '\0') 2169 common_prefix.push_back(quote_char); 2170 2171 common_prefix.push_back(' '); 2172 } 2173 common_prefix.erase (0, partial_name_len); 2174 matches.InsertStringAtIndex(0, common_prefix.c_str()); 2175 } 2176 return num_command_matches; 2177 } 2178 2179 2180 CommandInterpreter::~CommandInterpreter () 2181 { 2182 } 2183 2184 void 2185 CommandInterpreter::UpdatePrompt (const char *new_prompt) 2186 { 2187 EventSP prompt_change_event_sp (new Event(eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));; 2188 BroadcastEvent (prompt_change_event_sp); 2189 if (m_command_io_handler_sp) 2190 m_command_io_handler_sp->SetPrompt(new_prompt); 2191 } 2192 2193 2194 bool 2195 CommandInterpreter::Confirm (const char *message, bool default_answer) 2196 { 2197 // Check AutoConfirm first: 2198 if (m_debugger.GetAutoConfirm()) 2199 return default_answer; 2200 2201 IOHandlerConfirm *confirm = new IOHandlerConfirm(m_debugger, 2202 message, 2203 default_answer); 2204 IOHandlerSP io_handler_sp (confirm); 2205 m_debugger.RunIOHandler (io_handler_sp); 2206 return confirm->GetResponse(); 2207 } 2208 2209 OptionArgVectorSP 2210 CommandInterpreter::GetAliasOptions (const char *alias_name) 2211 { 2212 OptionArgMap::iterator pos; 2213 OptionArgVectorSP ret_val; 2214 2215 std::string alias (alias_name); 2216 2217 if (HasAliasOptions()) 2218 { 2219 pos = m_alias_options.find (alias); 2220 if (pos != m_alias_options.end()) 2221 ret_val = pos->second; 2222 } 2223 2224 return ret_val; 2225 } 2226 2227 void 2228 CommandInterpreter::RemoveAliasOptions (const char *alias_name) 2229 { 2230 OptionArgMap::iterator pos = m_alias_options.find(alias_name); 2231 if (pos != m_alias_options.end()) 2232 { 2233 m_alias_options.erase (pos); 2234 } 2235 } 2236 2237 void 2238 CommandInterpreter::AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp) 2239 { 2240 m_alias_options[alias_name] = option_arg_vector_sp; 2241 } 2242 2243 bool 2244 CommandInterpreter::HasCommands () 2245 { 2246 return (!m_command_dict.empty()); 2247 } 2248 2249 bool 2250 CommandInterpreter::HasAliases () 2251 { 2252 return (!m_alias_dict.empty()); 2253 } 2254 2255 bool 2256 CommandInterpreter::HasUserCommands () 2257 { 2258 return (!m_user_dict.empty()); 2259 } 2260 2261 bool 2262 CommandInterpreter::HasAliasOptions () 2263 { 2264 return (!m_alias_options.empty()); 2265 } 2266 2267 void 2268 CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj, 2269 const char *alias_name, 2270 Args &cmd_args, 2271 std::string &raw_input_string, 2272 CommandReturnObject &result) 2273 { 2274 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); 2275 2276 bool wants_raw_input = alias_cmd_obj->WantsRawCommandString(); 2277 2278 // Make sure that the alias name is the 0th element in cmd_args 2279 std::string alias_name_str = alias_name; 2280 if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0) 2281 cmd_args.Unshift (alias_name); 2282 2283 Args new_args (alias_cmd_obj->GetCommandName()); 2284 if (new_args.GetArgumentCount() == 2) 2285 new_args.Shift(); 2286 2287 if (option_arg_vector_sp.get()) 2288 { 2289 if (wants_raw_input) 2290 { 2291 // We have a command that both has command options and takes raw input. Make *sure* it has a 2292 // " -- " in the right place in the raw_input_string. 2293 size_t pos = raw_input_string.find(" -- "); 2294 if (pos == std::string::npos) 2295 { 2296 // None found; assume it goes at the beginning of the raw input string 2297 raw_input_string.insert (0, " -- "); 2298 } 2299 } 2300 2301 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 2302 const size_t old_size = cmd_args.GetArgumentCount(); 2303 std::vector<bool> used (old_size + 1, false); 2304 2305 used[0] = true; 2306 2307 for (size_t i = 0; i < option_arg_vector->size(); ++i) 2308 { 2309 OptionArgPair option_pair = (*option_arg_vector)[i]; 2310 OptionArgValue value_pair = option_pair.second; 2311 int value_type = value_pair.first; 2312 std::string option = option_pair.first; 2313 std::string value = value_pair.second; 2314 if (option.compare ("<argument>") == 0) 2315 { 2316 if (!wants_raw_input 2317 || (value.compare("--") != 0)) // Since we inserted this above, make sure we don't insert it twice 2318 new_args.AppendArgument (value.c_str()); 2319 } 2320 else 2321 { 2322 if (value_type != OptionParser::eOptionalArgument) 2323 new_args.AppendArgument (option.c_str()); 2324 if (value.compare ("<no-argument>") != 0) 2325 { 2326 int index = GetOptionArgumentPosition (value.c_str()); 2327 if (index == 0) 2328 { 2329 // value was NOT a positional argument; must be a real value 2330 if (value_type != OptionParser::eOptionalArgument) 2331 new_args.AppendArgument (value.c_str()); 2332 else 2333 { 2334 char buffer[255]; 2335 ::snprintf (buffer, sizeof (buffer), "%s%s", option.c_str(), value.c_str()); 2336 new_args.AppendArgument (buffer); 2337 } 2338 2339 } 2340 else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount()) 2341 { 2342 result.AppendErrorWithFormat 2343 ("Not enough arguments provided; you need at least %d arguments to use this alias.\n", 2344 index); 2345 result.SetStatus (eReturnStatusFailed); 2346 return; 2347 } 2348 else 2349 { 2350 // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string 2351 size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index)); 2352 if (strpos != std::string::npos) 2353 { 2354 raw_input_string = raw_input_string.erase (strpos, strlen (cmd_args.GetArgumentAtIndex (index))); 2355 } 2356 2357 if (value_type != OptionParser::eOptionalArgument) 2358 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index)); 2359 else 2360 { 2361 char buffer[255]; 2362 ::snprintf (buffer, sizeof(buffer), "%s%s", option.c_str(), 2363 cmd_args.GetArgumentAtIndex (index)); 2364 new_args.AppendArgument (buffer); 2365 } 2366 used[index] = true; 2367 } 2368 } 2369 } 2370 } 2371 2372 for (size_t j = 0; j < cmd_args.GetArgumentCount(); ++j) 2373 { 2374 if (!used[j] && !wants_raw_input) 2375 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (j)); 2376 } 2377 2378 cmd_args.Clear(); 2379 cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector()); 2380 } 2381 else 2382 { 2383 result.SetStatus (eReturnStatusSuccessFinishNoResult); 2384 // This alias was not created with any options; nothing further needs to be done, unless it is a command that 2385 // wants raw input, in which case we need to clear the rest of the data from cmd_args, since its in the raw 2386 // input string. 2387 if (wants_raw_input) 2388 { 2389 cmd_args.Clear(); 2390 cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector()); 2391 } 2392 return; 2393 } 2394 2395 result.SetStatus (eReturnStatusSuccessFinishNoResult); 2396 return; 2397 } 2398 2399 2400 int 2401 CommandInterpreter::GetOptionArgumentPosition (const char *in_string) 2402 { 2403 int position = 0; // Any string that isn't an argument position, i.e. '%' followed by an integer, gets a position 2404 // of zero. 2405 2406 char *cptr = (char *) in_string; 2407 2408 // Does it start with '%' 2409 if (cptr[0] == '%') 2410 { 2411 ++cptr; 2412 2413 // Is the rest of it entirely digits? 2414 if (isdigit (cptr[0])) 2415 { 2416 const char *start = cptr; 2417 while (isdigit (cptr[0])) 2418 ++cptr; 2419 2420 // We've gotten to the end of the digits; are we at the end of the string? 2421 if (cptr[0] == '\0') 2422 position = atoi (start); 2423 } 2424 } 2425 2426 return position; 2427 } 2428 2429 void 2430 CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result) 2431 { 2432 FileSpec init_file; 2433 if (in_cwd) 2434 { 2435 // In the current working directory we don't load any program specific 2436 // .lldbinit files, we only look for a "./.lldbinit" file. 2437 if (m_skip_lldbinit_files) 2438 return; 2439 2440 init_file.SetFile ("./.lldbinit", true); 2441 } 2442 else 2443 { 2444 // If we aren't looking in the current working directory we are looking 2445 // in the home directory. We will first see if there is an application 2446 // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a 2447 // "-" and the name of the program. If this file doesn't exist, we fall 2448 // back to just the "~/.lldbinit" file. We also obey any requests to not 2449 // load the init files. 2450 llvm::SmallString<64> home_dir_path; 2451 llvm::sys::path::home_directory(home_dir_path); 2452 FileSpec profilePath(home_dir_path.c_str(), false); 2453 profilePath.AppendPathComponent(".lldbinit"); 2454 std::string init_file_path = profilePath.GetPath(); 2455 2456 if (m_skip_app_init_files == false) 2457 { 2458 FileSpec program_file_spec(HostInfo::GetProgramFileSpec()); 2459 const char *program_name = program_file_spec.GetFilename().AsCString(); 2460 2461 if (program_name) 2462 { 2463 char program_init_file_name[PATH_MAX]; 2464 ::snprintf (program_init_file_name, sizeof(program_init_file_name), "%s-%s", init_file_path.c_str(), program_name); 2465 init_file.SetFile (program_init_file_name, true); 2466 if (!init_file.Exists()) 2467 init_file.Clear(); 2468 } 2469 } 2470 2471 if (!init_file && !m_skip_lldbinit_files) 2472 init_file.SetFile (init_file_path.c_str(), false); 2473 } 2474 2475 // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting 2476 // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details). 2477 2478 if (init_file.Exists()) 2479 { 2480 const bool saved_batch = SetBatchCommandMode (true); 2481 CommandInterpreterRunOptions options; 2482 options.SetSilent (true); 2483 options.SetStopOnError (false); 2484 options.SetStopOnContinue (true); 2485 2486 HandleCommandsFromFile (init_file, 2487 nullptr, // Execution context 2488 options, 2489 result); 2490 SetBatchCommandMode (saved_batch); 2491 } 2492 else 2493 { 2494 // nothing to be done if the file doesn't exist 2495 result.SetStatus(eReturnStatusSuccessFinishNoResult); 2496 } 2497 } 2498 2499 PlatformSP 2500 CommandInterpreter::GetPlatform (bool prefer_target_platform) 2501 { 2502 PlatformSP platform_sp; 2503 if (prefer_target_platform) 2504 { 2505 ExecutionContext exe_ctx(GetExecutionContext()); 2506 Target *target = exe_ctx.GetTargetPtr(); 2507 if (target) 2508 platform_sp = target->GetPlatform(); 2509 } 2510 2511 if (!platform_sp) 2512 platform_sp = m_debugger.GetPlatformList().GetSelectedPlatform(); 2513 return platform_sp; 2514 } 2515 2516 void 2517 CommandInterpreter::HandleCommands (const StringList &commands, 2518 ExecutionContext *override_context, 2519 CommandInterpreterRunOptions &options, 2520 CommandReturnObject &result) 2521 { 2522 size_t num_lines = commands.GetSize(); 2523 2524 // If we are going to continue past a "continue" then we need to run the commands synchronously. 2525 // Make sure you reset this value anywhere you return from the function. 2526 2527 bool old_async_execution = m_debugger.GetAsyncExecution(); 2528 2529 // If we've been given an execution context, set it at the start, but don't keep resetting it or we will 2530 // cause series of commands that change the context, then do an operation that relies on that context to fail. 2531 2532 if (override_context != nullptr) 2533 UpdateExecutionContext (override_context); 2534 2535 if (!options.GetStopOnContinue()) 2536 { 2537 m_debugger.SetAsyncExecution (false); 2538 } 2539 2540 for (size_t idx = 0; idx < num_lines; idx++) 2541 { 2542 const char *cmd = commands.GetStringAtIndex(idx); 2543 if (cmd[0] == '\0') 2544 continue; 2545 2546 if (options.GetEchoCommands()) 2547 { 2548 result.AppendMessageWithFormat ("%s %s\n", 2549 m_debugger.GetPrompt(), 2550 cmd); 2551 } 2552 2553 CommandReturnObject tmp_result; 2554 // If override_context is not NULL, pass no_context_switching = true for 2555 // HandleCommand() since we updated our context already. 2556 2557 // We might call into a regex or alias command, in which case the add_to_history will get lost. This 2558 // m_command_source_depth dingus is the way we turn off adding to the history in that case, so set it up here. 2559 if (!options.GetAddToHistory()) 2560 m_command_source_depth++; 2561 bool success = HandleCommand(cmd, options.m_add_to_history, tmp_result, 2562 nullptr, /* override_context */ 2563 true, /* repeat_on_empty_command */ 2564 override_context != nullptr /* no_context_switching */); 2565 if (!options.GetAddToHistory()) 2566 m_command_source_depth--; 2567 2568 if (options.GetPrintResults()) 2569 { 2570 if (tmp_result.Succeeded()) 2571 result.AppendMessageWithFormat("%s", tmp_result.GetOutputData()); 2572 } 2573 2574 if (!success || !tmp_result.Succeeded()) 2575 { 2576 const char *error_msg = tmp_result.GetErrorData(); 2577 if (error_msg == nullptr || error_msg[0] == '\0') 2578 error_msg = "<unknown error>.\n"; 2579 if (options.GetStopOnError()) 2580 { 2581 result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' failed with %s", 2582 (uint64_t)idx, cmd, error_msg); 2583 result.SetStatus (eReturnStatusFailed); 2584 m_debugger.SetAsyncExecution (old_async_execution); 2585 return; 2586 } 2587 else if (options.GetPrintResults()) 2588 { 2589 result.AppendMessageWithFormat ("Command #%" PRIu64 " '%s' failed with %s", 2590 (uint64_t)idx + 1, 2591 cmd, 2592 error_msg); 2593 } 2594 } 2595 2596 if (result.GetImmediateOutputStream()) 2597 result.GetImmediateOutputStream()->Flush(); 2598 2599 if (result.GetImmediateErrorStream()) 2600 result.GetImmediateErrorStream()->Flush(); 2601 2602 // N.B. Can't depend on DidChangeProcessState, because the state coming into the command execution 2603 // could be running (for instance in Breakpoint Commands. 2604 // So we check the return value to see if it is has running in it. 2605 if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult) 2606 || (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult)) 2607 { 2608 if (options.GetStopOnContinue()) 2609 { 2610 // If we caused the target to proceed, and we're going to stop in that case, set the 2611 // status in our real result before returning. This is an error if the continue was not the 2612 // last command in the set of commands to be run. 2613 if (idx != num_lines - 1) 2614 result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' continued the target.\n", 2615 (uint64_t)idx + 1, cmd); 2616 else 2617 result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' continued the target.\n", (uint64_t)idx + 1, cmd); 2618 2619 result.SetStatus(tmp_result.GetStatus()); 2620 m_debugger.SetAsyncExecution (old_async_execution); 2621 2622 return; 2623 } 2624 } 2625 2626 // Also check for "stop on crash here: 2627 bool should_stop = false; 2628 if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash()) 2629 { 2630 TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget()); 2631 if (target_sp) 2632 { 2633 ProcessSP process_sp (target_sp->GetProcessSP()); 2634 if (process_sp) 2635 { 2636 for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) 2637 { 2638 StopReason reason = thread_sp->GetStopReason(); 2639 if (reason == eStopReasonSignal || reason == eStopReasonException || reason == eStopReasonInstrumentation) 2640 { 2641 should_stop = true; 2642 break; 2643 } 2644 } 2645 } 2646 } 2647 if (should_stop) 2648 { 2649 if (idx != num_lines - 1) 2650 result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' stopped with a signal or exception.\n", 2651 (uint64_t)idx + 1, cmd); 2652 else 2653 result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' stopped with a signal or exception.\n", (uint64_t)idx + 1, cmd); 2654 2655 result.SetStatus(tmp_result.GetStatus()); 2656 m_debugger.SetAsyncExecution (old_async_execution); 2657 2658 return; 2659 } 2660 } 2661 2662 } 2663 2664 result.SetStatus (eReturnStatusSuccessFinishResult); 2665 m_debugger.SetAsyncExecution (old_async_execution); 2666 2667 return; 2668 } 2669 2670 // Make flags that we can pass into the IOHandler so our delegates can do the right thing 2671 enum { 2672 eHandleCommandFlagStopOnContinue = (1u << 0), 2673 eHandleCommandFlagStopOnError = (1u << 1), 2674 eHandleCommandFlagEchoCommand = (1u << 2), 2675 eHandleCommandFlagPrintResult = (1u << 3), 2676 eHandleCommandFlagStopOnCrash = (1u << 4) 2677 }; 2678 2679 void 2680 CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file, 2681 ExecutionContext *context, 2682 CommandInterpreterRunOptions &options, 2683 CommandReturnObject &result) 2684 { 2685 if (cmd_file.Exists()) 2686 { 2687 StreamFileSP input_file_sp (new StreamFile()); 2688 2689 std::string cmd_file_path = cmd_file.GetPath(); 2690 Error error = input_file_sp->GetFile().Open(cmd_file_path.c_str(), File::eOpenOptionRead); 2691 2692 if (error.Success()) 2693 { 2694 Debugger &debugger = GetDebugger(); 2695 2696 uint32_t flags = 0; 2697 2698 if (options.m_stop_on_continue == eLazyBoolCalculate) 2699 { 2700 if (m_command_source_flags.empty()) 2701 { 2702 // Stop on continue by default 2703 flags |= eHandleCommandFlagStopOnContinue; 2704 } 2705 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnContinue) 2706 { 2707 flags |= eHandleCommandFlagStopOnContinue; 2708 } 2709 } 2710 else if (options.m_stop_on_continue == eLazyBoolYes) 2711 { 2712 flags |= eHandleCommandFlagStopOnContinue; 2713 } 2714 2715 if (options.m_stop_on_error == eLazyBoolCalculate) 2716 { 2717 if (m_command_source_flags.empty()) 2718 { 2719 if (GetStopCmdSourceOnError()) 2720 flags |= eHandleCommandFlagStopOnError; 2721 } 2722 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnError) 2723 { 2724 flags |= eHandleCommandFlagStopOnError; 2725 } 2726 } 2727 else if (options.m_stop_on_error == eLazyBoolYes) 2728 { 2729 flags |= eHandleCommandFlagStopOnError; 2730 } 2731 2732 if (options.GetStopOnCrash()) 2733 { 2734 if (m_command_source_flags.empty()) 2735 { 2736 // Echo command by default 2737 flags |= eHandleCommandFlagStopOnCrash; 2738 } 2739 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnCrash) 2740 { 2741 flags |= eHandleCommandFlagStopOnCrash; 2742 } 2743 } 2744 2745 if (options.m_echo_commands == eLazyBoolCalculate) 2746 { 2747 if (m_command_source_flags.empty()) 2748 { 2749 // Echo command by default 2750 flags |= eHandleCommandFlagEchoCommand; 2751 } 2752 else if (m_command_source_flags.back() & eHandleCommandFlagEchoCommand) 2753 { 2754 flags |= eHandleCommandFlagEchoCommand; 2755 } 2756 } 2757 else if (options.m_echo_commands == eLazyBoolYes) 2758 { 2759 flags |= eHandleCommandFlagEchoCommand; 2760 } 2761 2762 if (options.m_print_results == eLazyBoolCalculate) 2763 { 2764 if (m_command_source_flags.empty()) 2765 { 2766 // Print output by default 2767 flags |= eHandleCommandFlagPrintResult; 2768 } 2769 else if (m_command_source_flags.back() & eHandleCommandFlagPrintResult) 2770 { 2771 flags |= eHandleCommandFlagPrintResult; 2772 } 2773 } 2774 else if (options.m_print_results == eLazyBoolYes) 2775 { 2776 flags |= eHandleCommandFlagPrintResult; 2777 } 2778 2779 if (flags & eHandleCommandFlagPrintResult) 2780 { 2781 debugger.GetOutputFile()->Printf("Executing commands in '%s'.\n", cmd_file_path.c_str()); 2782 } 2783 2784 // Used for inheriting the right settings when "command source" might have 2785 // nested "command source" commands 2786 lldb::StreamFileSP empty_stream_sp; 2787 m_command_source_flags.push_back(flags); 2788 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, 2789 IOHandler::Type::CommandInterpreter, 2790 input_file_sp, 2791 empty_stream_sp, // Pass in an empty stream so we inherit the top input reader output stream 2792 empty_stream_sp, // Pass in an empty stream so we inherit the top input reader error stream 2793 flags, 2794 nullptr, // Pass in NULL for "editline_name" so no history is saved, or written 2795 debugger.GetPrompt(), 2796 NULL, 2797 false, // Not multi-line 2798 debugger.GetUseColor(), 2799 0, 2800 *this)); 2801 const bool old_async_execution = debugger.GetAsyncExecution(); 2802 2803 // Set synchronous execution if we are not stopping on continue 2804 if ((flags & eHandleCommandFlagStopOnContinue) == 0) 2805 debugger.SetAsyncExecution (false); 2806 2807 m_command_source_depth++; 2808 2809 debugger.RunIOHandler(io_handler_sp); 2810 if (!m_command_source_flags.empty()) 2811 m_command_source_flags.pop_back(); 2812 m_command_source_depth--; 2813 result.SetStatus (eReturnStatusSuccessFinishNoResult); 2814 debugger.SetAsyncExecution (old_async_execution); 2815 } 2816 else 2817 { 2818 result.AppendErrorWithFormat ("error: an error occurred read file '%s': %s\n", cmd_file_path.c_str(), error.AsCString()); 2819 result.SetStatus (eReturnStatusFailed); 2820 } 2821 2822 2823 } 2824 else 2825 { 2826 result.AppendErrorWithFormat ("Error reading commands from file %s - file not found.\n", 2827 cmd_file.GetFilename().AsCString("<Unknown>")); 2828 result.SetStatus (eReturnStatusFailed); 2829 return; 2830 } 2831 } 2832 2833 ScriptInterpreter * 2834 CommandInterpreter::GetScriptInterpreter (bool can_create) 2835 { 2836 if (m_script_interpreter_ap.get() != nullptr) 2837 return m_script_interpreter_ap.get(); 2838 2839 if (!can_create) 2840 return nullptr; 2841 2842 // <rdar://problem/11751427> 2843 // we need to protect the initialization of the script interpreter 2844 // otherwise we could end up with two threads both trying to create 2845 // their instance of it, and for some languages (e.g. Python) 2846 // this is a bulletproof recipe for disaster! 2847 // this needs to be a function-level static because multiple Debugger instances living in the same process 2848 // still need to be isolated and not try to initialize Python concurrently 2849 static Mutex g_interpreter_mutex(Mutex::eMutexTypeRecursive); 2850 Mutex::Locker interpreter_lock(g_interpreter_mutex); 2851 2852 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 2853 if (log) 2854 log->Printf("Initializing the ScriptInterpreter now\n"); 2855 2856 lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage(); 2857 switch (script_lang) 2858 { 2859 case eScriptLanguagePython: 2860 #ifndef LLDB_DISABLE_PYTHON 2861 m_script_interpreter_ap.reset (new ScriptInterpreterPython (*this)); 2862 break; 2863 #else 2864 // Fall through to the None case when python is disabled 2865 #endif 2866 case eScriptLanguageNone: 2867 m_script_interpreter_ap.reset (new ScriptInterpreterNone (*this)); 2868 break; 2869 }; 2870 2871 return m_script_interpreter_ap.get(); 2872 } 2873 2874 2875 2876 bool 2877 CommandInterpreter::GetSynchronous () 2878 { 2879 return m_synchronous_execution; 2880 } 2881 2882 void 2883 CommandInterpreter::SetSynchronous (bool value) 2884 { 2885 m_synchronous_execution = value; 2886 } 2887 2888 void 2889 CommandInterpreter::OutputFormattedHelpText (Stream &strm, 2890 const char *word_text, 2891 const char *separator, 2892 const char *help_text, 2893 size_t max_word_len) 2894 { 2895 const uint32_t max_columns = m_debugger.GetTerminalWidth(); 2896 2897 int indent_size = max_word_len + strlen (separator) + 2; 2898 2899 strm.IndentMore (indent_size); 2900 2901 StreamString text_strm; 2902 text_strm.Printf ("%-*s %s %s", (int)max_word_len, word_text, separator, help_text); 2903 2904 size_t len = text_strm.GetSize(); 2905 const char *text = text_strm.GetData(); 2906 if (text[len - 1] == '\n') 2907 { 2908 text_strm.EOL(); 2909 len = text_strm.GetSize(); 2910 } 2911 2912 if (len < max_columns) 2913 { 2914 // Output it as a single line. 2915 strm.Printf ("%s", text); 2916 } 2917 else 2918 { 2919 // We need to break it up into multiple lines. 2920 bool first_line = true; 2921 int text_width; 2922 size_t start = 0; 2923 size_t end = start; 2924 const size_t final_end = strlen (text); 2925 2926 while (end < final_end) 2927 { 2928 if (first_line) 2929 text_width = max_columns - 1; 2930 else 2931 text_width = max_columns - indent_size - 1; 2932 2933 // Don't start the 'text' on a space, since we're already outputting the indentation. 2934 if (!first_line) 2935 { 2936 while ((start < final_end) && (text[start] == ' ')) 2937 start++; 2938 } 2939 2940 end = start + text_width; 2941 if (end > final_end) 2942 end = final_end; 2943 else 2944 { 2945 // If we're not at the end of the text, make sure we break the line on white space. 2946 while (end > start 2947 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n') 2948 end--; 2949 assert (end > 0); 2950 } 2951 2952 const size_t sub_len = end - start; 2953 if (start != 0) 2954 strm.EOL(); 2955 if (!first_line) 2956 strm.Indent(); 2957 else 2958 first_line = false; 2959 assert (start <= final_end); 2960 assert (start + sub_len <= final_end); 2961 if (sub_len > 0) 2962 strm.Write (text + start, sub_len); 2963 start = end + 1; 2964 } 2965 } 2966 strm.EOL(); 2967 strm.IndentLess(indent_size); 2968 } 2969 2970 void 2971 CommandInterpreter::OutputHelpText (Stream &strm, 2972 const char *word_text, 2973 const char *separator, 2974 const char *help_text, 2975 uint32_t max_word_len) 2976 { 2977 int indent_size = max_word_len + strlen (separator) + 2; 2978 2979 strm.IndentMore (indent_size); 2980 2981 StreamString text_strm; 2982 text_strm.Printf ("%-*s %s %s", max_word_len, word_text, separator, help_text); 2983 2984 const uint32_t max_columns = m_debugger.GetTerminalWidth(); 2985 2986 size_t len = text_strm.GetSize(); 2987 const char *text = text_strm.GetData(); 2988 2989 uint32_t chars_left = max_columns; 2990 2991 for (uint32_t i = 0; i < len; i++) 2992 { 2993 if ((text[i] == ' ' && ::strchr((text+i+1), ' ') && chars_left < ::strchr((text+i+1), ' ')-(text+i)) || text[i] == '\n') 2994 { 2995 chars_left = max_columns - indent_size; 2996 strm.EOL(); 2997 strm.Indent(); 2998 } 2999 else 3000 { 3001 strm.PutChar(text[i]); 3002 chars_left--; 3003 } 3004 3005 } 3006 3007 strm.EOL(); 3008 strm.IndentLess(indent_size); 3009 } 3010 3011 void 3012 CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found, 3013 StringList &commands_help, bool search_builtin_commands, bool search_user_commands) 3014 { 3015 CommandObject::CommandMap::const_iterator pos; 3016 3017 if (search_builtin_commands) 3018 { 3019 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) 3020 { 3021 const char *command_name = pos->first.c_str(); 3022 CommandObject *cmd_obj = pos->second.get(); 3023 3024 if (cmd_obj->HelpTextContainsWord (search_word)) 3025 { 3026 commands_found.AppendString (command_name); 3027 commands_help.AppendString (cmd_obj->GetHelp()); 3028 } 3029 3030 if (cmd_obj->IsMultiwordObject()) 3031 cmd_obj->AproposAllSubCommands (command_name, 3032 search_word, 3033 commands_found, 3034 commands_help); 3035 3036 } 3037 } 3038 3039 if (search_user_commands) 3040 { 3041 for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos) 3042 { 3043 const char *command_name = pos->first.c_str(); 3044 CommandObject *cmd_obj = pos->second.get(); 3045 3046 if (cmd_obj->HelpTextContainsWord (search_word)) 3047 { 3048 commands_found.AppendString (command_name); 3049 commands_help.AppendString (cmd_obj->GetHelp()); 3050 } 3051 3052 if (cmd_obj->IsMultiwordObject()) 3053 cmd_obj->AproposAllSubCommands (command_name, 3054 search_word, 3055 commands_found, 3056 commands_help); 3057 3058 } 3059 } 3060 } 3061 3062 void 3063 CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context) 3064 { 3065 if (override_context != nullptr) 3066 { 3067 m_exe_ctx_ref = *override_context; 3068 } 3069 else 3070 { 3071 const bool adopt_selected = true; 3072 m_exe_ctx_ref.SetTargetPtr (m_debugger.GetSelectedTarget().get(), adopt_selected); 3073 } 3074 } 3075 3076 3077 size_t 3078 CommandInterpreter::GetProcessOutput () 3079 { 3080 // The process has stuff waiting for stderr; get it and write it out to the appropriate place. 3081 char stdio_buffer[1024]; 3082 size_t len; 3083 size_t total_bytes = 0; 3084 Error error; 3085 TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget()); 3086 if (target_sp) 3087 { 3088 ProcessSP process_sp (target_sp->GetProcessSP()); 3089 if (process_sp) 3090 { 3091 while ((len = process_sp->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 3092 { 3093 size_t bytes_written = len; 3094 m_debugger.GetOutputFile()->Write (stdio_buffer, bytes_written); 3095 total_bytes += len; 3096 } 3097 while ((len = process_sp->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0) 3098 { 3099 size_t bytes_written = len; 3100 m_debugger.GetErrorFile()->Write (stdio_buffer, bytes_written); 3101 total_bytes += len; 3102 } 3103 } 3104 } 3105 return total_bytes; 3106 } 3107 3108 void 3109 CommandInterpreter::IOHandlerInputComplete (IOHandler &io_handler, std::string &line) 3110 { 3111 const bool is_interactive = io_handler.GetIsInteractive(); 3112 if (is_interactive == false) 3113 { 3114 // When we are not interactive, don't execute blank lines. This will happen 3115 // sourcing a commands file. We don't want blank lines to repeat the previous 3116 // command and cause any errors to occur (like redefining an alias, get an error 3117 // and stop parsing the commands file). 3118 if (line.empty()) 3119 return; 3120 3121 // When using a non-interactive file handle (like when sourcing commands from a file) 3122 // we need to echo the command out so we don't just see the command output and no 3123 // command... 3124 if (io_handler.GetFlags().Test(eHandleCommandFlagEchoCommand)) 3125 io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(), line.c_str()); 3126 } 3127 3128 lldb_private::CommandReturnObject result; 3129 HandleCommand(line.c_str(), eLazyBoolCalculate, result); 3130 3131 // Now emit the command output text from the command we just executed 3132 if (io_handler.GetFlags().Test(eHandleCommandFlagPrintResult)) 3133 { 3134 // Display any STDOUT/STDERR _prior_ to emitting the command result text 3135 GetProcessOutput (); 3136 3137 if (!result.GetImmediateOutputStream()) 3138 { 3139 const char *output = result.GetOutputData(); 3140 if (output && output[0]) 3141 io_handler.GetOutputStreamFile()->PutCString(output); 3142 } 3143 3144 // Now emit the command error text from the command we just executed 3145 if (!result.GetImmediateErrorStream()) 3146 { 3147 const char *error = result.GetErrorData(); 3148 if (error && error[0]) 3149 io_handler.GetErrorStreamFile()->PutCString(error); 3150 } 3151 } 3152 3153 switch (result.GetStatus()) 3154 { 3155 case eReturnStatusInvalid: 3156 case eReturnStatusSuccessFinishNoResult: 3157 case eReturnStatusSuccessFinishResult: 3158 case eReturnStatusStarted: 3159 break; 3160 3161 case eReturnStatusSuccessContinuingNoResult: 3162 case eReturnStatusSuccessContinuingResult: 3163 if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnContinue)) 3164 io_handler.SetIsDone(true); 3165 break; 3166 3167 case eReturnStatusFailed: 3168 m_num_errors++; 3169 if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError)) 3170 io_handler.SetIsDone(true); 3171 break; 3172 3173 case eReturnStatusQuit: 3174 m_quit_requested = true; 3175 io_handler.SetIsDone(true); 3176 break; 3177 } 3178 3179 // Finally, if we're going to stop on crash, check that here: 3180 if (!m_quit_requested 3181 && result.GetDidChangeProcessState() 3182 && io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash)) 3183 { 3184 bool should_stop = false; 3185 TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget()); 3186 if (target_sp) 3187 { 3188 ProcessSP process_sp (target_sp->GetProcessSP()); 3189 if (process_sp) 3190 { 3191 for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) 3192 { 3193 StopReason reason = thread_sp->GetStopReason(); 3194 if (reason == eStopReasonSignal || reason == eStopReasonException || reason == eStopReasonInstrumentation) 3195 { 3196 should_stop = true; 3197 break; 3198 } 3199 } 3200 } 3201 } 3202 if (should_stop) 3203 { 3204 io_handler.SetIsDone(true); 3205 m_stopped_for_crash = true; 3206 } 3207 } 3208 } 3209 3210 bool 3211 CommandInterpreter::IOHandlerInterrupt (IOHandler &io_handler) 3212 { 3213 ExecutionContext exe_ctx (GetExecutionContext()); 3214 Process *process = exe_ctx.GetProcessPtr(); 3215 3216 if (process) 3217 { 3218 StateType state = process->GetState(); 3219 if (StateIsRunningState(state)) 3220 { 3221 process->Halt(); 3222 return true; // Don't do any updating when we are running 3223 } 3224 } 3225 return false; 3226 } 3227 3228 void 3229 CommandInterpreter::GetLLDBCommandsFromIOHandler (const char *prompt, 3230 IOHandlerDelegate &delegate, 3231 bool asynchronously, 3232 void *baton) 3233 { 3234 Debugger &debugger = GetDebugger(); 3235 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, 3236 IOHandler::Type::CommandList, 3237 "lldb", // Name of input reader for history 3238 prompt, // Prompt 3239 NULL, // Continuation prompt 3240 true, // Get multiple lines 3241 debugger.GetUseColor(), 3242 0, // Don't show line numbers 3243 delegate)); // IOHandlerDelegate 3244 3245 if (io_handler_sp) 3246 { 3247 io_handler_sp->SetUserData (baton); 3248 if (asynchronously) 3249 debugger.PushIOHandler(io_handler_sp); 3250 else 3251 debugger.RunIOHandler(io_handler_sp); 3252 } 3253 3254 } 3255 3256 3257 void 3258 CommandInterpreter::GetPythonCommandsFromIOHandler (const char *prompt, 3259 IOHandlerDelegate &delegate, 3260 bool asynchronously, 3261 void *baton) 3262 { 3263 Debugger &debugger = GetDebugger(); 3264 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, 3265 IOHandler::Type::PythonCode, 3266 "lldb-python", // Name of input reader for history 3267 prompt, // Prompt 3268 NULL, // Continuation prompt 3269 true, // Get multiple lines 3270 debugger.GetUseColor(), 3271 0, // Don't show line numbers 3272 delegate)); // IOHandlerDelegate 3273 3274 if (io_handler_sp) 3275 { 3276 io_handler_sp->SetUserData (baton); 3277 if (asynchronously) 3278 debugger.PushIOHandler(io_handler_sp); 3279 else 3280 debugger.RunIOHandler(io_handler_sp); 3281 } 3282 3283 } 3284 3285 bool 3286 CommandInterpreter::IsActive () 3287 { 3288 return m_debugger.IsTopIOHandler (m_command_io_handler_sp); 3289 } 3290 3291 lldb::IOHandlerSP 3292 CommandInterpreter::GetIOHandler(bool force_create, CommandInterpreterRunOptions *options) 3293 { 3294 // Always re-create the IOHandlerEditline in case the input 3295 // changed. The old instance might have had a non-interactive 3296 // input and now it does or vice versa. 3297 if (force_create || !m_command_io_handler_sp) 3298 { 3299 // Always re-create the IOHandlerEditline in case the input 3300 // changed. The old instance might have had a non-interactive 3301 // input and now it does or vice versa. 3302 uint32_t flags = 0; 3303 3304 if (options) 3305 { 3306 if (options->m_stop_on_continue == eLazyBoolYes) 3307 flags |= eHandleCommandFlagStopOnContinue; 3308 if (options->m_stop_on_error == eLazyBoolYes) 3309 flags |= eHandleCommandFlagStopOnError; 3310 if (options->m_stop_on_crash == eLazyBoolYes) 3311 flags |= eHandleCommandFlagStopOnCrash; 3312 if (options->m_echo_commands != eLazyBoolNo) 3313 flags |= eHandleCommandFlagEchoCommand; 3314 if (options->m_print_results != eLazyBoolNo) 3315 flags |= eHandleCommandFlagPrintResult; 3316 } 3317 else 3318 { 3319 flags = eHandleCommandFlagEchoCommand | eHandleCommandFlagPrintResult; 3320 } 3321 3322 m_command_io_handler_sp.reset(new IOHandlerEditline (m_debugger, 3323 IOHandler::Type::CommandInterpreter, 3324 m_debugger.GetInputFile(), 3325 m_debugger.GetOutputFile(), 3326 m_debugger.GetErrorFile(), 3327 flags, 3328 "lldb", 3329 m_debugger.GetPrompt(), 3330 NULL, // Continuation prompt 3331 false, // Don't enable multiple line input, just single line commands 3332 m_debugger.GetUseColor(), 3333 0, // Don't show line numbers 3334 *this)); 3335 } 3336 return m_command_io_handler_sp; 3337 } 3338 3339 void 3340 CommandInterpreter::RunCommandInterpreter(bool auto_handle_events, 3341 bool spawn_thread, 3342 CommandInterpreterRunOptions &options) 3343 { 3344 // Always re-create the command intepreter when we run it in case 3345 // any file handles have changed. 3346 bool force_create = true; 3347 m_debugger.PushIOHandler(GetIOHandler(force_create, &options)); 3348 m_stopped_for_crash = false; 3349 3350 if (auto_handle_events) 3351 m_debugger.StartEventHandlerThread(); 3352 3353 if (spawn_thread) 3354 { 3355 m_debugger.StartIOHandlerThread(); 3356 } 3357 else 3358 { 3359 m_debugger.ExecuteIOHanders(); 3360 3361 if (auto_handle_events) 3362 m_debugger.StopEventHandlerThread(); 3363 } 3364 3365 } 3366 3367