130fdc8d8SChris Lattner //===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner #include "CommandObjectProcess.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1640af72e1SJim Ingham #include "lldb/Interpreter/Args.h" 1740af72e1SJim Ingham #include "lldb/Interpreter/Options.h" 1830fdc8d8SChris Lattner #include "lldb/Core/State.h" 1930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 2030fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 21e996fd30SGreg Clayton #include "CommandObjectThread.h" 227fb56d0aSGreg Clayton #include "lldb/Host/Host.h" 23e996fd30SGreg Clayton #include "lldb/Target/Platform.h" 2430fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2530fdc8d8SChris Lattner #include "lldb/Target/Target.h" 2630fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 2730fdc8d8SChris Lattner 2830fdc8d8SChris Lattner using namespace lldb; 2930fdc8d8SChris Lattner using namespace lldb_private; 3030fdc8d8SChris Lattner 3130fdc8d8SChris Lattner //------------------------------------------------------------------------- 3230fdc8d8SChris Lattner // CommandObjectProcessLaunch 3330fdc8d8SChris Lattner //------------------------------------------------------------------------- 34bb9caf73SJim Ingham #pragma mark CommandObjectProjectLaunch 3530fdc8d8SChris Lattner class CommandObjectProcessLaunch : public CommandObject 3630fdc8d8SChris Lattner { 3730fdc8d8SChris Lattner public: 3830fdc8d8SChris Lattner 3930fdc8d8SChris Lattner class CommandOptions : public Options 4030fdc8d8SChris Lattner { 4130fdc8d8SChris Lattner public: 4230fdc8d8SChris Lattner 43*eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 44*eb0103f2SGreg Clayton Options(interpreter) 4530fdc8d8SChris Lattner { 4630fdc8d8SChris Lattner // Keep default values of all options in one place: ResetOptionValues () 4730fdc8d8SChris Lattner ResetOptionValues (); 4830fdc8d8SChris Lattner } 4930fdc8d8SChris Lattner 5030fdc8d8SChris Lattner ~CommandOptions () 5130fdc8d8SChris Lattner { 5230fdc8d8SChris Lattner } 5330fdc8d8SChris Lattner 5430fdc8d8SChris Lattner Error 5530fdc8d8SChris Lattner SetOptionValue (int option_idx, const char *option_arg) 5630fdc8d8SChris Lattner { 5730fdc8d8SChris Lattner Error error; 5830fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 5930fdc8d8SChris Lattner 6030fdc8d8SChris Lattner switch (short_option) 6130fdc8d8SChris Lattner { 6230fdc8d8SChris Lattner case 's': stop_at_entry = true; break; 63bd82a5d2SGreg Clayton case 'e': stderr_path.assign (option_arg); break; 64bd82a5d2SGreg Clayton case 'i': stdin_path.assign (option_arg); break; 65bd82a5d2SGreg Clayton case 'o': stdout_path.assign (option_arg); break; 66bd82a5d2SGreg Clayton case 'p': plugin_name.assign (option_arg); break; 67f8da8631SCaroline Tice case 'n': no_stdio = true; break; 68bd82a5d2SGreg Clayton case 'w': working_dir.assign (option_arg); break; 69913c4fa1SGreg Clayton case 't': 70913c4fa1SGreg Clayton if (option_arg && option_arg[0]) 71913c4fa1SGreg Clayton tty_name.assign (option_arg); 72913c4fa1SGreg Clayton in_new_tty = true; 73913c4fa1SGreg Clayton break; 7430fdc8d8SChris Lattner default: 7530fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 7630fdc8d8SChris Lattner break; 7730fdc8d8SChris Lattner 7830fdc8d8SChris Lattner } 7930fdc8d8SChris Lattner return error; 8030fdc8d8SChris Lattner } 8130fdc8d8SChris Lattner 8230fdc8d8SChris Lattner void 8330fdc8d8SChris Lattner ResetOptionValues () 8430fdc8d8SChris Lattner { 8530fdc8d8SChris Lattner stop_at_entry = false; 8619388cfcSGreg Clayton in_new_tty = false; 87913c4fa1SGreg Clayton tty_name.clear(); 8830fdc8d8SChris Lattner stdin_path.clear(); 8930fdc8d8SChris Lattner stdout_path.clear(); 9030fdc8d8SChris Lattner stderr_path.clear(); 9130fdc8d8SChris Lattner plugin_name.clear(); 92bd82a5d2SGreg Clayton working_dir.clear(); 93f8da8631SCaroline Tice no_stdio = false; 9430fdc8d8SChris Lattner } 9530fdc8d8SChris Lattner 96e0d378b3SGreg Clayton const OptionDefinition* 9730fdc8d8SChris Lattner GetDefinitions () 9830fdc8d8SChris Lattner { 9930fdc8d8SChris Lattner return g_option_table; 10030fdc8d8SChris Lattner } 10130fdc8d8SChris Lattner 10230fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 10330fdc8d8SChris Lattner 104e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 10530fdc8d8SChris Lattner 10630fdc8d8SChris Lattner // Instance variables to hold the values for command options. 10730fdc8d8SChris Lattner 10830fdc8d8SChris Lattner bool stop_at_entry; 10919388cfcSGreg Clayton bool in_new_tty; 110f8da8631SCaroline Tice bool no_stdio; 111913c4fa1SGreg Clayton std::string tty_name; 11230fdc8d8SChris Lattner std::string stderr_path; 11330fdc8d8SChris Lattner std::string stdin_path; 11430fdc8d8SChris Lattner std::string stdout_path; 11530fdc8d8SChris Lattner std::string plugin_name; 116bd82a5d2SGreg Clayton std::string working_dir; 11730fdc8d8SChris Lattner 11830fdc8d8SChris Lattner }; 11930fdc8d8SChris Lattner 120a7015092SGreg Clayton CommandObjectProcessLaunch (CommandInterpreter &interpreter) : 121a7015092SGreg Clayton CommandObject (interpreter, 122a7015092SGreg Clayton "process launch", 123e3d26315SCaroline Tice "Launch the executable in the debugger.", 124*eb0103f2SGreg Clayton NULL), 125*eb0103f2SGreg Clayton m_options (interpreter) 12630fdc8d8SChris Lattner { 127405fe67fSCaroline Tice CommandArgumentEntry arg; 128405fe67fSCaroline Tice CommandArgumentData run_args_arg; 129405fe67fSCaroline Tice 130405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 131405fe67fSCaroline Tice run_args_arg.arg_type = eArgTypeRunArgs; 132405fe67fSCaroline Tice run_args_arg.arg_repetition = eArgRepeatOptional; 133405fe67fSCaroline Tice 134405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 135405fe67fSCaroline Tice arg.push_back (run_args_arg); 136405fe67fSCaroline Tice 137405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 138405fe67fSCaroline Tice m_arguments.push_back (arg); 13930fdc8d8SChris Lattner } 14030fdc8d8SChris Lattner 14130fdc8d8SChris Lattner 14230fdc8d8SChris Lattner ~CommandObjectProcessLaunch () 14330fdc8d8SChris Lattner { 14430fdc8d8SChris Lattner } 14530fdc8d8SChris Lattner 14630fdc8d8SChris Lattner Options * 14730fdc8d8SChris Lattner GetOptions () 14830fdc8d8SChris Lattner { 14930fdc8d8SChris Lattner return &m_options; 15030fdc8d8SChris Lattner } 15130fdc8d8SChris Lattner 15230fdc8d8SChris Lattner bool 15305faeb71SGreg Clayton Execute (Args& launch_args, CommandReturnObject &result) 15430fdc8d8SChris Lattner { 155a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 15630fdc8d8SChris Lattner 15730fdc8d8SChris Lattner if (target == NULL) 15830fdc8d8SChris Lattner { 15930fdc8d8SChris Lattner result.AppendError ("invalid target, set executable file using 'file' command"); 16030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 16130fdc8d8SChris Lattner return false; 16230fdc8d8SChris Lattner } 16330fdc8d8SChris Lattner 16430fdc8d8SChris Lattner // If our listener is NULL, users aren't allows to launch 16530fdc8d8SChris Lattner char filename[PATH_MAX]; 16619388cfcSGreg Clayton const Module *exe_module = target->GetExecutableModule().get(); 16771337622SGreg Clayton 16871337622SGreg Clayton if (exe_module == NULL) 16971337622SGreg Clayton { 17071337622SGreg Clayton result.AppendError ("no file in target, set executable file using 'file' command"); 17171337622SGreg Clayton result.SetStatus (eReturnStatusFailed); 17271337622SGreg Clayton return false; 17371337622SGreg Clayton } 17471337622SGreg Clayton 17530fdc8d8SChris Lattner exe_module->GetFileSpec().GetPath(filename, sizeof(filename)); 17630fdc8d8SChris Lattner 17771337622SGreg Clayton StateType state = eStateInvalid; 178a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 17971337622SGreg Clayton if (process) 18071337622SGreg Clayton { 18171337622SGreg Clayton state = process->GetState(); 18271337622SGreg Clayton 18371337622SGreg Clayton if (process->IsAlive() && state != eStateConnected) 18430fdc8d8SChris Lattner { 185513c26ceSGreg Clayton char message[1024]; 186513c26ceSGreg Clayton if (process->GetState() == eStateAttaching) 187513c26ceSGreg Clayton ::strncpy (message, "There is a pending attach, abort it and launch a new process?", sizeof(message)); 188513c26ceSGreg Clayton else 189513c26ceSGreg Clayton ::strncpy (message, "There is a running process, kill it and restart?", sizeof(message)); 190513c26ceSGreg Clayton 191513c26ceSGreg Clayton if (!m_interpreter.Confirm (message, true)) 192bb9caf73SJim Ingham { 19330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 19430fdc8d8SChris Lattner return false; 19530fdc8d8SChris Lattner } 196bb9caf73SJim Ingham else 197bb9caf73SJim Ingham { 198bb9caf73SJim Ingham Error error (process->Destroy()); 199bb9caf73SJim Ingham if (error.Success()) 200bb9caf73SJim Ingham { 201bb9caf73SJim Ingham result.SetStatus (eReturnStatusSuccessFinishResult); 202bb9caf73SJim Ingham } 203bb9caf73SJim Ingham else 204bb9caf73SJim Ingham { 205bb9caf73SJim Ingham result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 206bb9caf73SJim Ingham result.SetStatus (eReturnStatusFailed); 207bb9caf73SJim Ingham } 208bb9caf73SJim Ingham } 209bb9caf73SJim Ingham } 21071337622SGreg Clayton } 21130fdc8d8SChris Lattner 21271337622SGreg Clayton if (state != eStateConnected) 21371337622SGreg Clayton { 21430fdc8d8SChris Lattner const char *plugin_name; 21530fdc8d8SChris Lattner if (!m_options.plugin_name.empty()) 21630fdc8d8SChris Lattner plugin_name = m_options.plugin_name.c_str(); 21730fdc8d8SChris Lattner else 21830fdc8d8SChris Lattner plugin_name = NULL; 21930fdc8d8SChris Lattner 220a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 221a7015092SGreg Clayton if (process == NULL) 2223df9a8dfSCaroline Tice { 22343a8c39bSCaroline Tice result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n"); 224a7015092SGreg Clayton result.SetStatus (eReturnStatusFailed); 225a7015092SGreg Clayton return false; 2263df9a8dfSCaroline Tice } 22771337622SGreg Clayton } 22871337622SGreg Clayton 2293df9a8dfSCaroline Tice 230a7015092SGreg Clayton // If no launch args were given on the command line, then use any that 231a7015092SGreg Clayton // might have been set using the "run-args" set variable. 23230fdc8d8SChris Lattner if (launch_args.GetArgumentCount() == 0) 23330fdc8d8SChris Lattner { 234a7015092SGreg Clayton if (process->GetRunArguments().GetArgumentCount() > 0) 235a7015092SGreg Clayton launch_args = process->GetRunArguments(); 23630fdc8d8SChris Lattner } 23730fdc8d8SChris Lattner 23819388cfcSGreg Clayton if (m_options.in_new_tty) 23919388cfcSGreg Clayton { 24071337622SGreg Clayton if (state == eStateConnected) 24171337622SGreg Clayton { 24271337622SGreg Clayton result.AppendWarning("launch in tty option is ignored when launching through a remote connection"); 24371337622SGreg Clayton m_options.in_new_tty = false; 24471337622SGreg Clayton } 24571337622SGreg Clayton else 24671337622SGreg Clayton { 24719388cfcSGreg Clayton char exec_file_path[PATH_MAX]; 24819388cfcSGreg Clayton if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path))) 24919388cfcSGreg Clayton { 25019388cfcSGreg Clayton launch_args.InsertArgumentAtIndex(0, exec_file_path); 25119388cfcSGreg Clayton } 25219388cfcSGreg Clayton else 25319388cfcSGreg Clayton { 25419388cfcSGreg Clayton result.AppendError("invalid executable"); 25519388cfcSGreg Clayton result.SetStatus (eReturnStatusFailed); 25619388cfcSGreg Clayton return false; 25719388cfcSGreg Clayton } 25819388cfcSGreg Clayton } 25971337622SGreg Clayton } 26019388cfcSGreg Clayton 261a7015092SGreg Clayton Args environment; 26230fdc8d8SChris Lattner 263a7015092SGreg Clayton process->GetEnvironmentAsArgs (environment); 264a7015092SGreg Clayton 265a7015092SGreg Clayton uint32_t launch_flags = eLaunchFlagNone; 266a7015092SGreg Clayton 267a7015092SGreg Clayton if (process->GetDisableASLR()) 268a7015092SGreg Clayton launch_flags |= eLaunchFlagDisableASLR; 269a7015092SGreg Clayton 270f8da8631SCaroline Tice if (m_options.no_stdio) 271f8da8631SCaroline Tice launch_flags |= eLaunchFlagDisableSTDIO; 272f8da8631SCaroline Tice else if (!m_options.in_new_tty 273f8da8631SCaroline Tice && m_options.stdin_path.empty() 274f8da8631SCaroline Tice && m_options.stdout_path.empty() 275f8da8631SCaroline Tice && m_options.stderr_path.empty()) 276f8da8631SCaroline Tice { 277f8da8631SCaroline Tice // Only use the settings value if the user hasn't specified any options that would override it. 278f8da8631SCaroline Tice if (process->GetDisableSTDIO()) 279f8da8631SCaroline Tice launch_flags |= eLaunchFlagDisableSTDIO; 280f8da8631SCaroline Tice } 281f8da8631SCaroline Tice 28219388cfcSGreg Clayton const char **inferior_argv = launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL; 28319388cfcSGreg Clayton const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL; 28430fdc8d8SChris Lattner 28519388cfcSGreg Clayton Error error; 286bd82a5d2SGreg Clayton const char *working_dir = NULL; 287bd82a5d2SGreg Clayton if (!m_options.working_dir.empty()) 288bd82a5d2SGreg Clayton working_dir = m_options.working_dir.c_str(); 28919388cfcSGreg Clayton 29019388cfcSGreg Clayton if (m_options.in_new_tty) 29119388cfcSGreg Clayton { 29219388cfcSGreg Clayton 293913c4fa1SGreg Clayton lldb::pid_t pid = Host::LaunchInNewTerminal (m_options.tty_name.c_str(), 294913c4fa1SGreg Clayton inferior_argv, 29519388cfcSGreg Clayton inferior_envp, 296bd82a5d2SGreg Clayton working_dir, 29719388cfcSGreg Clayton &exe_module->GetArchitecture(), 29819388cfcSGreg Clayton true, 29919388cfcSGreg Clayton process->GetDisableASLR()); 30019388cfcSGreg Clayton 3013fcbed6bSGreg Clayton if (pid != LLDB_INVALID_PROCESS_ID) 3023fcbed6bSGreg Clayton error = process->Attach (pid); 30319388cfcSGreg Clayton } 30419388cfcSGreg Clayton else 30519388cfcSGreg Clayton { 30630fdc8d8SChris Lattner const char * stdin_path = NULL; 30730fdc8d8SChris Lattner const char * stdout_path = NULL; 30830fdc8d8SChris Lattner const char * stderr_path = NULL; 30930fdc8d8SChris Lattner 310a7015092SGreg Clayton // Were any standard input/output/error paths given on the command line? 311a7015092SGreg Clayton if (m_options.stdin_path.empty() && 31230fdc8d8SChris Lattner m_options.stdout_path.empty() && 313a7015092SGreg Clayton m_options.stderr_path.empty()) 31430fdc8d8SChris Lattner { 315a7015092SGreg Clayton // No standard file handles were given on the command line, check 316a7015092SGreg Clayton // with the process object in case they were give using "set settings" 317a7015092SGreg Clayton stdin_path = process->GetStandardInputPath(); 318a7015092SGreg Clayton stdout_path = process->GetStandardOutputPath(); 319a7015092SGreg Clayton stderr_path = process->GetStandardErrorPath(); 320a7015092SGreg Clayton } 321a7015092SGreg Clayton else 322a7015092SGreg Clayton { 323a7015092SGreg Clayton stdin_path = m_options.stdin_path.empty() ? NULL : m_options.stdin_path.c_str(); 324a7015092SGreg Clayton stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str(); 325a7015092SGreg Clayton stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str(); 32630fdc8d8SChris Lattner } 32730fdc8d8SChris Lattner 32819388cfcSGreg Clayton error = process->Launch (inferior_argv, 32919388cfcSGreg Clayton inferior_envp, 330f681b94fSGreg Clayton launch_flags, 33130fdc8d8SChris Lattner stdin_path, 33230fdc8d8SChris Lattner stdout_path, 333bd82a5d2SGreg Clayton stderr_path, 334bd82a5d2SGreg Clayton working_dir); 33519388cfcSGreg Clayton } 33630fdc8d8SChris Lattner 33730fdc8d8SChris Lattner if (error.Success()) 33830fdc8d8SChris Lattner { 33964195a2cSGreg Clayton const char *archname = exe_module->GetArchitecture().GetArchitectureName(); 34019388cfcSGreg Clayton 34119388cfcSGreg Clayton result.AppendMessageWithFormat ("Process %i launched: '%s' (%s)\n", process->GetID(), filename, archname); 34205faeb71SGreg Clayton result.SetDidChangeProcessState (true); 34330fdc8d8SChris Lattner if (m_options.stop_at_entry == false) 34430fdc8d8SChris Lattner { 34505faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 34630fdc8d8SChris Lattner StateType state = process->WaitForProcessToStop (NULL); 34730fdc8d8SChris Lattner 34830fdc8d8SChris Lattner if (state == eStateStopped) 34930fdc8d8SChris Lattner { 35005faeb71SGreg Clayton error = process->Resume(); 35105faeb71SGreg Clayton if (error.Success()) 35205faeb71SGreg Clayton { 35305faeb71SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 35430fdc8d8SChris Lattner if (synchronous_execution) 35530fdc8d8SChris Lattner { 35605faeb71SGreg Clayton state = process->WaitForProcessToStop (NULL); 35764195a2cSGreg Clayton if (!StateIsStoppedState(state)) 358514487e8SGreg Clayton { 359514487e8SGreg Clayton result.AppendErrorWithFormat ("Process isn't stopped: %s", StateAsCString(state)); 360514487e8SGreg Clayton } 36130fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 36205faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 36305faeb71SGreg Clayton } 36405faeb71SGreg Clayton else 36505faeb71SGreg Clayton { 36605faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 36705faeb71SGreg Clayton } 36805faeb71SGreg Clayton } 369514487e8SGreg Clayton else 370514487e8SGreg Clayton { 371514487e8SGreg Clayton result.AppendErrorWithFormat ("Process resume at entry point failed: %s", error.AsCString()); 372514487e8SGreg Clayton result.SetStatus (eReturnStatusFailed); 37330fdc8d8SChris Lattner } 37430fdc8d8SChris Lattner } 375514487e8SGreg Clayton else 376514487e8SGreg Clayton { 377514487e8SGreg Clayton result.AppendErrorWithFormat ("Initial process state wasn't stopped: %s", StateAsCString(state)); 378514487e8SGreg Clayton result.SetStatus (eReturnStatusFailed); 379514487e8SGreg Clayton } 380514487e8SGreg Clayton } 381514487e8SGreg Clayton } 382514487e8SGreg Clayton else 383514487e8SGreg Clayton { 384514487e8SGreg Clayton result.AppendErrorWithFormat ("Process launch failed: %s", error.AsCString()); 385514487e8SGreg Clayton result.SetStatus (eReturnStatusFailed); 38630fdc8d8SChris Lattner } 38730fdc8d8SChris Lattner 38830fdc8d8SChris Lattner return result.Succeeded(); 38930fdc8d8SChris Lattner } 39030fdc8d8SChris Lattner 391ebc09c36SJim Ingham virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 392ebc09c36SJim Ingham { 393ebc09c36SJim Ingham // No repeat for "process launch"... 394ebc09c36SJim Ingham return ""; 395ebc09c36SJim Ingham } 396ebc09c36SJim Ingham 39730fdc8d8SChris Lattner protected: 39830fdc8d8SChris Lattner 39930fdc8d8SChris Lattner CommandOptions m_options; 40030fdc8d8SChris Lattner }; 40130fdc8d8SChris Lattner 40230fdc8d8SChris Lattner 40319388cfcSGreg Clayton #define SET1 LLDB_OPT_SET_1 40419388cfcSGreg Clayton #define SET2 LLDB_OPT_SET_2 405f8da8631SCaroline Tice #define SET3 LLDB_OPT_SET_3 40619388cfcSGreg Clayton 407e0d378b3SGreg Clayton OptionDefinition 40830fdc8d8SChris Lattner CommandObjectProcessLaunch::CommandOptions::g_option_table[] = 40930fdc8d8SChris Lattner { 410f8da8631SCaroline Tice { SET1 | SET2 | SET3, false, "stop-at-entry", 's', no_argument, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."}, 41119388cfcSGreg Clayton { SET1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."}, 41219388cfcSGreg Clayton { SET1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."}, 41319388cfcSGreg Clayton { SET1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypePath, "Redirect stderr for the process to <path>."}, 414f8da8631SCaroline Tice { SET1 | SET2 | SET3, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 415913c4fa1SGreg Clayton { SET2 , false, "tty", 't', optional_argument, NULL, 0, eArgTypePath, "Start the process in a terminal. If <path> is specified, look for a terminal whose name contains <path>, else start the process in a new terminal."}, 416f8da8631SCaroline Tice { SET3, false, "no-stdio", 'n', no_argument, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."}, 417bd82a5d2SGreg Clayton { SET1 | SET2 | SET3, false, "working-dir", 'w', required_argument, NULL, 0, eArgTypePath, "Set the current working directory to <path> when running the inferior."}, 418deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 41930fdc8d8SChris Lattner }; 42030fdc8d8SChris Lattner 42119388cfcSGreg Clayton #undef SET1 42219388cfcSGreg Clayton #undef SET2 423f8da8631SCaroline Tice #undef SET3 42430fdc8d8SChris Lattner 42530fdc8d8SChris Lattner //------------------------------------------------------------------------- 42630fdc8d8SChris Lattner // CommandObjectProcessAttach 42730fdc8d8SChris Lattner //------------------------------------------------------------------------- 428bb9caf73SJim Ingham #pragma mark CommandObjectProcessAttach 42930fdc8d8SChris Lattner class CommandObjectProcessAttach : public CommandObject 43030fdc8d8SChris Lattner { 43130fdc8d8SChris Lattner public: 43230fdc8d8SChris Lattner 43330fdc8d8SChris Lattner class CommandOptions : public Options 43430fdc8d8SChris Lattner { 43530fdc8d8SChris Lattner public: 43630fdc8d8SChris Lattner 437*eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 438*eb0103f2SGreg Clayton Options(interpreter) 43930fdc8d8SChris Lattner { 44030fdc8d8SChris Lattner // Keep default values of all options in one place: ResetOptionValues () 44130fdc8d8SChris Lattner ResetOptionValues (); 44230fdc8d8SChris Lattner } 44330fdc8d8SChris Lattner 44430fdc8d8SChris Lattner ~CommandOptions () 44530fdc8d8SChris Lattner { 44630fdc8d8SChris Lattner } 44730fdc8d8SChris Lattner 44830fdc8d8SChris Lattner Error 44930fdc8d8SChris Lattner SetOptionValue (int option_idx, const char *option_arg) 45030fdc8d8SChris Lattner { 45130fdc8d8SChris Lattner Error error; 45230fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 45330fdc8d8SChris Lattner bool success = false; 45430fdc8d8SChris Lattner switch (short_option) 45530fdc8d8SChris Lattner { 45630fdc8d8SChris Lattner case 'p': 45730fdc8d8SChris Lattner pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); 45830fdc8d8SChris Lattner if (!success || pid == LLDB_INVALID_PROCESS_ID) 45930fdc8d8SChris Lattner { 46030fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg); 46130fdc8d8SChris Lattner } 46230fdc8d8SChris Lattner break; 46330fdc8d8SChris Lattner 46430fdc8d8SChris Lattner case 'P': 46530fdc8d8SChris Lattner plugin_name = option_arg; 46630fdc8d8SChris Lattner break; 46730fdc8d8SChris Lattner 46830fdc8d8SChris Lattner case 'n': 46930fdc8d8SChris Lattner name.assign(option_arg); 47030fdc8d8SChris Lattner break; 47130fdc8d8SChris Lattner 47230fdc8d8SChris Lattner case 'w': 47330fdc8d8SChris Lattner waitfor = true; 47430fdc8d8SChris Lattner break; 47530fdc8d8SChris Lattner 47630fdc8d8SChris Lattner default: 47730fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 47830fdc8d8SChris Lattner break; 47930fdc8d8SChris Lattner } 48030fdc8d8SChris Lattner return error; 48130fdc8d8SChris Lattner } 48230fdc8d8SChris Lattner 48330fdc8d8SChris Lattner void 48430fdc8d8SChris Lattner ResetOptionValues () 48530fdc8d8SChris Lattner { 48630fdc8d8SChris Lattner pid = LLDB_INVALID_PROCESS_ID; 48730fdc8d8SChris Lattner name.clear(); 48830fdc8d8SChris Lattner waitfor = false; 48930fdc8d8SChris Lattner } 49030fdc8d8SChris Lattner 491e0d378b3SGreg Clayton const OptionDefinition* 49230fdc8d8SChris Lattner GetDefinitions () 49330fdc8d8SChris Lattner { 49430fdc8d8SChris Lattner return g_option_table; 49530fdc8d8SChris Lattner } 49630fdc8d8SChris Lattner 4975aee162fSJim Ingham virtual bool 498*eb0103f2SGreg Clayton HandleOptionArgumentCompletion (Args &input, 4995aee162fSJim Ingham int cursor_index, 5005aee162fSJim Ingham int char_pos, 5015aee162fSJim Ingham OptionElementVector &opt_element_vector, 5025aee162fSJim Ingham int opt_element_index, 5035aee162fSJim Ingham int match_start_point, 5045aee162fSJim Ingham int max_return_elements, 5055aee162fSJim Ingham bool &word_complete, 5065aee162fSJim Ingham StringList &matches) 5075aee162fSJim Ingham { 5085aee162fSJim Ingham int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; 5095aee162fSJim Ingham int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; 5105aee162fSJim Ingham 5115aee162fSJim Ingham // We are only completing the name option for now... 5125aee162fSJim Ingham 513e0d378b3SGreg Clayton const OptionDefinition *opt_defs = GetDefinitions(); 5145aee162fSJim Ingham if (opt_defs[opt_defs_index].short_option == 'n') 5155aee162fSJim Ingham { 5165aee162fSJim Ingham // Are we in the name? 5175aee162fSJim Ingham 5185aee162fSJim Ingham // Look to see if there is a -P argument provided, and if so use that plugin, otherwise 5195aee162fSJim Ingham // use the default plugin. 5205aee162fSJim Ingham 5215aee162fSJim Ingham const char *partial_name = NULL; 5225aee162fSJim Ingham partial_name = input.GetArgumentAtIndex(opt_arg_pos); 5235aee162fSJim Ingham 524*eb0103f2SGreg Clayton PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform ()); 525e996fd30SGreg Clayton if (platform_sp) 5265aee162fSJim Ingham { 527e996fd30SGreg Clayton ProcessInfoList process_infos; 52832e0a750SGreg Clayton ProcessInfoMatch match_info; 52932e0a750SGreg Clayton if (partial_name) 53032e0a750SGreg Clayton { 53132e0a750SGreg Clayton match_info.GetProcessInfo().SetName(partial_name); 53232e0a750SGreg Clayton match_info.SetNameMatchType(eNameMatchStartsWith); 53332e0a750SGreg Clayton } 53432e0a750SGreg Clayton platform_sp->FindProcesses (match_info, process_infos); 535e996fd30SGreg Clayton const uint32_t num_matches = process_infos.GetSize(); 536e996fd30SGreg Clayton if (num_matches > 0) 537e996fd30SGreg Clayton { 538e996fd30SGreg Clayton for (uint32_t i=0; i<num_matches; ++i) 539e996fd30SGreg Clayton { 540e996fd30SGreg Clayton matches.AppendString (process_infos.GetProcessNameAtIndex(i), 541e996fd30SGreg Clayton process_infos.GetProcessNameLengthAtIndex(i)); 5425aee162fSJim Ingham } 5435aee162fSJim Ingham } 5445aee162fSJim Ingham } 5455aee162fSJim Ingham } 5465aee162fSJim Ingham 5475aee162fSJim Ingham return false; 5485aee162fSJim Ingham } 5495aee162fSJim Ingham 55030fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 55130fdc8d8SChris Lattner 552e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 55330fdc8d8SChris Lattner 55430fdc8d8SChris Lattner // Instance variables to hold the values for command options. 55530fdc8d8SChris Lattner 55630fdc8d8SChris Lattner lldb::pid_t pid; 55730fdc8d8SChris Lattner std::string plugin_name; 55830fdc8d8SChris Lattner std::string name; 55930fdc8d8SChris Lattner bool waitfor; 56030fdc8d8SChris Lattner }; 56130fdc8d8SChris Lattner 562a7015092SGreg Clayton CommandObjectProcessAttach (CommandInterpreter &interpreter) : 563a7015092SGreg Clayton CommandObject (interpreter, 564a7015092SGreg Clayton "process attach", 565e3d26315SCaroline Tice "Attach to a process.", 566*eb0103f2SGreg Clayton "process attach <cmd-options>"), 567*eb0103f2SGreg Clayton m_options (interpreter) 5685aee162fSJim Ingham { 5695aee162fSJim Ingham } 5705aee162fSJim Ingham 5715aee162fSJim Ingham ~CommandObjectProcessAttach () 5725aee162fSJim Ingham { 5735aee162fSJim Ingham } 5745aee162fSJim Ingham 5755aee162fSJim Ingham bool 576a7015092SGreg Clayton Execute (Args& command, 5775aee162fSJim Ingham CommandReturnObject &result) 5785aee162fSJim Ingham { 579a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 580bb3a283bSJim Ingham bool synchronous_execution = m_interpreter.GetSynchronous (); 5815aee162fSJim Ingham 582a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 58371337622SGreg Clayton StateType state = eStateInvalid; 5845aee162fSJim Ingham if (process) 5855aee162fSJim Ingham { 58671337622SGreg Clayton state = process->GetState(); 58771337622SGreg Clayton if (process->IsAlive() && state != eStateConnected) 5885aee162fSJim Ingham { 5895aee162fSJim Ingham result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", 5905aee162fSJim Ingham process->GetID()); 5915aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5925aee162fSJim Ingham return false; 5935aee162fSJim Ingham } 5945aee162fSJim Ingham } 5955aee162fSJim Ingham 5965aee162fSJim Ingham if (target == NULL) 5975aee162fSJim Ingham { 5985aee162fSJim Ingham // If there isn't a current target create one. 5995aee162fSJim Ingham TargetSP new_target_sp; 6005aee162fSJim Ingham FileSpec emptyFileSpec; 6015aee162fSJim Ingham ArchSpec emptyArchSpec; 6025aee162fSJim Ingham Error error; 6035aee162fSJim Ingham 604a7015092SGreg Clayton error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 6055aee162fSJim Ingham emptyFileSpec, 6065aee162fSJim Ingham emptyArchSpec, 6075aee162fSJim Ingham false, 6085aee162fSJim Ingham new_target_sp); 6095aee162fSJim Ingham target = new_target_sp.get(); 6105aee162fSJim Ingham if (target == NULL || error.Fail()) 6115aee162fSJim Ingham { 612b766a73dSGreg Clayton result.AppendError(error.AsCString("Error creating target")); 6135aee162fSJim Ingham return false; 6145aee162fSJim Ingham } 615a7015092SGreg Clayton m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); 6165aee162fSJim Ingham } 6175aee162fSJim Ingham 6185aee162fSJim Ingham // Record the old executable module, we want to issue a warning if the process of attaching changed the 6195aee162fSJim Ingham // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.) 6205aee162fSJim Ingham 6215aee162fSJim Ingham ModuleSP old_exec_module_sp = target->GetExecutableModule(); 6225aee162fSJim Ingham ArchSpec old_arch_spec = target->GetArchitecture(); 6235aee162fSJim Ingham 6245aee162fSJim Ingham if (command.GetArgumentCount()) 6255aee162fSJim Ingham { 6265aee162fSJim Ingham result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 6275aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6285aee162fSJim Ingham } 6295aee162fSJim Ingham else 6305aee162fSJim Ingham { 63171337622SGreg Clayton if (state != eStateConnected) 63271337622SGreg Clayton { 6335aee162fSJim Ingham const char *plugin_name = NULL; 6345aee162fSJim Ingham 6355aee162fSJim Ingham if (!m_options.plugin_name.empty()) 6365aee162fSJim Ingham plugin_name = m_options.plugin_name.c_str(); 6375aee162fSJim Ingham 638a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 63971337622SGreg Clayton } 6405aee162fSJim Ingham 6415aee162fSJim Ingham if (process) 6425aee162fSJim Ingham { 6435aee162fSJim Ingham Error error; 6445aee162fSJim Ingham int attach_pid = m_options.pid; 6455aee162fSJim Ingham 6463a0b9cdfSJim Ingham const char *wait_name = NULL; 6473a0b9cdfSJim Ingham 6485aee162fSJim Ingham if (m_options.name.empty()) 6495aee162fSJim Ingham { 6503a0b9cdfSJim Ingham if (old_exec_module_sp) 6513a0b9cdfSJim Ingham { 6523a0b9cdfSJim Ingham wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString(); 6533a0b9cdfSJim Ingham } 6545aee162fSJim Ingham } 6555aee162fSJim Ingham else 6565aee162fSJim Ingham { 6573a0b9cdfSJim Ingham wait_name = m_options.name.c_str(); 6583a0b9cdfSJim Ingham } 6593a0b9cdfSJim Ingham 6603a0b9cdfSJim Ingham // If we are waiting for a process with this name to show up, do that first. 6613a0b9cdfSJim Ingham if (m_options.waitfor) 6623a0b9cdfSJim Ingham { 6633a0b9cdfSJim Ingham 6643a0b9cdfSJim Ingham if (wait_name == NULL) 6653a0b9cdfSJim Ingham { 6663a0b9cdfSJim Ingham result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n"); 6673a0b9cdfSJim Ingham result.SetStatus (eReturnStatusFailed); 6683a0b9cdfSJim Ingham return false; 6693a0b9cdfSJim Ingham } 6703a0b9cdfSJim Ingham 671513c26ceSGreg Clayton result.AppendMessageWithFormat("Waiting to attach to a process named \"%s\".\n", wait_name); 6723a0b9cdfSJim Ingham error = process->Attach (wait_name, m_options.waitfor); 6735aee162fSJim Ingham if (error.Success()) 6745aee162fSJim Ingham { 6755aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 6765aee162fSJim Ingham } 6775aee162fSJim Ingham else 6785aee162fSJim Ingham { 6795aee162fSJim Ingham result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n", 6803a0b9cdfSJim Ingham wait_name, 6815aee162fSJim Ingham error.AsCString()); 6825aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6835aee162fSJim Ingham return false; 6845aee162fSJim Ingham } 685bb3a283bSJim Ingham // If we're synchronous, wait for the stopped event and report that. 686bb3a283bSJim Ingham // Otherwise just return. 687bb3a283bSJim Ingham // FIXME: in the async case it will now be possible to get to the command 688bb3a283bSJim Ingham // interpreter with a state eStateAttaching. Make sure we handle that correctly. 689bb3a283bSJim Ingham if (synchronous_execution) 690bb3a283bSJim Ingham { 691bb3a283bSJim Ingham StateType state = process->WaitForProcessToStop (NULL); 692bb3a283bSJim Ingham 693bb3a283bSJim Ingham result.SetDidChangeProcessState (true); 694bb3a283bSJim Ingham result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 695bb3a283bSJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 696bb3a283bSJim Ingham } 697bb3a283bSJim Ingham else 698bb3a283bSJim Ingham { 699bb3a283bSJim Ingham result.SetDidChangeProcessState (true); 700bb3a283bSJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 701bb3a283bSJim Ingham } 7025aee162fSJim Ingham } 7035aee162fSJim Ingham else 7045aee162fSJim Ingham { 7055aee162fSJim Ingham // If the process was specified by name look it up, so we can warn if there are multiple 7065aee162fSJim Ingham // processes with this pid. 7075aee162fSJim Ingham 7083a0b9cdfSJim Ingham if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL) 7095aee162fSJim Ingham { 710e996fd30SGreg Clayton ProcessInfoList process_infos; 711ded470d3SGreg Clayton PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform ()); 712e996fd30SGreg Clayton if (platform_sp) 713e996fd30SGreg Clayton { 71432e0a750SGreg Clayton ProcessInfoMatch match_info (wait_name, eNameMatchEquals); 71532e0a750SGreg Clayton platform_sp->FindProcesses (match_info, process_infos); 716e996fd30SGreg Clayton } 717e996fd30SGreg Clayton if (process_infos.GetSize() > 1) 7185aee162fSJim Ingham { 7193a0b9cdfSJim Ingham result.AppendErrorWithFormat("More than one process named %s\n", wait_name); 7205aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 7215aee162fSJim Ingham return false; 7225aee162fSJim Ingham } 723e996fd30SGreg Clayton else if (process_infos.GetSize() == 0) 7245aee162fSJim Ingham { 7253a0b9cdfSJim Ingham result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name); 7265aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 7275aee162fSJim Ingham return false; 7285aee162fSJim Ingham } 7295aee162fSJim Ingham else 7305aee162fSJim Ingham { 731e996fd30SGreg Clayton attach_pid = process_infos.GetProcessIDAtIndex (0); 7325aee162fSJim Ingham } 7335aee162fSJim Ingham } 7345aee162fSJim Ingham 7355aee162fSJim Ingham if (attach_pid != LLDB_INVALID_PROCESS_ID) 7365aee162fSJim Ingham { 7375aee162fSJim Ingham error = process->Attach (attach_pid); 7385aee162fSJim Ingham if (error.Success()) 7395aee162fSJim Ingham { 7405aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 7415aee162fSJim Ingham } 7425aee162fSJim Ingham else 7435aee162fSJim Ingham { 7445aee162fSJim Ingham result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n", 7455aee162fSJim Ingham attach_pid, 7465aee162fSJim Ingham error.AsCString()); 7475aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 7485aee162fSJim Ingham } 749bb3a283bSJim Ingham // See comment for synchronous_execution above. 750bb3a283bSJim Ingham if (synchronous_execution) 751bb3a283bSJim Ingham { 752bb3a283bSJim Ingham StateType state = process->WaitForProcessToStop (NULL); 753bb3a283bSJim Ingham 754bb3a283bSJim Ingham result.SetDidChangeProcessState (true); 755bb3a283bSJim Ingham result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 756bb3a283bSJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 757bb3a283bSJim Ingham } 758bb3a283bSJim Ingham else 759bb3a283bSJim Ingham { 760bb3a283bSJim Ingham result.SetDidChangeProcessState (true); 761bb3a283bSJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 762bb3a283bSJim Ingham } 7635aee162fSJim Ingham } 7645aee162fSJim Ingham else 7655aee162fSJim Ingham { 7665aee162fSJim Ingham result.AppendErrorWithFormat ("No PID specified for attach\n", 7675aee162fSJim Ingham attach_pid, 7685aee162fSJim Ingham error.AsCString()); 7695aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 7705aee162fSJim Ingham 7715aee162fSJim Ingham } 7725aee162fSJim Ingham } 7735aee162fSJim Ingham } 7745aee162fSJim Ingham } 7755aee162fSJim Ingham 7765aee162fSJim Ingham if (result.Succeeded()) 7775aee162fSJim Ingham { 7785aee162fSJim Ingham // Okay, we're done. Last step is to warn if the executable module has changed: 779513c26ceSGreg Clayton char new_path[PATH_MAX]; 7805aee162fSJim Ingham if (!old_exec_module_sp) 7815aee162fSJim Ingham { 782513c26ceSGreg Clayton // We might not have a module if we attached to a raw pid... 783513c26ceSGreg Clayton ModuleSP new_module_sp (target->GetExecutableModule()); 784513c26ceSGreg Clayton if (new_module_sp) 785513c26ceSGreg Clayton { 786513c26ceSGreg Clayton new_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX); 787513c26ceSGreg Clayton result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path); 788513c26ceSGreg Clayton } 7895aee162fSJim Ingham } 7905aee162fSJim Ingham else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec()) 7915aee162fSJim Ingham { 792513c26ceSGreg Clayton char old_path[PATH_MAX]; 7935aee162fSJim Ingham 7945aee162fSJim Ingham old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX); 7955aee162fSJim Ingham target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX); 7965aee162fSJim Ingham 7975aee162fSJim Ingham result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", 7985aee162fSJim Ingham old_path, new_path); 7995aee162fSJim Ingham } 8005aee162fSJim Ingham 8015aee162fSJim Ingham if (!old_arch_spec.IsValid()) 8025aee162fSJim Ingham { 80364195a2cSGreg Clayton result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetArchitectureName()); 8045aee162fSJim Ingham } 8055aee162fSJim Ingham else if (old_arch_spec != target->GetArchitecture()) 8065aee162fSJim Ingham { 8075aee162fSJim Ingham result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", 80864195a2cSGreg Clayton old_arch_spec.GetArchitectureName(), target->GetArchitecture().GetArchitectureName()); 8095aee162fSJim Ingham } 8105aee162fSJim Ingham } 8115aee162fSJim Ingham return result.Succeeded(); 8125aee162fSJim Ingham } 8135aee162fSJim Ingham 8145aee162fSJim Ingham Options * 8155aee162fSJim Ingham GetOptions () 8165aee162fSJim Ingham { 8175aee162fSJim Ingham return &m_options; 8185aee162fSJim Ingham } 8195aee162fSJim Ingham 82030fdc8d8SChris Lattner protected: 82130fdc8d8SChris Lattner 82230fdc8d8SChris Lattner CommandOptions m_options; 82330fdc8d8SChris Lattner }; 82430fdc8d8SChris Lattner 82530fdc8d8SChris Lattner 826e0d378b3SGreg Clayton OptionDefinition 82730fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] = 82830fdc8d8SChris Lattner { 829deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 830deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, 831deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, 832deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "waitfor",'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the the process with <process-name> to launch."}, 833deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 83430fdc8d8SChris Lattner }; 83530fdc8d8SChris Lattner 83630fdc8d8SChris Lattner //------------------------------------------------------------------------- 83730fdc8d8SChris Lattner // CommandObjectProcessContinue 83830fdc8d8SChris Lattner //------------------------------------------------------------------------- 839bb9caf73SJim Ingham #pragma mark CommandObjectProcessContinue 84030fdc8d8SChris Lattner 84130fdc8d8SChris Lattner class CommandObjectProcessContinue : public CommandObject 84230fdc8d8SChris Lattner { 84330fdc8d8SChris Lattner public: 84430fdc8d8SChris Lattner 845a7015092SGreg Clayton CommandObjectProcessContinue (CommandInterpreter &interpreter) : 846a7015092SGreg Clayton CommandObject (interpreter, 847a7015092SGreg Clayton "process continue", 848e3d26315SCaroline Tice "Continue execution of all threads in the current process.", 84930fdc8d8SChris Lattner "process continue", 85030fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 85130fdc8d8SChris Lattner { 85230fdc8d8SChris Lattner } 85330fdc8d8SChris Lattner 85430fdc8d8SChris Lattner 85530fdc8d8SChris Lattner ~CommandObjectProcessContinue () 85630fdc8d8SChris Lattner { 85730fdc8d8SChris Lattner } 85830fdc8d8SChris Lattner 85930fdc8d8SChris Lattner bool 860a7015092SGreg Clayton Execute (Args& command, 86130fdc8d8SChris Lattner CommandReturnObject &result) 86230fdc8d8SChris Lattner { 863a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 864a7015092SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 86530fdc8d8SChris Lattner 86630fdc8d8SChris Lattner if (process == NULL) 86730fdc8d8SChris Lattner { 86830fdc8d8SChris Lattner result.AppendError ("no process to continue"); 86930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 87030fdc8d8SChris Lattner return false; 87130fdc8d8SChris Lattner } 87230fdc8d8SChris Lattner 87330fdc8d8SChris Lattner StateType state = process->GetState(); 87430fdc8d8SChris Lattner if (state == eStateStopped) 87530fdc8d8SChris Lattner { 87630fdc8d8SChris Lattner if (command.GetArgumentCount() != 0) 87730fdc8d8SChris Lattner { 87830fdc8d8SChris Lattner result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str()); 87930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 88030fdc8d8SChris Lattner return false; 88130fdc8d8SChris Lattner } 88230fdc8d8SChris Lattner 88330fdc8d8SChris Lattner const uint32_t num_threads = process->GetThreadList().GetSize(); 88430fdc8d8SChris Lattner 88530fdc8d8SChris Lattner // Set the actions that the threads should each take when resuming 88630fdc8d8SChris Lattner for (uint32_t idx=0; idx<num_threads; ++idx) 88730fdc8d8SChris Lattner { 88830fdc8d8SChris Lattner process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning); 88930fdc8d8SChris Lattner } 89030fdc8d8SChris Lattner 89130fdc8d8SChris Lattner Error error(process->Resume()); 89230fdc8d8SChris Lattner if (error.Success()) 89330fdc8d8SChris Lattner { 89419388cfcSGreg Clayton result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID()); 89530fdc8d8SChris Lattner if (synchronous_execution) 89630fdc8d8SChris Lattner { 897b132097bSGreg Clayton state = process->WaitForProcessToStop (NULL); 89830fdc8d8SChris Lattner 89930fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 90030fdc8d8SChris Lattner result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 90130fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 90230fdc8d8SChris Lattner } 90330fdc8d8SChris Lattner else 90430fdc8d8SChris Lattner { 90530fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessContinuingNoResult); 90630fdc8d8SChris Lattner } 90730fdc8d8SChris Lattner } 90830fdc8d8SChris Lattner else 90930fdc8d8SChris Lattner { 91030fdc8d8SChris Lattner result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 91130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 91230fdc8d8SChris Lattner } 91330fdc8d8SChris Lattner } 91430fdc8d8SChris Lattner else 91530fdc8d8SChris Lattner { 91630fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 91730fdc8d8SChris Lattner StateAsCString(state)); 91830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 91930fdc8d8SChris Lattner } 92030fdc8d8SChris Lattner return result.Succeeded(); 92130fdc8d8SChris Lattner } 92230fdc8d8SChris Lattner }; 92330fdc8d8SChris Lattner 92430fdc8d8SChris Lattner //------------------------------------------------------------------------- 92530fdc8d8SChris Lattner // CommandObjectProcessDetach 92630fdc8d8SChris Lattner //------------------------------------------------------------------------- 927bb9caf73SJim Ingham #pragma mark CommandObjectProcessDetach 92830fdc8d8SChris Lattner 92930fdc8d8SChris Lattner class CommandObjectProcessDetach : public CommandObject 93030fdc8d8SChris Lattner { 93130fdc8d8SChris Lattner public: 93230fdc8d8SChris Lattner 933a7015092SGreg Clayton CommandObjectProcessDetach (CommandInterpreter &interpreter) : 934a7015092SGreg Clayton CommandObject (interpreter, 935a7015092SGreg Clayton "process detach", 936e3d26315SCaroline Tice "Detach from the current process being debugged.", 93730fdc8d8SChris Lattner "process detach", 93830fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 93930fdc8d8SChris Lattner { 94030fdc8d8SChris Lattner } 94130fdc8d8SChris Lattner 94230fdc8d8SChris Lattner ~CommandObjectProcessDetach () 94330fdc8d8SChris Lattner { 94430fdc8d8SChris Lattner } 94530fdc8d8SChris Lattner 94630fdc8d8SChris Lattner bool 947a7015092SGreg Clayton Execute (Args& command, 94830fdc8d8SChris Lattner CommandReturnObject &result) 94930fdc8d8SChris Lattner { 950a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 95130fdc8d8SChris Lattner if (process == NULL) 95230fdc8d8SChris Lattner { 95330fdc8d8SChris Lattner result.AppendError ("must have a valid process in order to detach"); 95430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 95530fdc8d8SChris Lattner return false; 95630fdc8d8SChris Lattner } 95730fdc8d8SChris Lattner 9585d7be2e6SCaroline Tice result.AppendMessageWithFormat ("Detaching from process %i\n", process->GetID()); 95930fdc8d8SChris Lattner Error error (process->Detach()); 96030fdc8d8SChris Lattner if (error.Success()) 96130fdc8d8SChris Lattner { 96230fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 96330fdc8d8SChris Lattner } 96430fdc8d8SChris Lattner else 96530fdc8d8SChris Lattner { 96630fdc8d8SChris Lattner result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString()); 96730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 96830fdc8d8SChris Lattner return false; 96930fdc8d8SChris Lattner } 97030fdc8d8SChris Lattner return result.Succeeded(); 97130fdc8d8SChris Lattner } 97230fdc8d8SChris Lattner }; 97330fdc8d8SChris Lattner 97430fdc8d8SChris Lattner //------------------------------------------------------------------------- 975b766a73dSGreg Clayton // CommandObjectProcessConnect 976b766a73dSGreg Clayton //------------------------------------------------------------------------- 977b766a73dSGreg Clayton #pragma mark CommandObjectProcessConnect 978b766a73dSGreg Clayton 979b766a73dSGreg Clayton class CommandObjectProcessConnect : public CommandObject 980b766a73dSGreg Clayton { 981b766a73dSGreg Clayton public: 982b766a73dSGreg Clayton 983b766a73dSGreg Clayton class CommandOptions : public Options 984b766a73dSGreg Clayton { 985b766a73dSGreg Clayton public: 986b766a73dSGreg Clayton 987*eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 988*eb0103f2SGreg Clayton Options(interpreter) 989b766a73dSGreg Clayton { 990b766a73dSGreg Clayton // Keep default values of all options in one place: ResetOptionValues () 991b766a73dSGreg Clayton ResetOptionValues (); 992b766a73dSGreg Clayton } 993b766a73dSGreg Clayton 994b766a73dSGreg Clayton ~CommandOptions () 995b766a73dSGreg Clayton { 996b766a73dSGreg Clayton } 997b766a73dSGreg Clayton 998b766a73dSGreg Clayton Error 999b766a73dSGreg Clayton SetOptionValue (int option_idx, const char *option_arg) 1000b766a73dSGreg Clayton { 1001b766a73dSGreg Clayton Error error; 1002b766a73dSGreg Clayton char short_option = (char) m_getopt_table[option_idx].val; 1003b766a73dSGreg Clayton 1004b766a73dSGreg Clayton switch (short_option) 1005b766a73dSGreg Clayton { 1006b766a73dSGreg Clayton case 'p': 1007b766a73dSGreg Clayton plugin_name.assign (option_arg); 1008b766a73dSGreg Clayton break; 1009b766a73dSGreg Clayton 1010b766a73dSGreg Clayton default: 1011b766a73dSGreg Clayton error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 1012b766a73dSGreg Clayton break; 1013b766a73dSGreg Clayton } 1014b766a73dSGreg Clayton return error; 1015b766a73dSGreg Clayton } 1016b766a73dSGreg Clayton 1017b766a73dSGreg Clayton void 1018b766a73dSGreg Clayton ResetOptionValues () 1019b766a73dSGreg Clayton { 1020b766a73dSGreg Clayton plugin_name.clear(); 1021b766a73dSGreg Clayton } 1022b766a73dSGreg Clayton 1023e0d378b3SGreg Clayton const OptionDefinition* 1024b766a73dSGreg Clayton GetDefinitions () 1025b766a73dSGreg Clayton { 1026b766a73dSGreg Clayton return g_option_table; 1027b766a73dSGreg Clayton } 1028b766a73dSGreg Clayton 1029b766a73dSGreg Clayton // Options table: Required for subclasses of Options. 1030b766a73dSGreg Clayton 1031e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 1032b766a73dSGreg Clayton 1033b766a73dSGreg Clayton // Instance variables to hold the values for command options. 1034b766a73dSGreg Clayton 1035b766a73dSGreg Clayton std::string plugin_name; 1036b766a73dSGreg Clayton }; 1037b766a73dSGreg Clayton 1038b766a73dSGreg Clayton CommandObjectProcessConnect (CommandInterpreter &interpreter) : 1039b766a73dSGreg Clayton CommandObject (interpreter, 1040b766a73dSGreg Clayton "process connect", 1041b766a73dSGreg Clayton "Connect to a remote debug service.", 1042b766a73dSGreg Clayton "process connect <remote-url>", 1043*eb0103f2SGreg Clayton 0), 1044*eb0103f2SGreg Clayton m_options (interpreter) 1045b766a73dSGreg Clayton { 1046b766a73dSGreg Clayton } 1047b766a73dSGreg Clayton 1048b766a73dSGreg Clayton ~CommandObjectProcessConnect () 1049b766a73dSGreg Clayton { 1050b766a73dSGreg Clayton } 1051b766a73dSGreg Clayton 1052b766a73dSGreg Clayton 1053b766a73dSGreg Clayton bool 1054b766a73dSGreg Clayton Execute (Args& command, 1055b766a73dSGreg Clayton CommandReturnObject &result) 1056b766a73dSGreg Clayton { 1057b766a73dSGreg Clayton 1058b766a73dSGreg Clayton TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget()); 1059b766a73dSGreg Clayton Error error; 1060b766a73dSGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 1061b766a73dSGreg Clayton if (process) 1062b766a73dSGreg Clayton { 1063b766a73dSGreg Clayton if (process->IsAlive()) 1064b766a73dSGreg Clayton { 1065b766a73dSGreg Clayton result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before connecting.\n", 1066b766a73dSGreg Clayton process->GetID()); 1067b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 1068b766a73dSGreg Clayton return false; 1069b766a73dSGreg Clayton } 1070b766a73dSGreg Clayton } 1071b766a73dSGreg Clayton 1072b766a73dSGreg Clayton if (!target_sp) 1073b766a73dSGreg Clayton { 1074b766a73dSGreg Clayton // If there isn't a current target create one. 1075b766a73dSGreg Clayton FileSpec emptyFileSpec; 1076b766a73dSGreg Clayton ArchSpec emptyArchSpec; 1077b766a73dSGreg Clayton 1078b766a73dSGreg Clayton error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 1079b766a73dSGreg Clayton emptyFileSpec, 1080b766a73dSGreg Clayton emptyArchSpec, 1081b766a73dSGreg Clayton false, 1082b766a73dSGreg Clayton target_sp); 1083b766a73dSGreg Clayton if (!target_sp || error.Fail()) 1084b766a73dSGreg Clayton { 1085b766a73dSGreg Clayton result.AppendError(error.AsCString("Error creating target")); 1086b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 1087b766a73dSGreg Clayton return false; 1088b766a73dSGreg Clayton } 1089b766a73dSGreg Clayton m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get()); 1090b766a73dSGreg Clayton } 1091b766a73dSGreg Clayton 1092b766a73dSGreg Clayton if (command.GetArgumentCount() == 1) 1093b766a73dSGreg Clayton { 1094b766a73dSGreg Clayton const char *plugin_name = NULL; 1095b766a73dSGreg Clayton if (!m_options.plugin_name.empty()) 1096b766a73dSGreg Clayton plugin_name = m_options.plugin_name.c_str(); 1097b766a73dSGreg Clayton 1098b766a73dSGreg Clayton const char *remote_url = command.GetArgumentAtIndex(0); 1099b766a73dSGreg Clayton process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 1100b766a73dSGreg Clayton 1101b766a73dSGreg Clayton if (process) 1102b766a73dSGreg Clayton { 1103b766a73dSGreg Clayton error = process->ConnectRemote (remote_url); 1104b766a73dSGreg Clayton 1105b766a73dSGreg Clayton if (error.Fail()) 1106b766a73dSGreg Clayton { 1107b766a73dSGreg Clayton result.AppendError(error.AsCString("Remote connect failed")); 1108b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 1109b766a73dSGreg Clayton return false; 1110b766a73dSGreg Clayton } 1111b766a73dSGreg Clayton } 1112b766a73dSGreg Clayton else 1113b766a73dSGreg Clayton { 1114b766a73dSGreg Clayton result.AppendErrorWithFormat ("Unable to find process plug-in for remote URL '%s'.\nPlease specify a process plug-in name with the --plugin option, or specify an object file using the \"file\" command: \n", 1115b766a73dSGreg Clayton m_cmd_name.c_str(), 1116b766a73dSGreg Clayton m_cmd_syntax.c_str()); 1117b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 1118b766a73dSGreg Clayton } 1119b766a73dSGreg Clayton } 1120b766a73dSGreg Clayton else 1121b766a73dSGreg Clayton { 1122b766a73dSGreg Clayton result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: \n", 1123b766a73dSGreg Clayton m_cmd_name.c_str(), 1124b766a73dSGreg Clayton m_cmd_syntax.c_str()); 1125b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 1126b766a73dSGreg Clayton } 1127b766a73dSGreg Clayton return result.Succeeded(); 1128b766a73dSGreg Clayton } 1129b766a73dSGreg Clayton 1130b766a73dSGreg Clayton Options * 1131b766a73dSGreg Clayton GetOptions () 1132b766a73dSGreg Clayton { 1133b766a73dSGreg Clayton return &m_options; 1134b766a73dSGreg Clayton } 1135b766a73dSGreg Clayton 1136b766a73dSGreg Clayton protected: 1137b766a73dSGreg Clayton 1138b766a73dSGreg Clayton CommandOptions m_options; 1139b766a73dSGreg Clayton }; 1140b766a73dSGreg Clayton 1141b766a73dSGreg Clayton 1142e0d378b3SGreg Clayton OptionDefinition 1143b766a73dSGreg Clayton CommandObjectProcessConnect::CommandOptions::g_option_table[] = 1144b766a73dSGreg Clayton { 1145b766a73dSGreg Clayton { LLDB_OPT_SET_ALL, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 1146b766a73dSGreg Clayton { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } 1147b766a73dSGreg Clayton }; 1148b766a73dSGreg Clayton 1149b766a73dSGreg Clayton //------------------------------------------------------------------------- 11508f343b09SGreg Clayton // CommandObjectProcessLoad 11518f343b09SGreg Clayton //------------------------------------------------------------------------- 1152bb9caf73SJim Ingham #pragma mark CommandObjectProcessLoad 11538f343b09SGreg Clayton 11548f343b09SGreg Clayton class CommandObjectProcessLoad : public CommandObject 11558f343b09SGreg Clayton { 11568f343b09SGreg Clayton public: 11578f343b09SGreg Clayton 11588f343b09SGreg Clayton CommandObjectProcessLoad (CommandInterpreter &interpreter) : 11598f343b09SGreg Clayton CommandObject (interpreter, 11608f343b09SGreg Clayton "process load", 11618f343b09SGreg Clayton "Load a shared library into the current process.", 11628f343b09SGreg Clayton "process load <filename> [<filename> ...]", 11638f343b09SGreg Clayton eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 11648f343b09SGreg Clayton { 11658f343b09SGreg Clayton } 11668f343b09SGreg Clayton 11678f343b09SGreg Clayton ~CommandObjectProcessLoad () 11688f343b09SGreg Clayton { 11698f343b09SGreg Clayton } 11708f343b09SGreg Clayton 11718f343b09SGreg Clayton bool 11728f343b09SGreg Clayton Execute (Args& command, 11738f343b09SGreg Clayton CommandReturnObject &result) 11748f343b09SGreg Clayton { 11758f343b09SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 11768f343b09SGreg Clayton if (process == NULL) 11778f343b09SGreg Clayton { 11788f343b09SGreg Clayton result.AppendError ("must have a valid process in order to load a shared library"); 11798f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 11808f343b09SGreg Clayton return false; 11818f343b09SGreg Clayton } 11828f343b09SGreg Clayton 11838f343b09SGreg Clayton const uint32_t argc = command.GetArgumentCount(); 11848f343b09SGreg Clayton 11858f343b09SGreg Clayton for (uint32_t i=0; i<argc; ++i) 11868f343b09SGreg Clayton { 11878f343b09SGreg Clayton Error error; 11888f343b09SGreg Clayton const char *image_path = command.GetArgumentAtIndex(i); 11898f343b09SGreg Clayton FileSpec image_spec (image_path, false); 11908f343b09SGreg Clayton uint32_t image_token = process->LoadImage(image_spec, error); 11918f343b09SGreg Clayton if (image_token != LLDB_INVALID_IMAGE_TOKEN) 11928f343b09SGreg Clayton { 11938f343b09SGreg Clayton result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token); 11948f343b09SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 11958f343b09SGreg Clayton } 11968f343b09SGreg Clayton else 11978f343b09SGreg Clayton { 11988f343b09SGreg Clayton result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString()); 11998f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 12008f343b09SGreg Clayton } 12018f343b09SGreg Clayton } 12028f343b09SGreg Clayton return result.Succeeded(); 12038f343b09SGreg Clayton } 12048f343b09SGreg Clayton }; 12058f343b09SGreg Clayton 12068f343b09SGreg Clayton 12078f343b09SGreg Clayton //------------------------------------------------------------------------- 12088f343b09SGreg Clayton // CommandObjectProcessUnload 12098f343b09SGreg Clayton //------------------------------------------------------------------------- 1210bb9caf73SJim Ingham #pragma mark CommandObjectProcessUnload 12118f343b09SGreg Clayton 12128f343b09SGreg Clayton class CommandObjectProcessUnload : public CommandObject 12138f343b09SGreg Clayton { 12148f343b09SGreg Clayton public: 12158f343b09SGreg Clayton 12168f343b09SGreg Clayton CommandObjectProcessUnload (CommandInterpreter &interpreter) : 12178f343b09SGreg Clayton CommandObject (interpreter, 12188f343b09SGreg Clayton "process unload", 12198f343b09SGreg Clayton "Unload a shared library from the current process using the index returned by a previous call to \"process load\".", 12208f343b09SGreg Clayton "process unload <index>", 12218f343b09SGreg Clayton eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 12228f343b09SGreg Clayton { 12238f343b09SGreg Clayton } 12248f343b09SGreg Clayton 12258f343b09SGreg Clayton ~CommandObjectProcessUnload () 12268f343b09SGreg Clayton { 12278f343b09SGreg Clayton } 12288f343b09SGreg Clayton 12298f343b09SGreg Clayton bool 12308f343b09SGreg Clayton Execute (Args& command, 12318f343b09SGreg Clayton CommandReturnObject &result) 12328f343b09SGreg Clayton { 12338f343b09SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 12348f343b09SGreg Clayton if (process == NULL) 12358f343b09SGreg Clayton { 12368f343b09SGreg Clayton result.AppendError ("must have a valid process in order to load a shared library"); 12378f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 12388f343b09SGreg Clayton return false; 12398f343b09SGreg Clayton } 12408f343b09SGreg Clayton 12418f343b09SGreg Clayton const uint32_t argc = command.GetArgumentCount(); 12428f343b09SGreg Clayton 12438f343b09SGreg Clayton for (uint32_t i=0; i<argc; ++i) 12448f343b09SGreg Clayton { 12458f343b09SGreg Clayton const char *image_token_cstr = command.GetArgumentAtIndex(i); 12468f343b09SGreg Clayton uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0); 12478f343b09SGreg Clayton if (image_token == LLDB_INVALID_IMAGE_TOKEN) 12488f343b09SGreg Clayton { 12498f343b09SGreg Clayton result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr); 12508f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 12518f343b09SGreg Clayton break; 12528f343b09SGreg Clayton } 12538f343b09SGreg Clayton else 12548f343b09SGreg Clayton { 12558f343b09SGreg Clayton Error error (process->UnloadImage(image_token)); 12568f343b09SGreg Clayton if (error.Success()) 12578f343b09SGreg Clayton { 12588f343b09SGreg Clayton result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token); 12598f343b09SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 12608f343b09SGreg Clayton } 12618f343b09SGreg Clayton else 12628f343b09SGreg Clayton { 12638f343b09SGreg Clayton result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString()); 12648f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 12658f343b09SGreg Clayton break; 12668f343b09SGreg Clayton } 12678f343b09SGreg Clayton } 12688f343b09SGreg Clayton } 12698f343b09SGreg Clayton return result.Succeeded(); 12708f343b09SGreg Clayton } 12718f343b09SGreg Clayton }; 12728f343b09SGreg Clayton 12738f343b09SGreg Clayton //------------------------------------------------------------------------- 127430fdc8d8SChris Lattner // CommandObjectProcessSignal 127530fdc8d8SChris Lattner //------------------------------------------------------------------------- 1276bb9caf73SJim Ingham #pragma mark CommandObjectProcessSignal 127730fdc8d8SChris Lattner 127830fdc8d8SChris Lattner class CommandObjectProcessSignal : public CommandObject 127930fdc8d8SChris Lattner { 128030fdc8d8SChris Lattner public: 128130fdc8d8SChris Lattner 1282a7015092SGreg Clayton CommandObjectProcessSignal (CommandInterpreter &interpreter) : 1283a7015092SGreg Clayton CommandObject (interpreter, 1284a7015092SGreg Clayton "process signal", 1285e3d26315SCaroline Tice "Send a UNIX signal to the current process being debugged.", 1286405fe67fSCaroline Tice NULL) 128730fdc8d8SChris Lattner { 1288405fe67fSCaroline Tice CommandArgumentEntry arg; 1289405fe67fSCaroline Tice CommandArgumentData signal_arg; 1290405fe67fSCaroline Tice 1291405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 1292c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1293405fe67fSCaroline Tice signal_arg.arg_repetition = eArgRepeatPlain; 1294405fe67fSCaroline Tice 1295405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 1296405fe67fSCaroline Tice arg.push_back (signal_arg); 1297405fe67fSCaroline Tice 1298405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 1299405fe67fSCaroline Tice m_arguments.push_back (arg); 130030fdc8d8SChris Lattner } 130130fdc8d8SChris Lattner 130230fdc8d8SChris Lattner ~CommandObjectProcessSignal () 130330fdc8d8SChris Lattner { 130430fdc8d8SChris Lattner } 130530fdc8d8SChris Lattner 130630fdc8d8SChris Lattner bool 1307a7015092SGreg Clayton Execute (Args& command, 130830fdc8d8SChris Lattner CommandReturnObject &result) 130930fdc8d8SChris Lattner { 1310a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 131130fdc8d8SChris Lattner if (process == NULL) 131230fdc8d8SChris Lattner { 131330fdc8d8SChris Lattner result.AppendError ("no process to signal"); 131430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 131530fdc8d8SChris Lattner return false; 131630fdc8d8SChris Lattner } 131730fdc8d8SChris Lattner 131830fdc8d8SChris Lattner if (command.GetArgumentCount() == 1) 131930fdc8d8SChris Lattner { 1320237cd906SGreg Clayton int signo = LLDB_INVALID_SIGNAL_NUMBER; 1321237cd906SGreg Clayton 1322237cd906SGreg Clayton const char *signal_name = command.GetArgumentAtIndex(0); 1323237cd906SGreg Clayton if (::isxdigit (signal_name[0])) 1324237cd906SGreg Clayton signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 1325237cd906SGreg Clayton else 1326237cd906SGreg Clayton signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); 1327237cd906SGreg Clayton 1328237cd906SGreg Clayton if (signo == LLDB_INVALID_SIGNAL_NUMBER) 132930fdc8d8SChris Lattner { 133030fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 133130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 133230fdc8d8SChris Lattner } 133330fdc8d8SChris Lattner else 133430fdc8d8SChris Lattner { 133530fdc8d8SChris Lattner Error error (process->Signal (signo)); 133630fdc8d8SChris Lattner if (error.Success()) 133730fdc8d8SChris Lattner { 133830fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 133930fdc8d8SChris Lattner } 134030fdc8d8SChris Lattner else 134130fdc8d8SChris Lattner { 134230fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 134330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 134430fdc8d8SChris Lattner } 134530fdc8d8SChris Lattner } 134630fdc8d8SChris Lattner } 134730fdc8d8SChris Lattner else 134830fdc8d8SChris Lattner { 134930fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(), 135030fdc8d8SChris Lattner m_cmd_syntax.c_str()); 135130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 135230fdc8d8SChris Lattner } 135330fdc8d8SChris Lattner return result.Succeeded(); 135430fdc8d8SChris Lattner } 135530fdc8d8SChris Lattner }; 135630fdc8d8SChris Lattner 135730fdc8d8SChris Lattner 135830fdc8d8SChris Lattner //------------------------------------------------------------------------- 135930fdc8d8SChris Lattner // CommandObjectProcessInterrupt 136030fdc8d8SChris Lattner //------------------------------------------------------------------------- 1361bb9caf73SJim Ingham #pragma mark CommandObjectProcessInterrupt 136230fdc8d8SChris Lattner 136330fdc8d8SChris Lattner class CommandObjectProcessInterrupt : public CommandObject 136430fdc8d8SChris Lattner { 136530fdc8d8SChris Lattner public: 136630fdc8d8SChris Lattner 136730fdc8d8SChris Lattner 1368a7015092SGreg Clayton CommandObjectProcessInterrupt (CommandInterpreter &interpreter) : 1369a7015092SGreg Clayton CommandObject (interpreter, 1370a7015092SGreg Clayton "process interrupt", 1371e3d26315SCaroline Tice "Interrupt the current process being debugged.", 137230fdc8d8SChris Lattner "process interrupt", 137330fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 137430fdc8d8SChris Lattner { 137530fdc8d8SChris Lattner } 137630fdc8d8SChris Lattner 137730fdc8d8SChris Lattner ~CommandObjectProcessInterrupt () 137830fdc8d8SChris Lattner { 137930fdc8d8SChris Lattner } 138030fdc8d8SChris Lattner 138130fdc8d8SChris Lattner bool 1382a7015092SGreg Clayton Execute (Args& command, 138330fdc8d8SChris Lattner CommandReturnObject &result) 138430fdc8d8SChris Lattner { 1385a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 138630fdc8d8SChris Lattner if (process == NULL) 138730fdc8d8SChris Lattner { 138830fdc8d8SChris Lattner result.AppendError ("no process to halt"); 138930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 139030fdc8d8SChris Lattner return false; 139130fdc8d8SChris Lattner } 139230fdc8d8SChris Lattner 139330fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 139430fdc8d8SChris Lattner { 139530fdc8d8SChris Lattner Error error(process->Halt ()); 139630fdc8d8SChris Lattner if (error.Success()) 139730fdc8d8SChris Lattner { 139830fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 139930fdc8d8SChris Lattner 140030fdc8d8SChris Lattner // Maybe we should add a "SuspendThreadPlans so we 140130fdc8d8SChris Lattner // can halt, and keep in place all the current thread plans. 140230fdc8d8SChris Lattner process->GetThreadList().DiscardThreadPlans(); 140330fdc8d8SChris Lattner } 140430fdc8d8SChris Lattner else 140530fdc8d8SChris Lattner { 140630fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 140730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 140830fdc8d8SChris Lattner } 140930fdc8d8SChris Lattner } 141030fdc8d8SChris Lattner else 141130fdc8d8SChris Lattner { 141230fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 141330fdc8d8SChris Lattner m_cmd_name.c_str(), 141430fdc8d8SChris Lattner m_cmd_syntax.c_str()); 141530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 141630fdc8d8SChris Lattner } 141730fdc8d8SChris Lattner return result.Succeeded(); 141830fdc8d8SChris Lattner } 141930fdc8d8SChris Lattner }; 142030fdc8d8SChris Lattner 142130fdc8d8SChris Lattner //------------------------------------------------------------------------- 142230fdc8d8SChris Lattner // CommandObjectProcessKill 142330fdc8d8SChris Lattner //------------------------------------------------------------------------- 1424bb9caf73SJim Ingham #pragma mark CommandObjectProcessKill 142530fdc8d8SChris Lattner 142630fdc8d8SChris Lattner class CommandObjectProcessKill : public CommandObject 142730fdc8d8SChris Lattner { 142830fdc8d8SChris Lattner public: 142930fdc8d8SChris Lattner 1430a7015092SGreg Clayton CommandObjectProcessKill (CommandInterpreter &interpreter) : 1431a7015092SGreg Clayton CommandObject (interpreter, 1432a7015092SGreg Clayton "process kill", 1433e3d26315SCaroline Tice "Terminate the current process being debugged.", 143430fdc8d8SChris Lattner "process kill", 143530fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 143630fdc8d8SChris Lattner { 143730fdc8d8SChris Lattner } 143830fdc8d8SChris Lattner 143930fdc8d8SChris Lattner ~CommandObjectProcessKill () 144030fdc8d8SChris Lattner { 144130fdc8d8SChris Lattner } 144230fdc8d8SChris Lattner 144330fdc8d8SChris Lattner bool 1444a7015092SGreg Clayton Execute (Args& command, 144530fdc8d8SChris Lattner CommandReturnObject &result) 144630fdc8d8SChris Lattner { 1447a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 144830fdc8d8SChris Lattner if (process == NULL) 144930fdc8d8SChris Lattner { 145030fdc8d8SChris Lattner result.AppendError ("no process to kill"); 145130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 145230fdc8d8SChris Lattner return false; 145330fdc8d8SChris Lattner } 145430fdc8d8SChris Lattner 145530fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 145630fdc8d8SChris Lattner { 145730fdc8d8SChris Lattner Error error (process->Destroy()); 145830fdc8d8SChris Lattner if (error.Success()) 145930fdc8d8SChris Lattner { 146030fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 146130fdc8d8SChris Lattner } 146230fdc8d8SChris Lattner else 146330fdc8d8SChris Lattner { 146430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 146530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 146630fdc8d8SChris Lattner } 146730fdc8d8SChris Lattner } 146830fdc8d8SChris Lattner else 146930fdc8d8SChris Lattner { 147030fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 147130fdc8d8SChris Lattner m_cmd_name.c_str(), 147230fdc8d8SChris Lattner m_cmd_syntax.c_str()); 147330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 147430fdc8d8SChris Lattner } 147530fdc8d8SChris Lattner return result.Succeeded(); 147630fdc8d8SChris Lattner } 147730fdc8d8SChris Lattner }; 147830fdc8d8SChris Lattner 147930fdc8d8SChris Lattner //------------------------------------------------------------------------- 14804b9bea87SJim Ingham // CommandObjectProcessStatus 14814b9bea87SJim Ingham //------------------------------------------------------------------------- 1482bb9caf73SJim Ingham #pragma mark CommandObjectProcessStatus 1483bb9caf73SJim Ingham 14844b9bea87SJim Ingham class CommandObjectProcessStatus : public CommandObject 14854b9bea87SJim Ingham { 14864b9bea87SJim Ingham public: 1487a7015092SGreg Clayton CommandObjectProcessStatus (CommandInterpreter &interpreter) : 1488a7015092SGreg Clayton CommandObject (interpreter, 1489a7015092SGreg Clayton "process status", 1490e3d26315SCaroline Tice "Show the current status and location of executing process.", 1491e3d26315SCaroline Tice "process status", 14924b9bea87SJim Ingham 0) 14934b9bea87SJim Ingham { 14944b9bea87SJim Ingham } 14954b9bea87SJim Ingham 14964b9bea87SJim Ingham ~CommandObjectProcessStatus() 14974b9bea87SJim Ingham { 14984b9bea87SJim Ingham } 14994b9bea87SJim Ingham 15004b9bea87SJim Ingham 15014b9bea87SJim Ingham bool 15024b9bea87SJim Ingham Execute 15034b9bea87SJim Ingham ( 15044b9bea87SJim Ingham Args& command, 15054b9bea87SJim Ingham CommandReturnObject &result 15064b9bea87SJim Ingham ) 15074b9bea87SJim Ingham { 150885e8b814SJim Ingham Stream &output_stream = result.GetOutputStream(); 15094b9bea87SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 1510a7015092SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext()); 15114b9bea87SJim Ingham if (exe_ctx.process) 15124b9bea87SJim Ingham { 15134b9bea87SJim Ingham const StateType state = exe_ctx.process->GetState(); 15144b9bea87SJim Ingham if (StateIsStoppedState(state)) 15154b9bea87SJim Ingham { 15164b9bea87SJim Ingham if (state == eStateExited) 15174b9bea87SJim Ingham { 15184b9bea87SJim Ingham int exit_status = exe_ctx.process->GetExitStatus(); 15194b9bea87SJim Ingham const char *exit_description = exe_ctx.process->GetExitDescription(); 15204b9bea87SJim Ingham output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n", 15214b9bea87SJim Ingham exe_ctx.process->GetID(), 15224b9bea87SJim Ingham exit_status, 15234b9bea87SJim Ingham exit_status, 15244b9bea87SJim Ingham exit_description ? exit_description : ""); 15254b9bea87SJim Ingham } 15264b9bea87SJim Ingham else 15274b9bea87SJim Ingham { 152871337622SGreg Clayton if (state == eStateConnected) 152971337622SGreg Clayton output_stream.Printf ("Connected to remote target.\n"); 153071337622SGreg Clayton else 15314b9bea87SJim Ingham output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state)); 15324b9bea87SJim Ingham if (exe_ctx.thread == NULL) 15334b9bea87SJim Ingham exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); 15344b9bea87SJim Ingham if (exe_ctx.thread != NULL) 15354b9bea87SJim Ingham { 1536a7015092SGreg Clayton DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true); 15374b9bea87SJim Ingham } 15384b9bea87SJim Ingham else 15394b9bea87SJim Ingham { 15404b9bea87SJim Ingham result.AppendError ("No valid thread found in current process."); 15414b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 15424b9bea87SJim Ingham } 15434b9bea87SJim Ingham } 15444b9bea87SJim Ingham } 15454b9bea87SJim Ingham else 15464b9bea87SJim Ingham { 15474b9bea87SJim Ingham output_stream.Printf ("Process %d is running.\n", 15484b9bea87SJim Ingham exe_ctx.process->GetID()); 15494b9bea87SJim Ingham } 15504b9bea87SJim Ingham } 15514b9bea87SJim Ingham else 15524b9bea87SJim Ingham { 15534b9bea87SJim Ingham result.AppendError ("No current location or status available."); 15544b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 15554b9bea87SJim Ingham } 15564b9bea87SJim Ingham return result.Succeeded(); 15574b9bea87SJim Ingham } 15584b9bea87SJim Ingham }; 15594b9bea87SJim Ingham 15604b9bea87SJim Ingham //------------------------------------------------------------------------- 156135731357SCaroline Tice // CommandObjectProcessHandle 156235731357SCaroline Tice //------------------------------------------------------------------------- 1563bb9caf73SJim Ingham #pragma mark CommandObjectProcessHandle 156435731357SCaroline Tice 156535731357SCaroline Tice class CommandObjectProcessHandle : public CommandObject 156635731357SCaroline Tice { 156735731357SCaroline Tice public: 156835731357SCaroline Tice 156935731357SCaroline Tice class CommandOptions : public Options 157035731357SCaroline Tice { 157135731357SCaroline Tice public: 157235731357SCaroline Tice 1573*eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 1574*eb0103f2SGreg Clayton Options (interpreter) 157535731357SCaroline Tice { 157635731357SCaroline Tice ResetOptionValues (); 157735731357SCaroline Tice } 157835731357SCaroline Tice 157935731357SCaroline Tice ~CommandOptions () 158035731357SCaroline Tice { 158135731357SCaroline Tice } 158235731357SCaroline Tice 158335731357SCaroline Tice Error 158435731357SCaroline Tice SetOptionValue (int option_idx, const char *option_arg) 158535731357SCaroline Tice { 158635731357SCaroline Tice Error error; 158735731357SCaroline Tice char short_option = (char) m_getopt_table[option_idx].val; 158835731357SCaroline Tice 158935731357SCaroline Tice switch (short_option) 159035731357SCaroline Tice { 159135731357SCaroline Tice case 's': 159235731357SCaroline Tice stop = option_arg; 159335731357SCaroline Tice break; 159435731357SCaroline Tice case 'n': 159535731357SCaroline Tice notify = option_arg; 159635731357SCaroline Tice break; 159735731357SCaroline Tice case 'p': 159835731357SCaroline Tice pass = option_arg; 159935731357SCaroline Tice break; 160035731357SCaroline Tice default: 160135731357SCaroline Tice error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 160235731357SCaroline Tice break; 160335731357SCaroline Tice } 160435731357SCaroline Tice return error; 160535731357SCaroline Tice } 160635731357SCaroline Tice 160735731357SCaroline Tice void 160835731357SCaroline Tice ResetOptionValues () 160935731357SCaroline Tice { 161035731357SCaroline Tice stop.clear(); 161135731357SCaroline Tice notify.clear(); 161235731357SCaroline Tice pass.clear(); 161335731357SCaroline Tice } 161435731357SCaroline Tice 1615e0d378b3SGreg Clayton const OptionDefinition* 161635731357SCaroline Tice GetDefinitions () 161735731357SCaroline Tice { 161835731357SCaroline Tice return g_option_table; 161935731357SCaroline Tice } 162035731357SCaroline Tice 162135731357SCaroline Tice // Options table: Required for subclasses of Options. 162235731357SCaroline Tice 1623e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 162435731357SCaroline Tice 162535731357SCaroline Tice // Instance variables to hold the values for command options. 162635731357SCaroline Tice 162735731357SCaroline Tice std::string stop; 162835731357SCaroline Tice std::string notify; 162935731357SCaroline Tice std::string pass; 163035731357SCaroline Tice }; 163135731357SCaroline Tice 163235731357SCaroline Tice 163335731357SCaroline Tice CommandObjectProcessHandle (CommandInterpreter &interpreter) : 163435731357SCaroline Tice CommandObject (interpreter, 163535731357SCaroline Tice "process handle", 163610ad7993SCaroline Tice "Show or update what the process and debugger should do with various signals received from the OS.", 1637*eb0103f2SGreg Clayton NULL), 1638*eb0103f2SGreg Clayton m_options (interpreter) 163935731357SCaroline Tice { 164010ad7993SCaroline Tice SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); 164135731357SCaroline Tice CommandArgumentEntry arg; 1642c0dbdfb6SCaroline Tice CommandArgumentData signal_arg; 164335731357SCaroline Tice 1644c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1645c0dbdfb6SCaroline Tice signal_arg.arg_repetition = eArgRepeatStar; 164635731357SCaroline Tice 1647c0dbdfb6SCaroline Tice arg.push_back (signal_arg); 164835731357SCaroline Tice 164935731357SCaroline Tice m_arguments.push_back (arg); 165035731357SCaroline Tice } 165135731357SCaroline Tice 165235731357SCaroline Tice ~CommandObjectProcessHandle () 165335731357SCaroline Tice { 165435731357SCaroline Tice } 165535731357SCaroline Tice 165635731357SCaroline Tice Options * 165735731357SCaroline Tice GetOptions () 165835731357SCaroline Tice { 165935731357SCaroline Tice return &m_options; 166035731357SCaroline Tice } 166135731357SCaroline Tice 166235731357SCaroline Tice bool 166310ad7993SCaroline Tice VerifyCommandOptionValue (const std::string &option, int &real_value) 166435731357SCaroline Tice { 166535731357SCaroline Tice bool okay = true; 166635731357SCaroline Tice 166710ad7993SCaroline Tice bool success = false; 166810ad7993SCaroline Tice bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success); 166910ad7993SCaroline Tice 167010ad7993SCaroline Tice if (success && tmp_value) 167110ad7993SCaroline Tice real_value = 1; 167210ad7993SCaroline Tice else if (success && !tmp_value) 167310ad7993SCaroline Tice real_value = 0; 167435731357SCaroline Tice else 167535731357SCaroline Tice { 167635731357SCaroline Tice // If the value isn't 'true' or 'false', it had better be 0 or 1. 167710ad7993SCaroline Tice real_value = Args::StringToUInt32 (option.c_str(), 3); 167810ad7993SCaroline Tice if (real_value != 0 && real_value != 1) 167935731357SCaroline Tice okay = false; 168035731357SCaroline Tice } 168135731357SCaroline Tice 168235731357SCaroline Tice return okay; 168335731357SCaroline Tice } 168435731357SCaroline Tice 168510ad7993SCaroline Tice void 168610ad7993SCaroline Tice PrintSignalHeader (Stream &str) 168710ad7993SCaroline Tice { 168810ad7993SCaroline Tice str.Printf ("NAME PASS STOP NOTIFY\n"); 168910ad7993SCaroline Tice str.Printf ("========== ===== ===== ======\n"); 169010ad7993SCaroline Tice } 169110ad7993SCaroline Tice 169210ad7993SCaroline Tice void 169310ad7993SCaroline Tice PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) 169410ad7993SCaroline Tice { 169510ad7993SCaroline Tice bool stop; 169610ad7993SCaroline Tice bool suppress; 169710ad7993SCaroline Tice bool notify; 169810ad7993SCaroline Tice 169910ad7993SCaroline Tice str.Printf ("%-10s ", sig_name); 170010ad7993SCaroline Tice if (signals.GetSignalInfo (signo, suppress, stop, notify)) 170110ad7993SCaroline Tice { 170210ad7993SCaroline Tice bool pass = !suppress; 170310ad7993SCaroline Tice str.Printf ("%s %s %s", 170410ad7993SCaroline Tice (pass ? "true " : "false"), 170510ad7993SCaroline Tice (stop ? "true " : "false"), 170610ad7993SCaroline Tice (notify ? "true " : "false")); 170710ad7993SCaroline Tice } 170810ad7993SCaroline Tice str.Printf ("\n"); 170910ad7993SCaroline Tice } 171010ad7993SCaroline Tice 171110ad7993SCaroline Tice void 171210ad7993SCaroline Tice PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) 171310ad7993SCaroline Tice { 171410ad7993SCaroline Tice PrintSignalHeader (str); 171510ad7993SCaroline Tice 171610ad7993SCaroline Tice if (num_valid_signals > 0) 171710ad7993SCaroline Tice { 171810ad7993SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 171910ad7993SCaroline Tice for (size_t i = 0; i < num_args; ++i) 172010ad7993SCaroline Tice { 172110ad7993SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 172210ad7993SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 172310ad7993SCaroline Tice PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); 172410ad7993SCaroline Tice } 172510ad7993SCaroline Tice } 172610ad7993SCaroline Tice else // Print info for ALL signals 172710ad7993SCaroline Tice { 172810ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 172910ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 173010ad7993SCaroline Tice { 173110ad7993SCaroline Tice PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); 173210ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 173310ad7993SCaroline Tice } 173410ad7993SCaroline Tice } 173510ad7993SCaroline Tice } 173610ad7993SCaroline Tice 173735731357SCaroline Tice bool 173835731357SCaroline Tice Execute (Args &signal_args, CommandReturnObject &result) 173935731357SCaroline Tice { 174035731357SCaroline Tice TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 174135731357SCaroline Tice 174235731357SCaroline Tice if (!target_sp) 174335731357SCaroline Tice { 174435731357SCaroline Tice result.AppendError ("No current target;" 174535731357SCaroline Tice " cannot handle signals until you have a valid target and process.\n"); 174635731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 174735731357SCaroline Tice return false; 174835731357SCaroline Tice } 174935731357SCaroline Tice 175035731357SCaroline Tice ProcessSP process_sp = target_sp->GetProcessSP(); 175135731357SCaroline Tice 175235731357SCaroline Tice if (!process_sp) 175335731357SCaroline Tice { 175435731357SCaroline Tice result.AppendError ("No current process; cannot handle signals until you have a valid process.\n"); 175535731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 175635731357SCaroline Tice return false; 175735731357SCaroline Tice } 175835731357SCaroline Tice 175935731357SCaroline Tice int stop_action = -1; // -1 means leave the current setting alone 176035731357SCaroline Tice int pass_action = -1; // -1 means leave the current setting alone 176135731357SCaroline Tice int notify_action = -1; // -1 means leave the current setting alone 176235731357SCaroline Tice 176335731357SCaroline Tice if (! m_options.stop.empty() 176410ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.stop, stop_action)) 176535731357SCaroline Tice { 176635731357SCaroline Tice result.AppendError ("Invalid argument for command option --stop; must be true or false.\n"); 176735731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 176835731357SCaroline Tice return false; 176935731357SCaroline Tice } 177035731357SCaroline Tice 177135731357SCaroline Tice if (! m_options.notify.empty() 177210ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.notify, notify_action)) 177335731357SCaroline Tice { 177435731357SCaroline Tice result.AppendError ("Invalid argument for command option --notify; must be true or false.\n"); 177535731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 177635731357SCaroline Tice return false; 177735731357SCaroline Tice } 177835731357SCaroline Tice 177935731357SCaroline Tice if (! m_options.pass.empty() 178010ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.pass, pass_action)) 178135731357SCaroline Tice { 178235731357SCaroline Tice result.AppendError ("Invalid argument for command option --pass; must be true or false.\n"); 178335731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 178435731357SCaroline Tice return false; 178535731357SCaroline Tice } 178635731357SCaroline Tice 178735731357SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 178835731357SCaroline Tice UnixSignals &signals = process_sp->GetUnixSignals(); 178935731357SCaroline Tice int num_signals_set = 0; 179035731357SCaroline Tice 179110ad7993SCaroline Tice if (num_args > 0) 179210ad7993SCaroline Tice { 179335731357SCaroline Tice for (size_t i = 0; i < num_args; ++i) 179435731357SCaroline Tice { 179535731357SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 179635731357SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 179735731357SCaroline Tice { 179810ad7993SCaroline Tice // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees 179935731357SCaroline Tice // the value is either 0 or 1. 180035731357SCaroline Tice if (stop_action != -1) 180135731357SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 180235731357SCaroline Tice if (pass_action != -1) 180335731357SCaroline Tice { 180410ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 180510ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 180635731357SCaroline Tice } 180735731357SCaroline Tice if (notify_action != -1) 180835731357SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 180935731357SCaroline Tice ++num_signals_set; 181035731357SCaroline Tice } 181135731357SCaroline Tice else 181235731357SCaroline Tice { 181335731357SCaroline Tice result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i)); 181435731357SCaroline Tice } 181535731357SCaroline Tice } 181610ad7993SCaroline Tice } 181710ad7993SCaroline Tice else 181810ad7993SCaroline Tice { 181910ad7993SCaroline Tice // No signal specified, if any command options were specified, update ALL signals. 182010ad7993SCaroline Tice if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) 182110ad7993SCaroline Tice { 182210ad7993SCaroline Tice if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) 182310ad7993SCaroline Tice { 182410ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 182510ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 182610ad7993SCaroline Tice { 182710ad7993SCaroline Tice if (notify_action != -1) 182810ad7993SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 182910ad7993SCaroline Tice if (stop_action != -1) 183010ad7993SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 183110ad7993SCaroline Tice if (pass_action != -1) 183210ad7993SCaroline Tice { 183310ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 183410ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 183510ad7993SCaroline Tice } 183610ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 183710ad7993SCaroline Tice } 183810ad7993SCaroline Tice } 183910ad7993SCaroline Tice } 184010ad7993SCaroline Tice } 184110ad7993SCaroline Tice 184210ad7993SCaroline Tice PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); 184335731357SCaroline Tice 184435731357SCaroline Tice if (num_signals_set > 0) 184535731357SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 184635731357SCaroline Tice else 184735731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 184835731357SCaroline Tice 184935731357SCaroline Tice return result.Succeeded(); 185035731357SCaroline Tice } 185135731357SCaroline Tice 185235731357SCaroline Tice protected: 185335731357SCaroline Tice 185435731357SCaroline Tice CommandOptions m_options; 185535731357SCaroline Tice }; 185635731357SCaroline Tice 1857e0d378b3SGreg Clayton OptionDefinition 185835731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] = 185935731357SCaroline Tice { 186035731357SCaroline Tice { LLDB_OPT_SET_1, false, "stop", 's', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." }, 186135731357SCaroline Tice { LLDB_OPT_SET_1, false, "notify", 'n', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." }, 186235731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass", 'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, 186335731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 186435731357SCaroline Tice }; 186535731357SCaroline Tice 186635731357SCaroline Tice //------------------------------------------------------------------------- 186730fdc8d8SChris Lattner // CommandObjectMultiwordProcess 186830fdc8d8SChris Lattner //------------------------------------------------------------------------- 186930fdc8d8SChris Lattner 18706611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) : 1871a7015092SGreg Clayton CommandObjectMultiword (interpreter, 1872a7015092SGreg Clayton "process", 187330fdc8d8SChris Lattner "A set of commands for operating on a process.", 187430fdc8d8SChris Lattner "process <subcommand> [<subcommand-options>]") 187530fdc8d8SChris Lattner { 1876a7015092SGreg Clayton LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); 1877a7015092SGreg Clayton LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); 1878a7015092SGreg Clayton LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); 1879b766a73dSGreg Clayton LoadSubCommand ("connect", CommandObjectSP (new CommandObjectProcessConnect (interpreter))); 1880a7015092SGreg Clayton LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); 18818f343b09SGreg Clayton LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter))); 18828f343b09SGreg Clayton LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter))); 1883a7015092SGreg Clayton LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); 188435731357SCaroline Tice LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); 1885a7015092SGreg Clayton LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); 1886a7015092SGreg Clayton LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); 1887a7015092SGreg Clayton LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); 188830fdc8d8SChris Lattner } 188930fdc8d8SChris Lattner 189030fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () 189130fdc8d8SChris Lattner { 189230fdc8d8SChris Lattner } 189330fdc8d8SChris Lattner 1894