blob: 7487f8aa07071085a3d5cd6c10accf78a8de0923 [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)
429 {
Greg Claytonabb33022011-11-08 02:43:13 +0000430 const Args &target_settings_args = target->GetRunArguments();
431 if (target_settings_args.GetArgumentCount())
432 m_options.launch_info.GetArguments() = target_settings_args;
Greg Claytonb72d0f02011-04-12 05:54:46 +0000433 }
434
435 ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info,
436 debugger,
437 target,
438 debugger.GetListener(),
439 error));
440 if (process_sp && process_sp->IsAlive())
441 {
442 result.SetStatus (eReturnStatusSuccessFinishNoResult);
443 return true;
444 }
445
446 if (error.Success())
447 result.AppendError ("process launch failed");
448 else
449 result.AppendError (error.AsCString());
450 result.SetStatus (eReturnStatusFailed);
451 }
452 else
453 {
454 result.AppendError ("'platform process launch' uses the current target file and arguments, or the executable and its arguments can be specified in this command");
455 result.SetStatus (eReturnStatusFailed);
456 return false;
457 }
458 }
459 else
460 {
461 result.AppendError ("no platform is selected\n");
462 }
463 return result.Succeeded();
464 }
465
Greg Claytonb72d0f02011-04-12 05:54:46 +0000466protected:
467 ProcessLaunchCommandOptions m_options;
468};
469
Greg Claytoncb8977d2011-03-23 00:09:55 +0000470
471
Greg Clayton24bc5d92011-03-30 18:16:51 +0000472//----------------------------------------------------------------------
473// "platform process list"
474//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000475class CommandObjectPlatformProcessList : public CommandObjectParsed
Greg Clayton24bc5d92011-03-30 18:16:51 +0000476{
477public:
478 CommandObjectPlatformProcessList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000479 CommandObjectParsed (interpreter,
480 "platform process list",
481 "List processes on a remote platform by name, pid, or many other matching attributes.",
482 "platform process list",
483 0),
Greg Claytonf15996e2011-04-07 22:46:35 +0000484 m_options (interpreter)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000485 {
486 }
487
488 virtual
489 ~CommandObjectPlatformProcessList ()
490 {
491 }
492
Jim Inghamda26bd22012-06-08 21:56:10 +0000493 virtual Options *
494 GetOptions ()
495 {
496 return &m_options;
497 }
498
499protected:
Greg Clayton24bc5d92011-03-30 18:16:51 +0000500 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000501 DoExecute (Args& args, CommandReturnObject &result)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000502 {
503 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
504
505 if (platform_sp)
506 {
507 Error error;
508 if (args.GetArgumentCount() == 0)
509 {
510
511 if (platform_sp)
512 {
Greg Claytonff39f742011-04-01 00:29:43 +0000513 Stream &ostrm = result.GetOutputStream();
514
Greg Clayton24bc5d92011-03-30 18:16:51 +0000515 lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
516 if (pid != LLDB_INVALID_PROCESS_ID)
517 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000518 ProcessInstanceInfo proc_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000519 if (platform_sp->GetProcessInfo (pid, proc_info))
520 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000521 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
522 proc_info.DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000523 result.SetStatus (eReturnStatusSuccessFinishResult);
524 }
525 else
526 {
Greg Claytond9919d32011-12-01 23:28:38 +0000527 result.AppendErrorWithFormat ("no process found with pid = %llu\n", pid);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000528 result.SetStatus (eReturnStatusFailed);
529 }
530 }
531 else
532 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000533 ProcessInstanceInfoList proc_infos;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000534 const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000535 const char *match_desc = NULL;
536 const char *match_name = m_options.match_info.GetProcessInfo().GetName();
537 if (match_name && match_name[0])
538 {
539 switch (m_options.match_info.GetNameMatchType())
540 {
541 case eNameMatchIgnore: break;
542 case eNameMatchEquals: match_desc = "matched"; break;
543 case eNameMatchContains: match_desc = "contained"; break;
544 case eNameMatchStartsWith: match_desc = "started with"; break;
545 case eNameMatchEndsWith: match_desc = "ended with"; break;
546 case eNameMatchRegularExpression: match_desc = "matched the regular expression"; break;
547 }
548 }
549
Greg Clayton24bc5d92011-03-30 18:16:51 +0000550 if (matches == 0)
551 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000552 if (match_desc)
553 result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n",
554 match_desc,
555 match_name,
556 platform_sp->GetShortPluginName());
557 else
558 result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetShortPluginName());
559 result.SetStatus (eReturnStatusFailed);
560 }
561 else
562 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000563 result.AppendMessageWithFormat ("%u matching process%s found on \"%s\"",
564 matches,
565 matches > 1 ? "es were" : " was",
566 platform_sp->GetName());
567 if (match_desc)
568 result.AppendMessageWithFormat (" whose name %s \"%s\"",
569 match_desc,
570 match_name);
571 result.AppendMessageWithFormat ("\n");
572 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000573 for (uint32_t i=0; i<matches; ++i)
574 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000575 proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000576 }
577 }
578 }
579 }
580 }
581 else
582 {
583 result.AppendError ("invalid args: process list takes only options\n");
584 result.SetStatus (eReturnStatusFailed);
585 }
586 }
587 else
588 {
589 result.AppendError ("no platform is selected\n");
590 result.SetStatus (eReturnStatusFailed);
591 }
592 return result.Succeeded();
593 }
594
Greg Clayton24bc5d92011-03-30 18:16:51 +0000595 class CommandOptions : public Options
596 {
597 public:
598
Greg Claytonf15996e2011-04-07 22:46:35 +0000599 CommandOptions (CommandInterpreter &interpreter) :
600 Options (interpreter),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000601 match_info ()
602 {
603 }
604
605 virtual
606 ~CommandOptions ()
607 {
608 }
609
610 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000611 SetOptionValue (uint32_t option_idx, const char *option_arg)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000612 {
613 Error error;
614 char short_option = (char) m_getopt_table[option_idx].val;
615 bool success = false;
616
617 switch (short_option)
618 {
619 case 'p':
620 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
621 if (!success)
622 error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
623 break;
624
625 case 'P':
626 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
627 if (!success)
628 error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
629 break;
630
631 case 'u':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000632 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000633 if (!success)
634 error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
635 break;
636
637 case 'U':
638 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
639 if (!success)
640 error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
641 break;
642
643 case 'g':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000644 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000645 if (!success)
646 error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
647 break;
648
649 case 'G':
650 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
651 if (!success)
652 error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
653 break;
654
655 case 'a':
Greg Claytonf15996e2011-04-07 22:46:35 +0000656 match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg, m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform().get());
Greg Clayton24bc5d92011-03-30 18:16:51 +0000657 break;
658
659 case 'n':
Greg Clayton527154d2011-11-15 03:53:30 +0000660 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000661 match_info.SetNameMatchType (eNameMatchEquals);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000662 break;
663
664 case 'e':
Greg Clayton527154d2011-11-15 03:53:30 +0000665 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000666 match_info.SetNameMatchType (eNameMatchEndsWith);
667 break;
668
669 case 's':
Greg Clayton527154d2011-11-15 03:53:30 +0000670 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000671 match_info.SetNameMatchType (eNameMatchStartsWith);
672 break;
673
674 case 'c':
Greg Clayton527154d2011-11-15 03:53:30 +0000675 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000676 match_info.SetNameMatchType (eNameMatchContains);
677 break;
678
679 case 'r':
Greg Clayton527154d2011-11-15 03:53:30 +0000680 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000681 match_info.SetNameMatchType (eNameMatchRegularExpression);
682 break;
683
Greg Claytonb72d0f02011-04-12 05:54:46 +0000684 case 'A':
685 show_args = true;
686 break;
687
688 case 'v':
689 verbose = true;
690 break;
691
Greg Clayton24bc5d92011-03-30 18:16:51 +0000692 default:
693 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
694 break;
695 }
696
697 return error;
698 }
699
700 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000701 OptionParsingStarting ()
Greg Clayton24bc5d92011-03-30 18:16:51 +0000702 {
703 match_info.Clear();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000704 show_args = false;
705 verbose = false;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000706 }
707
708 const OptionDefinition*
709 GetDefinitions ()
710 {
711 return g_option_table;
712 }
713
714 // Options table: Required for subclasses of Options.
715
716 static OptionDefinition g_option_table[];
717
718 // Instance variables to hold the values for command options.
719
Greg Claytonb72d0f02011-04-12 05:54:46 +0000720 ProcessInstanceInfoMatch match_info;
721 bool show_args;
722 bool verbose;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000723 };
724 CommandOptions m_options;
725};
726
727OptionDefinition
728CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
729{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000730{ LLDB_OPT_SET_1, false, "pid" , 'p', required_argument, NULL, 0, eArgTypePid , "List the process info for a specific process ID." },
731{ LLDB_OPT_SET_2, true , "name" , 'n', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." },
732{ LLDB_OPT_SET_3, true , "ends-with" , 'e', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that end with a string." },
733{ LLDB_OPT_SET_4, true , "starts-with" , 's', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that start with a string." },
734{ LLDB_OPT_SET_5, true , "contains" , 'c', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that contain a string." },
735{ LLDB_OPT_SET_6, true , "regex" , 'r', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that match a regular expression." },
736{ ~LLDB_OPT_SET_1, false, "parent" , 'P', required_argument, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
737{ ~LLDB_OPT_SET_1, false, "uid" , 'u', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching user ID." },
738{ ~LLDB_OPT_SET_1, false, "euid" , 'U', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective user ID." },
739{ ~LLDB_OPT_SET_1, false, "gid" , 'g', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching group ID." },
740{ ~LLDB_OPT_SET_1, false, "egid" , 'G', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective group ID." },
741{ ~LLDB_OPT_SET_1, false, "arch" , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
742{ LLDB_OPT_SET_ALL, false, "show-args" , 'A', no_argument , NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." },
743{ LLDB_OPT_SET_ALL, false, "verbose" , 'v', no_argument , NULL, 0, eArgTypeNone , "Enable verbose output." },
744{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000745};
746
Greg Claytonff39f742011-04-01 00:29:43 +0000747//----------------------------------------------------------------------
748// "platform process info"
749//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000750class CommandObjectPlatformProcessInfo : public CommandObjectParsed
Greg Claytonff39f742011-04-01 00:29:43 +0000751{
752public:
753 CommandObjectPlatformProcessInfo (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000754 CommandObjectParsed (interpreter,
755 "platform process info",
756 "Get detailed information for one or more process by process ID.",
757 "platform process info <pid> [<pid> <pid> ...]",
758 0)
Greg Claytonff39f742011-04-01 00:29:43 +0000759 {
760 CommandArgumentEntry arg;
761 CommandArgumentData pid_args;
762
763 // Define the first (and only) variant of this arg.
764 pid_args.arg_type = eArgTypePid;
765 pid_args.arg_repetition = eArgRepeatStar;
766
767 // There is only one variant this argument could be; put it into the argument entry.
768 arg.push_back (pid_args);
769
770 // Push the data for the first argument into the m_arguments vector.
771 m_arguments.push_back (arg);
772 }
773
774 virtual
775 ~CommandObjectPlatformProcessInfo ()
776 {
777 }
778
Jim Inghamda26bd22012-06-08 21:56:10 +0000779protected:
Greg Claytonff39f742011-04-01 00:29:43 +0000780 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000781 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonff39f742011-04-01 00:29:43 +0000782 {
783 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
784 if (platform_sp)
785 {
786 const size_t argc = args.GetArgumentCount();
787 if (argc > 0)
788 {
789 Error error;
790
791 if (platform_sp->IsConnected())
792 {
793 Stream &ostrm = result.GetOutputStream();
794 bool success;
795 for (size_t i=0; i<argc; ++ i)
796 {
797 const char *arg = args.GetArgumentAtIndex(i);
798 lldb::pid_t pid = Args::StringToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success);
799 if (success)
800 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000801 ProcessInstanceInfo proc_info;
Greg Claytonff39f742011-04-01 00:29:43 +0000802 if (platform_sp->GetProcessInfo (pid, proc_info))
803 {
Greg Claytond9919d32011-12-01 23:28:38 +0000804 ostrm.Printf ("Process information for process %llu:\n", pid);
Greg Claytonff39f742011-04-01 00:29:43 +0000805 proc_info.Dump (ostrm, platform_sp.get());
806 }
807 else
808 {
Greg Claytond9919d32011-12-01 23:28:38 +0000809 ostrm.Printf ("error: no process information is available for process %llu\n", pid);
Greg Claytonff39f742011-04-01 00:29:43 +0000810 }
811 ostrm.EOL();
812 }
813 else
814 {
815 result.AppendErrorWithFormat ("invalid process ID argument '%s'", arg);
816 result.SetStatus (eReturnStatusFailed);
817 break;
818 }
819 }
820 }
821 else
822 {
823 // Not connected...
824 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName());
825 result.SetStatus (eReturnStatusFailed);
826 }
827 }
828 else
829 {
Johnny Chen1736fef2011-05-09 19:05:46 +0000830 // No args
831 result.AppendError ("one or more process id(s) must be specified");
Greg Claytonff39f742011-04-01 00:29:43 +0000832 result.SetStatus (eReturnStatusFailed);
833 }
834 }
835 else
836 {
837 result.AppendError ("no platform is currently selected");
838 result.SetStatus (eReturnStatusFailed);
839 }
840 return result.Succeeded();
841 }
842};
843
844
845
846
Greg Clayton24bc5d92011-03-30 18:16:51 +0000847class CommandObjectPlatformProcess : public CommandObjectMultiword
848{
849public:
850 //------------------------------------------------------------------
851 // Constructors and Destructors
852 //------------------------------------------------------------------
853 CommandObjectPlatformProcess (CommandInterpreter &interpreter) :
854 CommandObjectMultiword (interpreter,
855 "platform process",
856 "A set of commands to query, launch and attach to platform processes",
857 "platform process [attach|launch|list] ...")
858 {
859// LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
Greg Claytonb72d0f02011-04-12 05:54:46 +0000860 LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
Greg Claytonff39f742011-04-01 00:29:43 +0000861 LoadSubCommand ("info" , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000862 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
863
864 }
865
866 virtual
867 ~CommandObjectPlatformProcess ()
868 {
869 }
870
871private:
872 //------------------------------------------------------------------
873 // For CommandObjectPlatform only
874 //------------------------------------------------------------------
875 DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformProcess);
876};
Greg Claytonb1888f22011-03-19 01:12:21 +0000877
Greg Clayton97471182012-04-14 01:42:46 +0000878
Jim Inghamda26bd22012-06-08 21:56:10 +0000879class CommandObjectPlatformShell : public CommandObjectRaw
Greg Clayton97471182012-04-14 01:42:46 +0000880{
881public:
882 CommandObjectPlatformShell (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000883 CommandObjectRaw (interpreter,
884 "platform shell",
885 "Run a shell command on a the selected platform.",
886 "platform shell <shell-command>",
887 0)
Greg Clayton97471182012-04-14 01:42:46 +0000888 {
889 }
890
891 virtual
892 ~CommandObjectPlatformShell ()
893 {
894 }
895
Jim Inghamda26bd22012-06-08 21:56:10 +0000896protected:
Greg Clayton97471182012-04-14 01:42:46 +0000897 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000898 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Greg Clayton97471182012-04-14 01:42:46 +0000899 {
900 // TODO: Implement "Platform::RunShellCommand()" and switch over to using
901 // the current platform when it is in the interface.
902 const char *working_dir = NULL;
903 std::string output;
904 int status = -1;
905 int signo = -1;
906 Error error (Host::RunShellCommand (raw_command_line, working_dir, &status, &signo, &output, 10));
907 if (!output.empty())
908 result.GetOutputStream().PutCString(output.c_str());
909 if (status > 0)
910 {
911 if (signo > 0)
912 {
913 const char *signo_cstr = Host::GetSignalAsCString(signo);
914 if (signo_cstr)
915 result.GetOutputStream().Printf("error: command returned with status %i and signal %s\n", status, signo_cstr);
916 else
917 result.GetOutputStream().Printf("error: command returned with status %i and signal %i\n", status, signo);
918 }
919 else
920 result.GetOutputStream().Printf("error: command returned with status %i\n", status);
921 }
922
923 if (error.Fail())
924 {
925 result.AppendError(error.AsCString());
926 result.SetStatus (eReturnStatusFailed);
927 }
928 else
929 {
930 result.SetStatus (eReturnStatusSuccessFinishResult);
931 }
932 return true;
933 }
Greg Clayton97471182012-04-14 01:42:46 +0000934};
935
Greg Claytonb1888f22011-03-19 01:12:21 +0000936//----------------------------------------------------------------------
937// CommandObjectPlatform constructor
938//----------------------------------------------------------------------
939CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
940 CommandObjectMultiword (interpreter,
941 "platform",
942 "A set of commands to manage and create platforms.",
Greg Clayton143fcc32011-04-13 00:18:08 +0000943 "platform [connect|disconnect|info|list|status|select] ...")
Greg Claytonb1888f22011-03-19 01:12:21 +0000944{
Greg Claytonb1888f22011-03-19 01:12:21 +0000945 LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
Greg Clayton143fcc32011-04-13 00:18:08 +0000946 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000947 LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000948 LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
949 LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000950 LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
Greg Clayton97471182012-04-14 01:42:46 +0000951 LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000952}
953
954
955//----------------------------------------------------------------------
956// Destructor
957//----------------------------------------------------------------------
958CommandObjectPlatform::~CommandObjectPlatform()
959{
960}