blob: 3be46ab872eb87fa0e2f7e0e49372e78e942d59f [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"
Greg Clayton49ce8962012-08-29 21:13:06 +000018#include "lldb/Core/Module.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000019#include "lldb/Core/PluginManager.h"
20#include "lldb/Interpreter/Args.h"
21#include "lldb/Interpreter/CommandInterpreter.h"
22#include "lldb/Interpreter/CommandReturnObject.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000023#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000024#include "lldb/Target/ExecutionContext.h"
25#include "lldb/Target/Platform.h"
Greg Claytonf15996e2011-04-07 22:46:35 +000026#include "lldb/Target/Process.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000027
28using namespace lldb;
29using namespace lldb_private;
30
Greg Clayton143fcc32011-04-13 00:18:08 +000031
Greg Claytonb1888f22011-03-19 01:12:21 +000032//----------------------------------------------------------------------
Greg Claytonabe0fed2011-04-18 08:33:37 +000033// "platform select <platform-name>"
Greg Claytonb1888f22011-03-19 01:12:21 +000034//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +000035class CommandObjectPlatformSelect : public CommandObjectParsed
Greg Claytonb1888f22011-03-19 01:12:21 +000036{
37public:
Greg Clayton143fcc32011-04-13 00:18:08 +000038 CommandObjectPlatformSelect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +000039 CommandObjectParsed (interpreter,
40 "platform select",
41 "Create a platform if needed and select it as the current platform.",
42 "platform select <platform-name>",
43 0),
Greg Clayton143fcc32011-04-13 00:18:08 +000044 m_option_group (interpreter),
45 m_platform_options (false) // Don't include the "--platform" option by passing false
Greg Claytonb1888f22011-03-19 01:12:21 +000046 {
Greg Clayton5e342f52011-04-13 22:47:15 +000047 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, 1);
Greg Clayton143fcc32011-04-13 00:18:08 +000048 m_option_group.Finalize();
Greg Claytonb1888f22011-03-19 01:12:21 +000049 }
50
51 virtual
Greg Clayton143fcc32011-04-13 00:18:08 +000052 ~CommandObjectPlatformSelect ()
Greg Claytonb1888f22011-03-19 01:12:21 +000053 {
54 }
55
Jim Inghamda26bd22012-06-08 21:56:10 +000056 virtual int
57 HandleCompletion (Args &input,
58 int &cursor_index,
59 int &cursor_char_position,
60 int match_start_point,
61 int max_return_elements,
62 bool &word_complete,
63 StringList &matches)
64 {
65 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
66 completion_str.erase (cursor_char_position);
67
68 CommandCompletions::PlatformPluginNames (m_interpreter,
69 completion_str.c_str(),
70 match_start_point,
71 max_return_elements,
72 NULL,
73 word_complete,
74 matches);
75 return matches.GetSize();
76 }
77
78 virtual Options *
79 GetOptions ()
80 {
81 return &m_option_group;
82 }
83
84protected:
Greg Claytonb1888f22011-03-19 01:12:21 +000085 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +000086 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonb1888f22011-03-19 01:12:21 +000087 {
Greg Claytonb1888f22011-03-19 01:12:21 +000088 if (args.GetArgumentCount() == 1)
89 {
Greg Clayton5e342f52011-04-13 22:47:15 +000090 const char *platform_name = args.GetArgumentAtIndex (0);
91 if (platform_name && platform_name[0])
92 {
93 const bool select = true;
Greg Claytonabe0fed2011-04-18 08:33:37 +000094 m_platform_options.SetPlatformName (platform_name);
Greg Clayton5e342f52011-04-13 22:47:15 +000095 Error error;
Greg Claytonb170aee2012-05-08 01:45:38 +000096 ArchSpec platform_arch;
97 PlatformSP platform_sp (m_platform_options.CreatePlatformWithOptions (m_interpreter, ArchSpec(), select, error, platform_arch));
Greg Clayton5e342f52011-04-13 22:47:15 +000098 if (platform_sp)
99 {
100 platform_sp->GetStatus (result.GetOutputStream());
101 result.SetStatus (eReturnStatusSuccessFinishResult);
102 }
103 else
104 {
105 result.AppendError(error.AsCString());
106 result.SetStatus (eReturnStatusFailed);
107 }
108 }
109 else
110 {
111 result.AppendError ("invalid platform name");
112 result.SetStatus (eReturnStatusFailed);
113 }
Greg Claytonb1888f22011-03-19 01:12:21 +0000114 }
115 else
116 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000117 result.AppendError ("platform create takes a platform name as an argument\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000118 result.SetStatus (eReturnStatusFailed);
119 }
120 return result.Succeeded();
121 }
Greg Claytonabe0fed2011-04-18 08:33:37 +0000122
Greg Clayton143fcc32011-04-13 00:18:08 +0000123 OptionGroupOptions m_option_group;
Greg Claytonabe0fed2011-04-18 08:33:37 +0000124 OptionGroupPlatform m_platform_options;
Greg Claytonb1888f22011-03-19 01:12:21 +0000125};
126
127//----------------------------------------------------------------------
128// "platform list"
129//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000130class CommandObjectPlatformList : public CommandObjectParsed
Greg Claytonb1888f22011-03-19 01:12:21 +0000131{
132public:
133 CommandObjectPlatformList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000134 CommandObjectParsed (interpreter,
135 "platform list",
136 "List all platforms that are available.",
137 NULL,
138 0)
Greg Claytonb1888f22011-03-19 01:12:21 +0000139 {
140 }
141
142 virtual
143 ~CommandObjectPlatformList ()
144 {
145 }
146
Jim Inghamda26bd22012-06-08 21:56:10 +0000147protected:
Greg Claytonb1888f22011-03-19 01:12:21 +0000148 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000149 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonb1888f22011-03-19 01:12:21 +0000150 {
151 Stream &ostrm = result.GetOutputStream();
152 ostrm.Printf("Available platforms:\n");
153
154 PlatformSP host_platform_sp (Platform::GetDefaultPlatform());
155 ostrm.Printf ("%s: %s\n",
156 host_platform_sp->GetShortPluginName(),
157 host_platform_sp->GetDescription());
158
159 uint32_t idx;
160 for (idx = 0; 1; ++idx)
161 {
162 const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (idx);
163 if (plugin_name == NULL)
164 break;
165 const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (idx);
166 if (plugin_desc == NULL)
167 break;
168 ostrm.Printf("%s: %s\n", plugin_name, plugin_desc);
169 }
170
171 if (idx == 0)
172 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000173 result.AppendError ("no platforms are available\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000174 result.SetStatus (eReturnStatusFailed);
175 }
Johnny Chen08150312011-03-30 21:19:59 +0000176 else
177 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonb1888f22011-03-19 01:12:21 +0000178 return result.Succeeded();
179 }
180};
181
182//----------------------------------------------------------------------
183// "platform status"
184//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000185class CommandObjectPlatformStatus : public CommandObjectParsed
Greg Claytonb1888f22011-03-19 01:12:21 +0000186{
187public:
188 CommandObjectPlatformStatus (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000189 CommandObjectParsed (interpreter,
190 "platform status",
191 "Display status for the currently selected platform.",
192 NULL,
193 0)
Greg Claytonb1888f22011-03-19 01:12:21 +0000194 {
195 }
196
197 virtual
198 ~CommandObjectPlatformStatus ()
199 {
200 }
201
Jim Inghamda26bd22012-06-08 21:56:10 +0000202protected:
Greg Claytonb1888f22011-03-19 01:12:21 +0000203 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000204 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonb1888f22011-03-19 01:12:21 +0000205 {
206 Stream &ostrm = result.GetOutputStream();
207
Greg Claytonff39f742011-04-01 00:29:43 +0000208 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
209 if (platform_sp)
Greg Claytonb1888f22011-03-19 01:12:21 +0000210 {
Greg Claytonff39f742011-04-01 00:29:43 +0000211 platform_sp->GetStatus (ostrm);
Greg Claytonb1888f22011-03-19 01:12:21 +0000212 result.SetStatus (eReturnStatusSuccessFinishResult);
213 }
214 else
215 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000216 result.AppendError ("no platform us currently selected\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000217 result.SetStatus (eReturnStatusFailed);
218 }
219 return result.Succeeded();
220 }
221};
222
Greg Claytoncb8977d2011-03-23 00:09:55 +0000223//----------------------------------------------------------------------
224// "platform connect <connect-url>"
225//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000226class CommandObjectPlatformConnect : public CommandObjectParsed
Greg Claytoncb8977d2011-03-23 00:09:55 +0000227{
228public:
229 CommandObjectPlatformConnect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000230 CommandObjectParsed (interpreter,
231 "platform connect",
232 "Connect a platform by name to be the currently selected platform.",
233 "platform connect <connect-url>",
234 0)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000235 {
236 }
237
238 virtual
239 ~CommandObjectPlatformConnect ()
240 {
241 }
242
Jim Inghamda26bd22012-06-08 21:56:10 +0000243protected:
Greg Claytoncb8977d2011-03-23 00:09:55 +0000244 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000245 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000246 {
247 Stream &ostrm = result.GetOutputStream();
248
Greg Claytonff39f742011-04-01 00:29:43 +0000249 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
250 if (platform_sp)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000251 {
Greg Claytonff39f742011-04-01 00:29:43 +0000252 Error error (platform_sp->ConnectRemote (args));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000253 if (error.Success())
254 {
Greg Claytonff39f742011-04-01 00:29:43 +0000255 platform_sp->GetStatus (ostrm);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000256 result.SetStatus (eReturnStatusSuccessFinishResult);
257 }
258 else
259 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000260 result.AppendErrorWithFormat ("%s\n", error.AsCString());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000261 result.SetStatus (eReturnStatusFailed);
262 }
263 }
264 else
265 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000266 result.AppendError ("no platform us currently selected\n");
Greg Claytoncb8977d2011-03-23 00:09:55 +0000267 result.SetStatus (eReturnStatusFailed);
268 }
269 return result.Succeeded();
270 }
271};
272
273//----------------------------------------------------------------------
274// "platform disconnect"
275//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000276class CommandObjectPlatformDisconnect : public CommandObjectParsed
Greg Claytoncb8977d2011-03-23 00:09:55 +0000277{
278public:
279 CommandObjectPlatformDisconnect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000280 CommandObjectParsed (interpreter,
281 "platform disconnect",
282 "Disconnect a platform by name to be the currently selected platform.",
283 "platform disconnect",
284 0)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000285 {
286 }
287
288 virtual
289 ~CommandObjectPlatformDisconnect ()
290 {
291 }
292
Jim Inghamda26bd22012-06-08 21:56:10 +0000293protected:
Greg Claytoncb8977d2011-03-23 00:09:55 +0000294 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000295 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000296 {
Greg Claytonff39f742011-04-01 00:29:43 +0000297 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
298 if (platform_sp)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000299 {
300 if (args.GetArgumentCount() == 0)
301 {
302 Error error;
303
Greg Claytonff39f742011-04-01 00:29:43 +0000304 if (platform_sp->IsConnected())
Greg Claytoncb8977d2011-03-23 00:09:55 +0000305 {
306 // Cache the instance name if there is one since we are
307 // about to disconnect and the name might go with it.
Greg Claytonff39f742011-04-01 00:29:43 +0000308 const char *hostname_cstr = platform_sp->GetHostname();
Greg Clayton58e26e02011-03-24 04:28:38 +0000309 std::string hostname;
310 if (hostname_cstr)
311 hostname.assign (hostname_cstr);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000312
Greg Claytonff39f742011-04-01 00:29:43 +0000313 error = platform_sp->DisconnectRemote ();
Greg Claytoncb8977d2011-03-23 00:09:55 +0000314 if (error.Success())
315 {
316 Stream &ostrm = result.GetOutputStream();
Greg Clayton58e26e02011-03-24 04:28:38 +0000317 if (hostname.empty())
Greg Claytonff39f742011-04-01 00:29:43 +0000318 ostrm.Printf ("Disconnected from \"%s\"\n", platform_sp->GetShortPluginName());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000319 else
Greg Clayton58e26e02011-03-24 04:28:38 +0000320 ostrm.Printf ("Disconnected from \"%s\"\n", hostname.c_str());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000321 result.SetStatus (eReturnStatusSuccessFinishResult);
322 }
323 else
324 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000325 result.AppendErrorWithFormat ("%s", error.AsCString());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000326 result.SetStatus (eReturnStatusFailed);
327 }
328 }
329 else
330 {
331 // Not connected...
Greg Claytonff39f742011-04-01 00:29:43 +0000332 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000333 result.SetStatus (eReturnStatusFailed);
334 }
335 }
336 else
337 {
338 // Bad args
339 result.AppendError ("\"platform disconnect\" doesn't take any arguments");
340 result.SetStatus (eReturnStatusFailed);
341 }
342 }
343 else
344 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000345 result.AppendError ("no platform is currently selected");
Greg Claytoncb8977d2011-03-23 00:09:55 +0000346 result.SetStatus (eReturnStatusFailed);
347 }
348 return result.Succeeded();
349 }
350};
Greg Claytonb72d0f02011-04-12 05:54:46 +0000351//----------------------------------------------------------------------
352// "platform process launch"
353//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000354class CommandObjectPlatformProcessLaunch : public CommandObjectParsed
Greg Claytonb72d0f02011-04-12 05:54:46 +0000355{
356public:
357 CommandObjectPlatformProcessLaunch (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000358 CommandObjectParsed (interpreter,
359 "platform process launch",
360 "Launch a new process on a remote platform.",
361 "platform process launch program",
362 0),
Greg Claytonb72d0f02011-04-12 05:54:46 +0000363 m_options (interpreter)
364 {
365 }
366
367 virtual
368 ~CommandObjectPlatformProcessLaunch ()
369 {
370 }
371
Jim Inghamda26bd22012-06-08 21:56:10 +0000372 virtual Options *
373 GetOptions ()
374 {
375 return &m_options;
376 }
377
378protected:
Greg Claytonb72d0f02011-04-12 05:54:46 +0000379 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000380 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000381 {
382 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
383
384 if (platform_sp)
385 {
386 Error error;
387 const uint32_t argc = args.GetArgumentCount();
Greg Clayton567e7f32011-09-22 04:58:26 +0000388 Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
Greg Claytonabb33022011-11-08 02:43:13 +0000389 if (target == NULL)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000390 {
Greg Claytonabb33022011-11-08 02:43:13 +0000391 result.AppendError ("invalid target, create a debug target using the 'target create' command");
392 result.SetStatus (eReturnStatusFailed);
393 return false;
394 }
395
396 Module *exe_module = target->GetExecutableModulePointer();
397 if (exe_module)
398 {
399 m_options.launch_info.GetExecutableFile () = exe_module->GetFileSpec();
400 char exe_path[PATH_MAX];
401 if (m_options.launch_info.GetExecutableFile ().GetPath (exe_path, sizeof(exe_path)))
402 m_options.launch_info.GetArguments().AppendArgument (exe_path);
403 m_options.launch_info.GetArchitecture() = exe_module->GetArchitecture();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000404 }
405
406 if (argc > 0)
407 {
408 if (m_options.launch_info.GetExecutableFile ())
409 {
410 // We already have an executable file, so we will use this
411 // and all arguments to this function are extra arguments
412 m_options.launch_info.GetArguments().AppendArguments (args);
413 }
414 else
415 {
416 // We don't have any file yet, so the first argument is our
417 // executable, and the rest are program arguments
418 const bool first_arg_is_executable = true;
Greg Clayton0c8446c2012-10-17 22:57:12 +0000419 m_options.launch_info.SetArguments (args, first_arg_is_executable);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000420 }
421 }
422
423 if (m_options.launch_info.GetExecutableFile ())
424 {
425 Debugger &debugger = m_interpreter.GetDebugger();
426
427 if (argc == 0)
Greg Clayton73844aa2012-08-22 17:17:09 +0000428 target->GetRunArguments(m_options.launch_info.GetArguments());
Greg Claytonb72d0f02011-04-12 05:54:46 +0000429
430 ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info,
431 debugger,
432 target,
433 debugger.GetListener(),
434 error));
435 if (process_sp && process_sp->IsAlive())
436 {
437 result.SetStatus (eReturnStatusSuccessFinishNoResult);
438 return true;
439 }
440
441 if (error.Success())
442 result.AppendError ("process launch failed");
443 else
444 result.AppendError (error.AsCString());
445 result.SetStatus (eReturnStatusFailed);
446 }
447 else
448 {
449 result.AppendError ("'platform process launch' uses the current target file and arguments, or the executable and its arguments can be specified in this command");
450 result.SetStatus (eReturnStatusFailed);
451 return false;
452 }
453 }
454 else
455 {
456 result.AppendError ("no platform is selected\n");
457 }
458 return result.Succeeded();
459 }
460
Greg Claytonb72d0f02011-04-12 05:54:46 +0000461protected:
462 ProcessLaunchCommandOptions m_options;
463};
464
Greg Claytoncb8977d2011-03-23 00:09:55 +0000465
466
Greg Clayton24bc5d92011-03-30 18:16:51 +0000467//----------------------------------------------------------------------
468// "platform process list"
469//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000470class CommandObjectPlatformProcessList : public CommandObjectParsed
Greg Clayton24bc5d92011-03-30 18:16:51 +0000471{
472public:
473 CommandObjectPlatformProcessList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000474 CommandObjectParsed (interpreter,
475 "platform process list",
476 "List processes on a remote platform by name, pid, or many other matching attributes.",
477 "platform process list",
478 0),
Greg Claytonf15996e2011-04-07 22:46:35 +0000479 m_options (interpreter)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000480 {
481 }
482
483 virtual
484 ~CommandObjectPlatformProcessList ()
485 {
486 }
487
Jim Inghamda26bd22012-06-08 21:56:10 +0000488 virtual Options *
489 GetOptions ()
490 {
491 return &m_options;
492 }
493
494protected:
Greg Clayton24bc5d92011-03-30 18:16:51 +0000495 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000496 DoExecute (Args& args, CommandReturnObject &result)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000497 {
498 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
499
500 if (platform_sp)
501 {
502 Error error;
503 if (args.GetArgumentCount() == 0)
504 {
505
506 if (platform_sp)
507 {
Greg Claytonff39f742011-04-01 00:29:43 +0000508 Stream &ostrm = result.GetOutputStream();
509
Greg Clayton24bc5d92011-03-30 18:16:51 +0000510 lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
511 if (pid != LLDB_INVALID_PROCESS_ID)
512 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000513 ProcessInstanceInfo proc_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000514 if (platform_sp->GetProcessInfo (pid, proc_info))
515 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000516 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
517 proc_info.DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000518 result.SetStatus (eReturnStatusSuccessFinishResult);
519 }
520 else
521 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000522 result.AppendErrorWithFormat ("no process found with pid = %" PRIu64 "\n", pid);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000523 result.SetStatus (eReturnStatusFailed);
524 }
525 }
526 else
527 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000528 ProcessInstanceInfoList proc_infos;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000529 const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000530 const char *match_desc = NULL;
531 const char *match_name = m_options.match_info.GetProcessInfo().GetName();
532 if (match_name && match_name[0])
533 {
534 switch (m_options.match_info.GetNameMatchType())
535 {
536 case eNameMatchIgnore: break;
537 case eNameMatchEquals: match_desc = "matched"; break;
538 case eNameMatchContains: match_desc = "contained"; break;
539 case eNameMatchStartsWith: match_desc = "started with"; break;
540 case eNameMatchEndsWith: match_desc = "ended with"; break;
541 case eNameMatchRegularExpression: match_desc = "matched the regular expression"; break;
542 }
543 }
544
Greg Clayton24bc5d92011-03-30 18:16:51 +0000545 if (matches == 0)
546 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000547 if (match_desc)
548 result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n",
549 match_desc,
550 match_name,
551 platform_sp->GetShortPluginName());
552 else
553 result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetShortPluginName());
554 result.SetStatus (eReturnStatusFailed);
555 }
556 else
557 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000558 result.AppendMessageWithFormat ("%u matching process%s found on \"%s\"",
559 matches,
560 matches > 1 ? "es were" : " was",
561 platform_sp->GetName());
562 if (match_desc)
563 result.AppendMessageWithFormat (" whose name %s \"%s\"",
564 match_desc,
565 match_name);
566 result.AppendMessageWithFormat ("\n");
567 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000568 for (uint32_t i=0; i<matches; ++i)
569 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000570 proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000571 }
572 }
573 }
574 }
575 }
576 else
577 {
578 result.AppendError ("invalid args: process list takes only options\n");
579 result.SetStatus (eReturnStatusFailed);
580 }
581 }
582 else
583 {
584 result.AppendError ("no platform is selected\n");
585 result.SetStatus (eReturnStatusFailed);
586 }
587 return result.Succeeded();
588 }
589
Greg Clayton24bc5d92011-03-30 18:16:51 +0000590 class CommandOptions : public Options
591 {
592 public:
593
Greg Claytonf15996e2011-04-07 22:46:35 +0000594 CommandOptions (CommandInterpreter &interpreter) :
595 Options (interpreter),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000596 match_info ()
597 {
598 }
599
600 virtual
601 ~CommandOptions ()
602 {
603 }
604
605 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000606 SetOptionValue (uint32_t option_idx, const char *option_arg)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000607 {
608 Error error;
609 char short_option = (char) m_getopt_table[option_idx].val;
610 bool success = false;
611
612 switch (short_option)
613 {
614 case 'p':
615 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
616 if (!success)
617 error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
618 break;
619
620 case 'P':
621 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
622 if (!success)
623 error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
624 break;
625
626 case 'u':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000627 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000628 if (!success)
629 error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
630 break;
631
632 case 'U':
633 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
634 if (!success)
635 error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
636 break;
637
638 case 'g':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000639 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000640 if (!success)
641 error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
642 break;
643
644 case 'G':
645 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
646 if (!success)
647 error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
648 break;
649
650 case 'a':
Greg Claytonf15996e2011-04-07 22:46:35 +0000651 match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg, m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform().get());
Greg Clayton24bc5d92011-03-30 18:16:51 +0000652 break;
653
654 case 'n':
Greg Clayton527154d2011-11-15 03:53:30 +0000655 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000656 match_info.SetNameMatchType (eNameMatchEquals);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000657 break;
658
659 case 'e':
Greg Clayton527154d2011-11-15 03:53:30 +0000660 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000661 match_info.SetNameMatchType (eNameMatchEndsWith);
662 break;
663
664 case 's':
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 (eNameMatchStartsWith);
667 break;
668
669 case 'c':
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 (eNameMatchContains);
672 break;
673
674 case 'r':
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 (eNameMatchRegularExpression);
677 break;
678
Greg Claytonb72d0f02011-04-12 05:54:46 +0000679 case 'A':
680 show_args = true;
681 break;
682
683 case 'v':
684 verbose = true;
685 break;
686
Greg Clayton24bc5d92011-03-30 18:16:51 +0000687 default:
688 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
689 break;
690 }
691
692 return error;
693 }
694
695 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000696 OptionParsingStarting ()
Greg Clayton24bc5d92011-03-30 18:16:51 +0000697 {
698 match_info.Clear();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000699 show_args = false;
700 verbose = false;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000701 }
702
703 const OptionDefinition*
704 GetDefinitions ()
705 {
706 return g_option_table;
707 }
708
709 // Options table: Required for subclasses of Options.
710
711 static OptionDefinition g_option_table[];
712
713 // Instance variables to hold the values for command options.
714
Greg Claytonb72d0f02011-04-12 05:54:46 +0000715 ProcessInstanceInfoMatch match_info;
716 bool show_args;
717 bool verbose;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000718 };
719 CommandOptions m_options;
720};
721
722OptionDefinition
723CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
724{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000725{ LLDB_OPT_SET_1, false, "pid" , 'p', required_argument, NULL, 0, eArgTypePid , "List the process info for a specific process ID." },
726{ LLDB_OPT_SET_2, true , "name" , 'n', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." },
727{ LLDB_OPT_SET_3, true , "ends-with" , 'e', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that end with a string." },
728{ LLDB_OPT_SET_4, true , "starts-with" , 's', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that start with a string." },
729{ LLDB_OPT_SET_5, true , "contains" , 'c', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that contain a string." },
730{ LLDB_OPT_SET_6, true , "regex" , 'r', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that match a regular expression." },
731{ ~LLDB_OPT_SET_1, false, "parent" , 'P', required_argument, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
732{ ~LLDB_OPT_SET_1, false, "uid" , 'u', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching user ID." },
733{ ~LLDB_OPT_SET_1, false, "euid" , 'U', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective user ID." },
734{ ~LLDB_OPT_SET_1, false, "gid" , 'g', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching group ID." },
735{ ~LLDB_OPT_SET_1, false, "egid" , 'G', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective group ID." },
736{ ~LLDB_OPT_SET_1, false, "arch" , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
737{ LLDB_OPT_SET_ALL, false, "show-args" , 'A', no_argument , NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." },
738{ LLDB_OPT_SET_ALL, false, "verbose" , 'v', no_argument , NULL, 0, eArgTypeNone , "Enable verbose output." },
739{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000740};
741
Greg Claytonff39f742011-04-01 00:29:43 +0000742//----------------------------------------------------------------------
743// "platform process info"
744//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000745class CommandObjectPlatformProcessInfo : public CommandObjectParsed
Greg Claytonff39f742011-04-01 00:29:43 +0000746{
747public:
748 CommandObjectPlatformProcessInfo (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000749 CommandObjectParsed (interpreter,
750 "platform process info",
751 "Get detailed information for one or more process by process ID.",
752 "platform process info <pid> [<pid> <pid> ...]",
753 0)
Greg Claytonff39f742011-04-01 00:29:43 +0000754 {
755 CommandArgumentEntry arg;
756 CommandArgumentData pid_args;
757
758 // Define the first (and only) variant of this arg.
759 pid_args.arg_type = eArgTypePid;
760 pid_args.arg_repetition = eArgRepeatStar;
761
762 // There is only one variant this argument could be; put it into the argument entry.
763 arg.push_back (pid_args);
764
765 // Push the data for the first argument into the m_arguments vector.
766 m_arguments.push_back (arg);
767 }
768
769 virtual
770 ~CommandObjectPlatformProcessInfo ()
771 {
772 }
773
Jim Inghamda26bd22012-06-08 21:56:10 +0000774protected:
Greg Claytonff39f742011-04-01 00:29:43 +0000775 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000776 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonff39f742011-04-01 00:29:43 +0000777 {
778 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
779 if (platform_sp)
780 {
781 const size_t argc = args.GetArgumentCount();
782 if (argc > 0)
783 {
784 Error error;
785
786 if (platform_sp->IsConnected())
787 {
788 Stream &ostrm = result.GetOutputStream();
789 bool success;
790 for (size_t i=0; i<argc; ++ i)
791 {
792 const char *arg = args.GetArgumentAtIndex(i);
793 lldb::pid_t pid = Args::StringToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success);
794 if (success)
795 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000796 ProcessInstanceInfo proc_info;
Greg Claytonff39f742011-04-01 00:29:43 +0000797 if (platform_sp->GetProcessInfo (pid, proc_info))
798 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000799 ostrm.Printf ("Process information for process %" PRIu64 ":\n", pid);
Greg Claytonff39f742011-04-01 00:29:43 +0000800 proc_info.Dump (ostrm, platform_sp.get());
801 }
802 else
803 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000804 ostrm.Printf ("error: no process information is available for process %" PRIu64 "\n", pid);
Greg Claytonff39f742011-04-01 00:29:43 +0000805 }
806 ostrm.EOL();
807 }
808 else
809 {
810 result.AppendErrorWithFormat ("invalid process ID argument '%s'", arg);
811 result.SetStatus (eReturnStatusFailed);
812 break;
813 }
814 }
815 }
816 else
817 {
818 // Not connected...
819 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName());
820 result.SetStatus (eReturnStatusFailed);
821 }
822 }
823 else
824 {
Johnny Chen1736fef2011-05-09 19:05:46 +0000825 // No args
826 result.AppendError ("one or more process id(s) must be specified");
Greg Claytonff39f742011-04-01 00:29:43 +0000827 result.SetStatus (eReturnStatusFailed);
828 }
829 }
830 else
831 {
832 result.AppendError ("no platform is currently selected");
833 result.SetStatus (eReturnStatusFailed);
834 }
835 return result.Succeeded();
836 }
837};
838
839
840
841
Greg Clayton24bc5d92011-03-30 18:16:51 +0000842class CommandObjectPlatformProcess : public CommandObjectMultiword
843{
844public:
845 //------------------------------------------------------------------
846 // Constructors and Destructors
847 //------------------------------------------------------------------
848 CommandObjectPlatformProcess (CommandInterpreter &interpreter) :
849 CommandObjectMultiword (interpreter,
850 "platform process",
851 "A set of commands to query, launch and attach to platform processes",
852 "platform process [attach|launch|list] ...")
853 {
854// LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
Greg Claytonb72d0f02011-04-12 05:54:46 +0000855 LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
Greg Claytonff39f742011-04-01 00:29:43 +0000856 LoadSubCommand ("info" , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000857 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
858
859 }
860
861 virtual
862 ~CommandObjectPlatformProcess ()
863 {
864 }
865
866private:
867 //------------------------------------------------------------------
868 // For CommandObjectPlatform only
869 //------------------------------------------------------------------
870 DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformProcess);
871};
Greg Claytonb1888f22011-03-19 01:12:21 +0000872
Greg Clayton97471182012-04-14 01:42:46 +0000873
Jim Inghamda26bd22012-06-08 21:56:10 +0000874class CommandObjectPlatformShell : public CommandObjectRaw
Greg Clayton97471182012-04-14 01:42:46 +0000875{
876public:
877 CommandObjectPlatformShell (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000878 CommandObjectRaw (interpreter,
879 "platform shell",
880 "Run a shell command on a the selected platform.",
881 "platform shell <shell-command>",
882 0)
Greg Clayton97471182012-04-14 01:42:46 +0000883 {
884 }
885
886 virtual
887 ~CommandObjectPlatformShell ()
888 {
889 }
890
Jim Inghamda26bd22012-06-08 21:56:10 +0000891protected:
Greg Clayton97471182012-04-14 01:42:46 +0000892 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000893 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Greg Clayton97471182012-04-14 01:42:46 +0000894 {
895 // TODO: Implement "Platform::RunShellCommand()" and switch over to using
896 // the current platform when it is in the interface.
897 const char *working_dir = NULL;
898 std::string output;
899 int status = -1;
900 int signo = -1;
901 Error error (Host::RunShellCommand (raw_command_line, working_dir, &status, &signo, &output, 10));
902 if (!output.empty())
903 result.GetOutputStream().PutCString(output.c_str());
904 if (status > 0)
905 {
906 if (signo > 0)
907 {
908 const char *signo_cstr = Host::GetSignalAsCString(signo);
909 if (signo_cstr)
910 result.GetOutputStream().Printf("error: command returned with status %i and signal %s\n", status, signo_cstr);
911 else
912 result.GetOutputStream().Printf("error: command returned with status %i and signal %i\n", status, signo);
913 }
914 else
915 result.GetOutputStream().Printf("error: command returned with status %i\n", status);
916 }
917
918 if (error.Fail())
919 {
920 result.AppendError(error.AsCString());
921 result.SetStatus (eReturnStatusFailed);
922 }
923 else
924 {
925 result.SetStatus (eReturnStatusSuccessFinishResult);
926 }
927 return true;
928 }
Greg Clayton97471182012-04-14 01:42:46 +0000929};
930
Greg Claytonb1888f22011-03-19 01:12:21 +0000931//----------------------------------------------------------------------
932// CommandObjectPlatform constructor
933//----------------------------------------------------------------------
934CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
935 CommandObjectMultiword (interpreter,
936 "platform",
937 "A set of commands to manage and create platforms.",
Greg Clayton143fcc32011-04-13 00:18:08 +0000938 "platform [connect|disconnect|info|list|status|select] ...")
Greg Claytonb1888f22011-03-19 01:12:21 +0000939{
Greg Claytonb1888f22011-03-19 01:12:21 +0000940 LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
Greg Clayton143fcc32011-04-13 00:18:08 +0000941 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000942 LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000943 LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
944 LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000945 LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
Greg Clayton97471182012-04-14 01:42:46 +0000946 LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000947}
948
949
950//----------------------------------------------------------------------
951// Destructor
952//----------------------------------------------------------------------
953CommandObjectPlatform::~CommandObjectPlatform()
954{
955}