blob: 82de22a2cfb9e7ffcf55ede8b38dd4d2c08a9434 [file] [log] [blame]
Greg Claytonb1888f22011-03-19 01:12:21 +00001//===-- CommandObjectPlatform.cpp -------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectPlatform.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/DataExtractor.h"
17#include "lldb/Core/Debugger.h"
18#include "lldb/Core/PluginManager.h"
19#include "lldb/Interpreter/Args.h"
20#include "lldb/Interpreter/CommandInterpreter.h"
21#include "lldb/Interpreter/CommandReturnObject.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000022#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000023#include "lldb/Target/ExecutionContext.h"
24#include "lldb/Target/Platform.h"
Greg Claytonf15996e2011-04-07 22:46:35 +000025#include "lldb/Target/Process.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000026
27using namespace lldb;
28using namespace lldb_private;
29
Greg Clayton143fcc32011-04-13 00:18:08 +000030
Greg Claytonb1888f22011-03-19 01:12:21 +000031//----------------------------------------------------------------------
Greg Claytonabe0fed2011-04-18 08:33:37 +000032// "platform select <platform-name>"
Greg Claytonb1888f22011-03-19 01:12:21 +000033//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +000034class CommandObjectPlatformSelect : public CommandObjectParsed
Greg Claytonb1888f22011-03-19 01:12:21 +000035{
36public:
Greg Clayton143fcc32011-04-13 00:18:08 +000037 CommandObjectPlatformSelect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +000038 CommandObjectParsed (interpreter,
39 "platform select",
40 "Create a platform if needed and select it as the current platform.",
41 "platform select <platform-name>",
42 0),
Greg Clayton143fcc32011-04-13 00:18:08 +000043 m_option_group (interpreter),
44 m_platform_options (false) // Don't include the "--platform" option by passing false
Greg Claytonb1888f22011-03-19 01:12:21 +000045 {
Greg Clayton5e342f52011-04-13 22:47:15 +000046 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, 1);
Greg Clayton143fcc32011-04-13 00:18:08 +000047 m_option_group.Finalize();
Greg Claytonb1888f22011-03-19 01:12:21 +000048 }
49
50 virtual
Greg Clayton143fcc32011-04-13 00:18:08 +000051 ~CommandObjectPlatformSelect ()
Greg Claytonb1888f22011-03-19 01:12:21 +000052 {
53 }
54
Jim Inghamda26bd22012-06-08 21:56:10 +000055 virtual int
56 HandleCompletion (Args &input,
57 int &cursor_index,
58 int &cursor_char_position,
59 int match_start_point,
60 int max_return_elements,
61 bool &word_complete,
62 StringList &matches)
63 {
64 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
65 completion_str.erase (cursor_char_position);
66
67 CommandCompletions::PlatformPluginNames (m_interpreter,
68 completion_str.c_str(),
69 match_start_point,
70 max_return_elements,
71 NULL,
72 word_complete,
73 matches);
74 return matches.GetSize();
75 }
76
77 virtual Options *
78 GetOptions ()
79 {
80 return &m_option_group;
81 }
82
83protected:
Greg Claytonb1888f22011-03-19 01:12:21 +000084 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +000085 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonb1888f22011-03-19 01:12:21 +000086 {
Greg Claytonb1888f22011-03-19 01:12:21 +000087 if (args.GetArgumentCount() == 1)
88 {
Greg Clayton5e342f52011-04-13 22:47:15 +000089 const char *platform_name = args.GetArgumentAtIndex (0);
90 if (platform_name && platform_name[0])
91 {
92 const bool select = true;
Greg Claytonabe0fed2011-04-18 08:33:37 +000093 m_platform_options.SetPlatformName (platform_name);
Greg Clayton5e342f52011-04-13 22:47:15 +000094 Error error;
Greg Claytonb170aee2012-05-08 01:45:38 +000095 ArchSpec platform_arch;
96 PlatformSP platform_sp (m_platform_options.CreatePlatformWithOptions (m_interpreter, ArchSpec(), select, error, platform_arch));
Greg Clayton5e342f52011-04-13 22:47:15 +000097 if (platform_sp)
98 {
99 platform_sp->GetStatus (result.GetOutputStream());
100 result.SetStatus (eReturnStatusSuccessFinishResult);
101 }
102 else
103 {
104 result.AppendError(error.AsCString());
105 result.SetStatus (eReturnStatusFailed);
106 }
107 }
108 else
109 {
110 result.AppendError ("invalid platform name");
111 result.SetStatus (eReturnStatusFailed);
112 }
Greg Claytonb1888f22011-03-19 01:12:21 +0000113 }
114 else
115 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000116 result.AppendError ("platform create takes a platform name as an argument\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000117 result.SetStatus (eReturnStatusFailed);
118 }
119 return result.Succeeded();
120 }
Greg Claytonabe0fed2011-04-18 08:33:37 +0000121
Greg Clayton143fcc32011-04-13 00:18:08 +0000122 OptionGroupOptions m_option_group;
Greg Claytonabe0fed2011-04-18 08:33:37 +0000123 OptionGroupPlatform m_platform_options;
Greg Claytonb1888f22011-03-19 01:12:21 +0000124};
125
126//----------------------------------------------------------------------
127// "platform list"
128//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000129class CommandObjectPlatformList : public CommandObjectParsed
Greg Claytonb1888f22011-03-19 01:12:21 +0000130{
131public:
132 CommandObjectPlatformList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000133 CommandObjectParsed (interpreter,
134 "platform list",
135 "List all platforms that are available.",
136 NULL,
137 0)
Greg Claytonb1888f22011-03-19 01:12:21 +0000138 {
139 }
140
141 virtual
142 ~CommandObjectPlatformList ()
143 {
144 }
145
Jim Inghamda26bd22012-06-08 21:56:10 +0000146protected:
Greg Claytonb1888f22011-03-19 01:12:21 +0000147 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000148 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonb1888f22011-03-19 01:12:21 +0000149 {
150 Stream &ostrm = result.GetOutputStream();
151 ostrm.Printf("Available platforms:\n");
152
153 PlatformSP host_platform_sp (Platform::GetDefaultPlatform());
154 ostrm.Printf ("%s: %s\n",
155 host_platform_sp->GetShortPluginName(),
156 host_platform_sp->GetDescription());
157
158 uint32_t idx;
159 for (idx = 0; 1; ++idx)
160 {
161 const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (idx);
162 if (plugin_name == NULL)
163 break;
164 const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (idx);
165 if (plugin_desc == NULL)
166 break;
167 ostrm.Printf("%s: %s\n", plugin_name, plugin_desc);
168 }
169
170 if (idx == 0)
171 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000172 result.AppendError ("no platforms are available\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000173 result.SetStatus (eReturnStatusFailed);
174 }
Johnny Chen08150312011-03-30 21:19:59 +0000175 else
176 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonb1888f22011-03-19 01:12:21 +0000177 return result.Succeeded();
178 }
179};
180
181//----------------------------------------------------------------------
182// "platform status"
183//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000184class CommandObjectPlatformStatus : public CommandObjectParsed
Greg Claytonb1888f22011-03-19 01:12:21 +0000185{
186public:
187 CommandObjectPlatformStatus (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000188 CommandObjectParsed (interpreter,
189 "platform status",
190 "Display status for the currently selected platform.",
191 NULL,
192 0)
Greg Claytonb1888f22011-03-19 01:12:21 +0000193 {
194 }
195
196 virtual
197 ~CommandObjectPlatformStatus ()
198 {
199 }
200
Jim Inghamda26bd22012-06-08 21:56:10 +0000201protected:
Greg Claytonb1888f22011-03-19 01:12:21 +0000202 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000203 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonb1888f22011-03-19 01:12:21 +0000204 {
205 Stream &ostrm = result.GetOutputStream();
206
Greg Claytonff39f742011-04-01 00:29:43 +0000207 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
208 if (platform_sp)
Greg Claytonb1888f22011-03-19 01:12:21 +0000209 {
Greg Claytonff39f742011-04-01 00:29:43 +0000210 platform_sp->GetStatus (ostrm);
Greg Claytonb1888f22011-03-19 01:12:21 +0000211 result.SetStatus (eReturnStatusSuccessFinishResult);
212 }
213 else
214 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000215 result.AppendError ("no platform us currently selected\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000216 result.SetStatus (eReturnStatusFailed);
217 }
218 return result.Succeeded();
219 }
220};
221
Greg Claytoncb8977d2011-03-23 00:09:55 +0000222//----------------------------------------------------------------------
223// "platform connect <connect-url>"
224//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000225class CommandObjectPlatformConnect : public CommandObjectParsed
Greg Claytoncb8977d2011-03-23 00:09:55 +0000226{
227public:
228 CommandObjectPlatformConnect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000229 CommandObjectParsed (interpreter,
230 "platform connect",
231 "Connect a platform by name to be the currently selected platform.",
232 "platform connect <connect-url>",
233 0)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000234 {
235 }
236
237 virtual
238 ~CommandObjectPlatformConnect ()
239 {
240 }
241
Jim Inghamda26bd22012-06-08 21:56:10 +0000242protected:
Greg Claytoncb8977d2011-03-23 00:09:55 +0000243 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000244 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000245 {
246 Stream &ostrm = result.GetOutputStream();
247
Greg Claytonff39f742011-04-01 00:29:43 +0000248 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
249 if (platform_sp)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000250 {
Greg Claytonff39f742011-04-01 00:29:43 +0000251 Error error (platform_sp->ConnectRemote (args));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000252 if (error.Success())
253 {
Greg Claytonff39f742011-04-01 00:29:43 +0000254 platform_sp->GetStatus (ostrm);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000255 result.SetStatus (eReturnStatusSuccessFinishResult);
256 }
257 else
258 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000259 result.AppendErrorWithFormat ("%s\n", error.AsCString());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000260 result.SetStatus (eReturnStatusFailed);
261 }
262 }
263 else
264 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000265 result.AppendError ("no platform us currently selected\n");
Greg Claytoncb8977d2011-03-23 00:09:55 +0000266 result.SetStatus (eReturnStatusFailed);
267 }
268 return result.Succeeded();
269 }
270};
271
272//----------------------------------------------------------------------
273// "platform disconnect"
274//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000275class CommandObjectPlatformDisconnect : public CommandObjectParsed
Greg Claytoncb8977d2011-03-23 00:09:55 +0000276{
277public:
278 CommandObjectPlatformDisconnect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000279 CommandObjectParsed (interpreter,
280 "platform disconnect",
281 "Disconnect a platform by name to be the currently selected platform.",
282 "platform disconnect",
283 0)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000284 {
285 }
286
287 virtual
288 ~CommandObjectPlatformDisconnect ()
289 {
290 }
291
Jim Inghamda26bd22012-06-08 21:56:10 +0000292protected:
Greg Claytoncb8977d2011-03-23 00:09:55 +0000293 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000294 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000295 {
Greg Claytonff39f742011-04-01 00:29:43 +0000296 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
297 if (platform_sp)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000298 {
299 if (args.GetArgumentCount() == 0)
300 {
301 Error error;
302
Greg Claytonff39f742011-04-01 00:29:43 +0000303 if (platform_sp->IsConnected())
Greg Claytoncb8977d2011-03-23 00:09:55 +0000304 {
305 // Cache the instance name if there is one since we are
306 // about to disconnect and the name might go with it.
Greg Claytonff39f742011-04-01 00:29:43 +0000307 const char *hostname_cstr = platform_sp->GetHostname();
Greg Clayton58e26e02011-03-24 04:28:38 +0000308 std::string hostname;
309 if (hostname_cstr)
310 hostname.assign (hostname_cstr);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000311
Greg Claytonff39f742011-04-01 00:29:43 +0000312 error = platform_sp->DisconnectRemote ();
Greg Claytoncb8977d2011-03-23 00:09:55 +0000313 if (error.Success())
314 {
315 Stream &ostrm = result.GetOutputStream();
Greg Clayton58e26e02011-03-24 04:28:38 +0000316 if (hostname.empty())
Greg Claytonff39f742011-04-01 00:29:43 +0000317 ostrm.Printf ("Disconnected from \"%s\"\n", platform_sp->GetShortPluginName());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000318 else
Greg Clayton58e26e02011-03-24 04:28:38 +0000319 ostrm.Printf ("Disconnected from \"%s\"\n", hostname.c_str());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000320 result.SetStatus (eReturnStatusSuccessFinishResult);
321 }
322 else
323 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000324 result.AppendErrorWithFormat ("%s", error.AsCString());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000325 result.SetStatus (eReturnStatusFailed);
326 }
327 }
328 else
329 {
330 // Not connected...
Greg Claytonff39f742011-04-01 00:29:43 +0000331 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000332 result.SetStatus (eReturnStatusFailed);
333 }
334 }
335 else
336 {
337 // Bad args
338 result.AppendError ("\"platform disconnect\" doesn't take any arguments");
339 result.SetStatus (eReturnStatusFailed);
340 }
341 }
342 else
343 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000344 result.AppendError ("no platform is currently selected");
Greg Claytoncb8977d2011-03-23 00:09:55 +0000345 result.SetStatus (eReturnStatusFailed);
346 }
347 return result.Succeeded();
348 }
349};
Greg Claytonb72d0f02011-04-12 05:54:46 +0000350//----------------------------------------------------------------------
351// "platform process launch"
352//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000353class CommandObjectPlatformProcessLaunch : public CommandObjectParsed
Greg Claytonb72d0f02011-04-12 05:54:46 +0000354{
355public:
356 CommandObjectPlatformProcessLaunch (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000357 CommandObjectParsed (interpreter,
358 "platform process launch",
359 "Launch a new process on a remote platform.",
360 "platform process launch program",
361 0),
Greg Claytonb72d0f02011-04-12 05:54:46 +0000362 m_options (interpreter)
363 {
364 }
365
366 virtual
367 ~CommandObjectPlatformProcessLaunch ()
368 {
369 }
370
Jim Inghamda26bd22012-06-08 21:56:10 +0000371 virtual Options *
372 GetOptions ()
373 {
374 return &m_options;
375 }
376
377protected:
Greg Claytonb72d0f02011-04-12 05:54:46 +0000378 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000379 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000380 {
381 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
382
383 if (platform_sp)
384 {
385 Error error;
386 const uint32_t argc = args.GetArgumentCount();
Greg Clayton567e7f32011-09-22 04:58:26 +0000387 Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
Greg Claytonabb33022011-11-08 02:43:13 +0000388 if (target == NULL)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000389 {
Greg Claytonabb33022011-11-08 02:43:13 +0000390 result.AppendError ("invalid target, create a debug target using the 'target create' command");
391 result.SetStatus (eReturnStatusFailed);
392 return false;
393 }
394
395 Module *exe_module = target->GetExecutableModulePointer();
396 if (exe_module)
397 {
398 m_options.launch_info.GetExecutableFile () = exe_module->GetFileSpec();
399 char exe_path[PATH_MAX];
400 if (m_options.launch_info.GetExecutableFile ().GetPath (exe_path, sizeof(exe_path)))
401 m_options.launch_info.GetArguments().AppendArgument (exe_path);
402 m_options.launch_info.GetArchitecture() = exe_module->GetArchitecture();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000403 }
404
405 if (argc > 0)
406 {
407 if (m_options.launch_info.GetExecutableFile ())
408 {
409 // We already have an executable file, so we will use this
410 // and all arguments to this function are extra arguments
411 m_options.launch_info.GetArguments().AppendArguments (args);
412 }
413 else
414 {
415 // We don't have any file yet, so the first argument is our
416 // executable, and the rest are program arguments
417 const bool first_arg_is_executable = true;
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000418 m_options.launch_info.SetArguments (args,
419 first_arg_is_executable,
420 first_arg_is_executable);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000421 }
422 }
423
424 if (m_options.launch_info.GetExecutableFile ())
425 {
426 Debugger &debugger = m_interpreter.GetDebugger();
427
428 if (argc == 0)
Greg Clayton73844aa2012-08-22 17:17:09 +0000429 target->GetRunArguments(m_options.launch_info.GetArguments());
Greg Claytonb72d0f02011-04-12 05:54:46 +0000430
431 ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info,
432 debugger,
433 target,
434 debugger.GetListener(),
435 error));
436 if (process_sp && process_sp->IsAlive())
437 {
438 result.SetStatus (eReturnStatusSuccessFinishNoResult);
439 return true;
440 }
441
442 if (error.Success())
443 result.AppendError ("process launch failed");
444 else
445 result.AppendError (error.AsCString());
446 result.SetStatus (eReturnStatusFailed);
447 }
448 else
449 {
450 result.AppendError ("'platform process launch' uses the current target file and arguments, or the executable and its arguments can be specified in this command");
451 result.SetStatus (eReturnStatusFailed);
452 return false;
453 }
454 }
455 else
456 {
457 result.AppendError ("no platform is selected\n");
458 }
459 return result.Succeeded();
460 }
461
Greg Claytonb72d0f02011-04-12 05:54:46 +0000462protected:
463 ProcessLaunchCommandOptions m_options;
464};
465
Greg Claytoncb8977d2011-03-23 00:09:55 +0000466
467
Greg Clayton24bc5d92011-03-30 18:16:51 +0000468//----------------------------------------------------------------------
469// "platform process list"
470//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000471class CommandObjectPlatformProcessList : public CommandObjectParsed
Greg Clayton24bc5d92011-03-30 18:16:51 +0000472{
473public:
474 CommandObjectPlatformProcessList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000475 CommandObjectParsed (interpreter,
476 "platform process list",
477 "List processes on a remote platform by name, pid, or many other matching attributes.",
478 "platform process list",
479 0),
Greg Claytonf15996e2011-04-07 22:46:35 +0000480 m_options (interpreter)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000481 {
482 }
483
484 virtual
485 ~CommandObjectPlatformProcessList ()
486 {
487 }
488
Jim Inghamda26bd22012-06-08 21:56:10 +0000489 virtual Options *
490 GetOptions ()
491 {
492 return &m_options;
493 }
494
495protected:
Greg Clayton24bc5d92011-03-30 18:16:51 +0000496 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000497 DoExecute (Args& args, CommandReturnObject &result)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000498 {
499 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
500
501 if (platform_sp)
502 {
503 Error error;
504 if (args.GetArgumentCount() == 0)
505 {
506
507 if (platform_sp)
508 {
Greg Claytonff39f742011-04-01 00:29:43 +0000509 Stream &ostrm = result.GetOutputStream();
510
Greg Clayton24bc5d92011-03-30 18:16:51 +0000511 lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
512 if (pid != LLDB_INVALID_PROCESS_ID)
513 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000514 ProcessInstanceInfo proc_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000515 if (platform_sp->GetProcessInfo (pid, proc_info))
516 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000517 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
518 proc_info.DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000519 result.SetStatus (eReturnStatusSuccessFinishResult);
520 }
521 else
522 {
Greg Claytond9919d32011-12-01 23:28:38 +0000523 result.AppendErrorWithFormat ("no process found with pid = %llu\n", pid);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000524 result.SetStatus (eReturnStatusFailed);
525 }
526 }
527 else
528 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000529 ProcessInstanceInfoList proc_infos;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000530 const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000531 const char *match_desc = NULL;
532 const char *match_name = m_options.match_info.GetProcessInfo().GetName();
533 if (match_name && match_name[0])
534 {
535 switch (m_options.match_info.GetNameMatchType())
536 {
537 case eNameMatchIgnore: break;
538 case eNameMatchEquals: match_desc = "matched"; break;
539 case eNameMatchContains: match_desc = "contained"; break;
540 case eNameMatchStartsWith: match_desc = "started with"; break;
541 case eNameMatchEndsWith: match_desc = "ended with"; break;
542 case eNameMatchRegularExpression: match_desc = "matched the regular expression"; break;
543 }
544 }
545
Greg Clayton24bc5d92011-03-30 18:16:51 +0000546 if (matches == 0)
547 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000548 if (match_desc)
549 result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n",
550 match_desc,
551 match_name,
552 platform_sp->GetShortPluginName());
553 else
554 result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetShortPluginName());
555 result.SetStatus (eReturnStatusFailed);
556 }
557 else
558 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000559 result.AppendMessageWithFormat ("%u matching process%s found on \"%s\"",
560 matches,
561 matches > 1 ? "es were" : " was",
562 platform_sp->GetName());
563 if (match_desc)
564 result.AppendMessageWithFormat (" whose name %s \"%s\"",
565 match_desc,
566 match_name);
567 result.AppendMessageWithFormat ("\n");
568 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000569 for (uint32_t i=0; i<matches; ++i)
570 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000571 proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000572 }
573 }
574 }
575 }
576 }
577 else
578 {
579 result.AppendError ("invalid args: process list takes only options\n");
580 result.SetStatus (eReturnStatusFailed);
581 }
582 }
583 else
584 {
585 result.AppendError ("no platform is selected\n");
586 result.SetStatus (eReturnStatusFailed);
587 }
588 return result.Succeeded();
589 }
590
Greg Clayton24bc5d92011-03-30 18:16:51 +0000591 class CommandOptions : public Options
592 {
593 public:
594
Greg Claytonf15996e2011-04-07 22:46:35 +0000595 CommandOptions (CommandInterpreter &interpreter) :
596 Options (interpreter),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000597 match_info ()
598 {
599 }
600
601 virtual
602 ~CommandOptions ()
603 {
604 }
605
606 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000607 SetOptionValue (uint32_t option_idx, const char *option_arg)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000608 {
609 Error error;
610 char short_option = (char) m_getopt_table[option_idx].val;
611 bool success = false;
612
613 switch (short_option)
614 {
615 case 'p':
616 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
617 if (!success)
618 error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
619 break;
620
621 case 'P':
622 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
623 if (!success)
624 error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
625 break;
626
627 case 'u':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000628 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000629 if (!success)
630 error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
631 break;
632
633 case 'U':
634 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
635 if (!success)
636 error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
637 break;
638
639 case 'g':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000640 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000641 if (!success)
642 error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
643 break;
644
645 case 'G':
646 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
647 if (!success)
648 error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
649 break;
650
651 case 'a':
Greg Claytonf15996e2011-04-07 22:46:35 +0000652 match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg, m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform().get());
Greg Clayton24bc5d92011-03-30 18:16:51 +0000653 break;
654
655 case 'n':
Greg Clayton527154d2011-11-15 03:53:30 +0000656 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000657 match_info.SetNameMatchType (eNameMatchEquals);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000658 break;
659
660 case 'e':
Greg Clayton527154d2011-11-15 03:53:30 +0000661 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000662 match_info.SetNameMatchType (eNameMatchEndsWith);
663 break;
664
665 case 's':
Greg Clayton527154d2011-11-15 03:53:30 +0000666 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000667 match_info.SetNameMatchType (eNameMatchStartsWith);
668 break;
669
670 case 'c':
Greg Clayton527154d2011-11-15 03:53:30 +0000671 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000672 match_info.SetNameMatchType (eNameMatchContains);
673 break;
674
675 case 'r':
Greg Clayton527154d2011-11-15 03:53:30 +0000676 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000677 match_info.SetNameMatchType (eNameMatchRegularExpression);
678 break;
679
Greg Claytonb72d0f02011-04-12 05:54:46 +0000680 case 'A':
681 show_args = true;
682 break;
683
684 case 'v':
685 verbose = true;
686 break;
687
Greg Clayton24bc5d92011-03-30 18:16:51 +0000688 default:
689 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
690 break;
691 }
692
693 return error;
694 }
695
696 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000697 OptionParsingStarting ()
Greg Clayton24bc5d92011-03-30 18:16:51 +0000698 {
699 match_info.Clear();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000700 show_args = false;
701 verbose = false;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000702 }
703
704 const OptionDefinition*
705 GetDefinitions ()
706 {
707 return g_option_table;
708 }
709
710 // Options table: Required for subclasses of Options.
711
712 static OptionDefinition g_option_table[];
713
714 // Instance variables to hold the values for command options.
715
Greg Claytonb72d0f02011-04-12 05:54:46 +0000716 ProcessInstanceInfoMatch match_info;
717 bool show_args;
718 bool verbose;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000719 };
720 CommandOptions m_options;
721};
722
723OptionDefinition
724CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
725{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000726{ LLDB_OPT_SET_1, false, "pid" , 'p', required_argument, NULL, 0, eArgTypePid , "List the process info for a specific process ID." },
727{ LLDB_OPT_SET_2, true , "name" , 'n', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." },
728{ LLDB_OPT_SET_3, true , "ends-with" , 'e', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that end with a string." },
729{ LLDB_OPT_SET_4, true , "starts-with" , 's', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that start with a string." },
730{ LLDB_OPT_SET_5, true , "contains" , 'c', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that contain a string." },
731{ LLDB_OPT_SET_6, true , "regex" , 'r', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that match a regular expression." },
732{ ~LLDB_OPT_SET_1, false, "parent" , 'P', required_argument, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
733{ ~LLDB_OPT_SET_1, false, "uid" , 'u', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching user ID." },
734{ ~LLDB_OPT_SET_1, false, "euid" , 'U', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective user ID." },
735{ ~LLDB_OPT_SET_1, false, "gid" , 'g', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching group ID." },
736{ ~LLDB_OPT_SET_1, false, "egid" , 'G', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective group ID." },
737{ ~LLDB_OPT_SET_1, false, "arch" , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
738{ LLDB_OPT_SET_ALL, false, "show-args" , 'A', no_argument , NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." },
739{ LLDB_OPT_SET_ALL, false, "verbose" , 'v', no_argument , NULL, 0, eArgTypeNone , "Enable verbose output." },
740{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000741};
742
Greg Claytonff39f742011-04-01 00:29:43 +0000743//----------------------------------------------------------------------
744// "platform process info"
745//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000746class CommandObjectPlatformProcessInfo : public CommandObjectParsed
Greg Claytonff39f742011-04-01 00:29:43 +0000747{
748public:
749 CommandObjectPlatformProcessInfo (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000750 CommandObjectParsed (interpreter,
751 "platform process info",
752 "Get detailed information for one or more process by process ID.",
753 "platform process info <pid> [<pid> <pid> ...]",
754 0)
Greg Claytonff39f742011-04-01 00:29:43 +0000755 {
756 CommandArgumentEntry arg;
757 CommandArgumentData pid_args;
758
759 // Define the first (and only) variant of this arg.
760 pid_args.arg_type = eArgTypePid;
761 pid_args.arg_repetition = eArgRepeatStar;
762
763 // There is only one variant this argument could be; put it into the argument entry.
764 arg.push_back (pid_args);
765
766 // Push the data for the first argument into the m_arguments vector.
767 m_arguments.push_back (arg);
768 }
769
770 virtual
771 ~CommandObjectPlatformProcessInfo ()
772 {
773 }
774
Jim Inghamda26bd22012-06-08 21:56:10 +0000775protected:
Greg Claytonff39f742011-04-01 00:29:43 +0000776 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000777 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonff39f742011-04-01 00:29:43 +0000778 {
779 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
780 if (platform_sp)
781 {
782 const size_t argc = args.GetArgumentCount();
783 if (argc > 0)
784 {
785 Error error;
786
787 if (platform_sp->IsConnected())
788 {
789 Stream &ostrm = result.GetOutputStream();
790 bool success;
791 for (size_t i=0; i<argc; ++ i)
792 {
793 const char *arg = args.GetArgumentAtIndex(i);
794 lldb::pid_t pid = Args::StringToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success);
795 if (success)
796 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000797 ProcessInstanceInfo proc_info;
Greg Claytonff39f742011-04-01 00:29:43 +0000798 if (platform_sp->GetProcessInfo (pid, proc_info))
799 {
Greg Claytond9919d32011-12-01 23:28:38 +0000800 ostrm.Printf ("Process information for process %llu:\n", pid);
Greg Claytonff39f742011-04-01 00:29:43 +0000801 proc_info.Dump (ostrm, platform_sp.get());
802 }
803 else
804 {
Greg Claytond9919d32011-12-01 23:28:38 +0000805 ostrm.Printf ("error: no process information is available for process %llu\n", pid);
Greg Claytonff39f742011-04-01 00:29:43 +0000806 }
807 ostrm.EOL();
808 }
809 else
810 {
811 result.AppendErrorWithFormat ("invalid process ID argument '%s'", arg);
812 result.SetStatus (eReturnStatusFailed);
813 break;
814 }
815 }
816 }
817 else
818 {
819 // Not connected...
820 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName());
821 result.SetStatus (eReturnStatusFailed);
822 }
823 }
824 else
825 {
Johnny Chen1736fef2011-05-09 19:05:46 +0000826 // No args
827 result.AppendError ("one or more process id(s) must be specified");
Greg Claytonff39f742011-04-01 00:29:43 +0000828 result.SetStatus (eReturnStatusFailed);
829 }
830 }
831 else
832 {
833 result.AppendError ("no platform is currently selected");
834 result.SetStatus (eReturnStatusFailed);
835 }
836 return result.Succeeded();
837 }
838};
839
840
841
842
Greg Clayton24bc5d92011-03-30 18:16:51 +0000843class CommandObjectPlatformProcess : public CommandObjectMultiword
844{
845public:
846 //------------------------------------------------------------------
847 // Constructors and Destructors
848 //------------------------------------------------------------------
849 CommandObjectPlatformProcess (CommandInterpreter &interpreter) :
850 CommandObjectMultiword (interpreter,
851 "platform process",
852 "A set of commands to query, launch and attach to platform processes",
853 "platform process [attach|launch|list] ...")
854 {
855// LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
Greg Claytonb72d0f02011-04-12 05:54:46 +0000856 LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
Greg Claytonff39f742011-04-01 00:29:43 +0000857 LoadSubCommand ("info" , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000858 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
859
860 }
861
862 virtual
863 ~CommandObjectPlatformProcess ()
864 {
865 }
866
867private:
868 //------------------------------------------------------------------
869 // For CommandObjectPlatform only
870 //------------------------------------------------------------------
871 DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformProcess);
872};
Greg Claytonb1888f22011-03-19 01:12:21 +0000873
Greg Clayton97471182012-04-14 01:42:46 +0000874
Jim Inghamda26bd22012-06-08 21:56:10 +0000875class CommandObjectPlatformShell : public CommandObjectRaw
Greg Clayton97471182012-04-14 01:42:46 +0000876{
877public:
878 CommandObjectPlatformShell (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000879 CommandObjectRaw (interpreter,
880 "platform shell",
881 "Run a shell command on a the selected platform.",
882 "platform shell <shell-command>",
883 0)
Greg Clayton97471182012-04-14 01:42:46 +0000884 {
885 }
886
887 virtual
888 ~CommandObjectPlatformShell ()
889 {
890 }
891
Jim Inghamda26bd22012-06-08 21:56:10 +0000892protected:
Greg Clayton97471182012-04-14 01:42:46 +0000893 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000894 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Greg Clayton97471182012-04-14 01:42:46 +0000895 {
896 // TODO: Implement "Platform::RunShellCommand()" and switch over to using
897 // the current platform when it is in the interface.
898 const char *working_dir = NULL;
899 std::string output;
900 int status = -1;
901 int signo = -1;
902 Error error (Host::RunShellCommand (raw_command_line, working_dir, &status, &signo, &output, 10));
903 if (!output.empty())
904 result.GetOutputStream().PutCString(output.c_str());
905 if (status > 0)
906 {
907 if (signo > 0)
908 {
909 const char *signo_cstr = Host::GetSignalAsCString(signo);
910 if (signo_cstr)
911 result.GetOutputStream().Printf("error: command returned with status %i and signal %s\n", status, signo_cstr);
912 else
913 result.GetOutputStream().Printf("error: command returned with status %i and signal %i\n", status, signo);
914 }
915 else
916 result.GetOutputStream().Printf("error: command returned with status %i\n", status);
917 }
918
919 if (error.Fail())
920 {
921 result.AppendError(error.AsCString());
922 result.SetStatus (eReturnStatusFailed);
923 }
924 else
925 {
926 result.SetStatus (eReturnStatusSuccessFinishResult);
927 }
928 return true;
929 }
Greg Clayton97471182012-04-14 01:42:46 +0000930};
931
Greg Claytonb1888f22011-03-19 01:12:21 +0000932//----------------------------------------------------------------------
933// CommandObjectPlatform constructor
934//----------------------------------------------------------------------
935CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
936 CommandObjectMultiword (interpreter,
937 "platform",
938 "A set of commands to manage and create platforms.",
Greg Clayton143fcc32011-04-13 00:18:08 +0000939 "platform [connect|disconnect|info|list|status|select] ...")
Greg Claytonb1888f22011-03-19 01:12:21 +0000940{
Greg Claytonb1888f22011-03-19 01:12:21 +0000941 LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
Greg Clayton143fcc32011-04-13 00:18:08 +0000942 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000943 LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000944 LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
945 LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000946 LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
Greg Clayton97471182012-04-14 01:42:46 +0000947 LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000948}
949
950
951//----------------------------------------------------------------------
952// Destructor
953//----------------------------------------------------------------------
954CommandObjectPlatform::~CommandObjectPlatform()
955{
956}