blob: cd6a9e282589a2fa27d5dad8d965365e56dd7bcf [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
Daniel Malead891f9b2012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Greg Claytonb1888f22011-03-19 01:12:21 +000012#include "CommandObjectPlatform.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18#include "lldb/Core/DataExtractor.h"
19#include "lldb/Core/Debugger.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000020#include "lldb/Core/Module.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000021#include "lldb/Core/PluginManager.h"
22#include "lldb/Interpreter/Args.h"
23#include "lldb/Interpreter/CommandInterpreter.h"
24#include "lldb/Interpreter/CommandReturnObject.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000025#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000026#include "lldb/Target/ExecutionContext.h"
27#include "lldb/Target/Platform.h"
Greg Claytonf15996e2011-04-07 22:46:35 +000028#include "lldb/Target/Process.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000029
30using namespace lldb;
31using namespace lldb_private;
32
Greg Clayton143fcc32011-04-13 00:18:08 +000033
Greg Claytonb1888f22011-03-19 01:12:21 +000034//----------------------------------------------------------------------
Greg Claytonabe0fed2011-04-18 08:33:37 +000035// "platform select <platform-name>"
Greg Claytonb1888f22011-03-19 01:12:21 +000036//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +000037class CommandObjectPlatformSelect : public CommandObjectParsed
Greg Claytonb1888f22011-03-19 01:12:21 +000038{
39public:
Greg Clayton143fcc32011-04-13 00:18:08 +000040 CommandObjectPlatformSelect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +000041 CommandObjectParsed (interpreter,
42 "platform select",
43 "Create a platform if needed and select it as the current platform.",
44 "platform select <platform-name>",
45 0),
Greg Clayton143fcc32011-04-13 00:18:08 +000046 m_option_group (interpreter),
47 m_platform_options (false) // Don't include the "--platform" option by passing false
Greg Claytonb1888f22011-03-19 01:12:21 +000048 {
Greg Clayton5e342f52011-04-13 22:47:15 +000049 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, 1);
Greg Clayton143fcc32011-04-13 00:18:08 +000050 m_option_group.Finalize();
Greg Claytonb1888f22011-03-19 01:12:21 +000051 }
52
53 virtual
Greg Clayton143fcc32011-04-13 00:18:08 +000054 ~CommandObjectPlatformSelect ()
Greg Claytonb1888f22011-03-19 01:12:21 +000055 {
56 }
57
Jim Inghamda26bd22012-06-08 21:56:10 +000058 virtual int
59 HandleCompletion (Args &input,
60 int &cursor_index,
61 int &cursor_char_position,
62 int match_start_point,
63 int max_return_elements,
64 bool &word_complete,
65 StringList &matches)
66 {
67 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
68 completion_str.erase (cursor_char_position);
69
70 CommandCompletions::PlatformPluginNames (m_interpreter,
71 completion_str.c_str(),
72 match_start_point,
73 max_return_elements,
74 NULL,
75 word_complete,
76 matches);
77 return matches.GetSize();
78 }
79
80 virtual Options *
81 GetOptions ()
82 {
83 return &m_option_group;
84 }
85
86protected:
Greg Claytonb1888f22011-03-19 01:12:21 +000087 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +000088 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonb1888f22011-03-19 01:12:21 +000089 {
Greg Claytonb1888f22011-03-19 01:12:21 +000090 if (args.GetArgumentCount() == 1)
91 {
Greg Clayton5e342f52011-04-13 22:47:15 +000092 const char *platform_name = args.GetArgumentAtIndex (0);
93 if (platform_name && platform_name[0])
94 {
95 const bool select = true;
Greg Claytonabe0fed2011-04-18 08:33:37 +000096 m_platform_options.SetPlatformName (platform_name);
Greg Clayton5e342f52011-04-13 22:47:15 +000097 Error error;
Greg Claytonb170aee2012-05-08 01:45:38 +000098 ArchSpec platform_arch;
99 PlatformSP platform_sp (m_platform_options.CreatePlatformWithOptions (m_interpreter, ArchSpec(), select, error, platform_arch));
Greg Clayton5e342f52011-04-13 22:47:15 +0000100 if (platform_sp)
101 {
102 platform_sp->GetStatus (result.GetOutputStream());
103 result.SetStatus (eReturnStatusSuccessFinishResult);
104 }
105 else
106 {
107 result.AppendError(error.AsCString());
108 result.SetStatus (eReturnStatusFailed);
109 }
110 }
111 else
112 {
113 result.AppendError ("invalid platform name");
114 result.SetStatus (eReturnStatusFailed);
115 }
Greg Claytonb1888f22011-03-19 01:12:21 +0000116 }
117 else
118 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000119 result.AppendError ("platform create takes a platform name as an argument\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000120 result.SetStatus (eReturnStatusFailed);
121 }
122 return result.Succeeded();
123 }
Greg Claytonabe0fed2011-04-18 08:33:37 +0000124
Greg Clayton143fcc32011-04-13 00:18:08 +0000125 OptionGroupOptions m_option_group;
Greg Claytonabe0fed2011-04-18 08:33:37 +0000126 OptionGroupPlatform m_platform_options;
Greg Claytonb1888f22011-03-19 01:12:21 +0000127};
128
129//----------------------------------------------------------------------
130// "platform list"
131//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000132class CommandObjectPlatformList : public CommandObjectParsed
Greg Claytonb1888f22011-03-19 01:12:21 +0000133{
134public:
135 CommandObjectPlatformList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000136 CommandObjectParsed (interpreter,
137 "platform list",
138 "List all platforms that are available.",
139 NULL,
140 0)
Greg Claytonb1888f22011-03-19 01:12:21 +0000141 {
142 }
143
144 virtual
145 ~CommandObjectPlatformList ()
146 {
147 }
148
Jim Inghamda26bd22012-06-08 21:56:10 +0000149protected:
Greg Claytonb1888f22011-03-19 01:12:21 +0000150 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000151 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonb1888f22011-03-19 01:12:21 +0000152 {
153 Stream &ostrm = result.GetOutputStream();
154 ostrm.Printf("Available platforms:\n");
155
156 PlatformSP host_platform_sp (Platform::GetDefaultPlatform());
157 ostrm.Printf ("%s: %s\n",
158 host_platform_sp->GetShortPluginName(),
159 host_platform_sp->GetDescription());
160
161 uint32_t idx;
162 for (idx = 0; 1; ++idx)
163 {
164 const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (idx);
165 if (plugin_name == NULL)
166 break;
167 const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (idx);
168 if (plugin_desc == NULL)
169 break;
170 ostrm.Printf("%s: %s\n", plugin_name, plugin_desc);
171 }
172
173 if (idx == 0)
174 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000175 result.AppendError ("no platforms are available\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000176 result.SetStatus (eReturnStatusFailed);
177 }
Johnny Chen08150312011-03-30 21:19:59 +0000178 else
179 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonb1888f22011-03-19 01:12:21 +0000180 return result.Succeeded();
181 }
182};
183
184//----------------------------------------------------------------------
185// "platform status"
186//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000187class CommandObjectPlatformStatus : public CommandObjectParsed
Greg Claytonb1888f22011-03-19 01:12:21 +0000188{
189public:
190 CommandObjectPlatformStatus (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000191 CommandObjectParsed (interpreter,
192 "platform status",
193 "Display status for the currently selected platform.",
194 NULL,
195 0)
Greg Claytonb1888f22011-03-19 01:12:21 +0000196 {
197 }
198
199 virtual
200 ~CommandObjectPlatformStatus ()
201 {
202 }
203
Jim Inghamda26bd22012-06-08 21:56:10 +0000204protected:
Greg Claytonb1888f22011-03-19 01:12:21 +0000205 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000206 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonb1888f22011-03-19 01:12:21 +0000207 {
208 Stream &ostrm = result.GetOutputStream();
209
Greg Claytonff39f742011-04-01 00:29:43 +0000210 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
211 if (platform_sp)
Greg Claytonb1888f22011-03-19 01:12:21 +0000212 {
Greg Claytonff39f742011-04-01 00:29:43 +0000213 platform_sp->GetStatus (ostrm);
Greg Claytonb1888f22011-03-19 01:12:21 +0000214 result.SetStatus (eReturnStatusSuccessFinishResult);
215 }
216 else
217 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000218 result.AppendError ("no platform us currently selected\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000219 result.SetStatus (eReturnStatusFailed);
220 }
221 return result.Succeeded();
222 }
223};
224
Greg Claytoncb8977d2011-03-23 00:09:55 +0000225//----------------------------------------------------------------------
226// "platform connect <connect-url>"
227//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000228class CommandObjectPlatformConnect : public CommandObjectParsed
Greg Claytoncb8977d2011-03-23 00:09:55 +0000229{
230public:
231 CommandObjectPlatformConnect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000232 CommandObjectParsed (interpreter,
233 "platform connect",
234 "Connect a platform by name to be the currently selected platform.",
235 "platform connect <connect-url>",
236 0)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000237 {
238 }
239
240 virtual
241 ~CommandObjectPlatformConnect ()
242 {
243 }
244
Jim Inghamda26bd22012-06-08 21:56:10 +0000245protected:
Greg Claytoncb8977d2011-03-23 00:09:55 +0000246 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000247 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000248 {
249 Stream &ostrm = result.GetOutputStream();
250
Greg Claytonff39f742011-04-01 00:29:43 +0000251 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
252 if (platform_sp)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000253 {
Greg Claytonff39f742011-04-01 00:29:43 +0000254 Error error (platform_sp->ConnectRemote (args));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000255 if (error.Success())
256 {
Greg Claytonff39f742011-04-01 00:29:43 +0000257 platform_sp->GetStatus (ostrm);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000258 result.SetStatus (eReturnStatusSuccessFinishResult);
259 }
260 else
261 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000262 result.AppendErrorWithFormat ("%s\n", error.AsCString());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000263 result.SetStatus (eReturnStatusFailed);
264 }
265 }
266 else
267 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000268 result.AppendError ("no platform us currently selected\n");
Greg Claytoncb8977d2011-03-23 00:09:55 +0000269 result.SetStatus (eReturnStatusFailed);
270 }
271 return result.Succeeded();
272 }
273};
274
275//----------------------------------------------------------------------
276// "platform disconnect"
277//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000278class CommandObjectPlatformDisconnect : public CommandObjectParsed
Greg Claytoncb8977d2011-03-23 00:09:55 +0000279{
280public:
281 CommandObjectPlatformDisconnect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000282 CommandObjectParsed (interpreter,
283 "platform disconnect",
284 "Disconnect a platform by name to be the currently selected platform.",
285 "platform disconnect",
286 0)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000287 {
288 }
289
290 virtual
291 ~CommandObjectPlatformDisconnect ()
292 {
293 }
294
Jim Inghamda26bd22012-06-08 21:56:10 +0000295protected:
Greg Claytoncb8977d2011-03-23 00:09:55 +0000296 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000297 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000298 {
Greg Claytonff39f742011-04-01 00:29:43 +0000299 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
300 if (platform_sp)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000301 {
302 if (args.GetArgumentCount() == 0)
303 {
304 Error error;
305
Greg Claytonff39f742011-04-01 00:29:43 +0000306 if (platform_sp->IsConnected())
Greg Claytoncb8977d2011-03-23 00:09:55 +0000307 {
308 // Cache the instance name if there is one since we are
309 // about to disconnect and the name might go with it.
Greg Claytonff39f742011-04-01 00:29:43 +0000310 const char *hostname_cstr = platform_sp->GetHostname();
Greg Clayton58e26e02011-03-24 04:28:38 +0000311 std::string hostname;
312 if (hostname_cstr)
313 hostname.assign (hostname_cstr);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000314
Greg Claytonff39f742011-04-01 00:29:43 +0000315 error = platform_sp->DisconnectRemote ();
Greg Claytoncb8977d2011-03-23 00:09:55 +0000316 if (error.Success())
317 {
318 Stream &ostrm = result.GetOutputStream();
Greg Clayton58e26e02011-03-24 04:28:38 +0000319 if (hostname.empty())
Greg Claytonff39f742011-04-01 00:29:43 +0000320 ostrm.Printf ("Disconnected from \"%s\"\n", platform_sp->GetShortPluginName());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000321 else
Greg Clayton58e26e02011-03-24 04:28:38 +0000322 ostrm.Printf ("Disconnected from \"%s\"\n", hostname.c_str());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000323 result.SetStatus (eReturnStatusSuccessFinishResult);
324 }
325 else
326 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000327 result.AppendErrorWithFormat ("%s", error.AsCString());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000328 result.SetStatus (eReturnStatusFailed);
329 }
330 }
331 else
332 {
333 // Not connected...
Greg Claytonff39f742011-04-01 00:29:43 +0000334 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000335 result.SetStatus (eReturnStatusFailed);
336 }
337 }
338 else
339 {
340 // Bad args
341 result.AppendError ("\"platform disconnect\" doesn't take any arguments");
342 result.SetStatus (eReturnStatusFailed);
343 }
344 }
345 else
346 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000347 result.AppendError ("no platform is currently selected");
Greg Claytoncb8977d2011-03-23 00:09:55 +0000348 result.SetStatus (eReturnStatusFailed);
349 }
350 return result.Succeeded();
351 }
352};
Greg Claytonb72d0f02011-04-12 05:54:46 +0000353//----------------------------------------------------------------------
354// "platform process launch"
355//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000356class CommandObjectPlatformProcessLaunch : public CommandObjectParsed
Greg Claytonb72d0f02011-04-12 05:54:46 +0000357{
358public:
359 CommandObjectPlatformProcessLaunch (CommandInterpreter &interpreter) :
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000360 CommandObjectParsed (interpreter,
Jim Inghamda26bd22012-06-08 21:56:10 +0000361 "platform process launch",
362 "Launch a new process on a remote platform.",
363 "platform process launch program",
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000364 eFlagRequiresTarget | eFlagTryTargetAPILock),
Greg Claytonb72d0f02011-04-12 05:54:46 +0000365 m_options (interpreter)
366 {
367 }
368
369 virtual
370 ~CommandObjectPlatformProcessLaunch ()
371 {
372 }
373
Jim Inghamda26bd22012-06-08 21:56:10 +0000374 virtual Options *
375 GetOptions ()
376 {
377 return &m_options;
378 }
379
380protected:
Greg Claytonb72d0f02011-04-12 05:54:46 +0000381 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000382 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000383 {
384 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
385
386 if (platform_sp)
387 {
388 Error error;
389 const uint32_t argc = args.GetArgumentCount();
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000390 Target *target = m_exe_ctx.GetTargetPtr();
Greg Claytonabb33022011-11-08 02:43:13 +0000391 Module *exe_module = target->GetExecutableModulePointer();
392 if (exe_module)
393 {
394 m_options.launch_info.GetExecutableFile () = exe_module->GetFileSpec();
395 char exe_path[PATH_MAX];
396 if (m_options.launch_info.GetExecutableFile ().GetPath (exe_path, sizeof(exe_path)))
397 m_options.launch_info.GetArguments().AppendArgument (exe_path);
398 m_options.launch_info.GetArchitecture() = exe_module->GetArchitecture();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000399 }
400
401 if (argc > 0)
402 {
403 if (m_options.launch_info.GetExecutableFile ())
404 {
405 // We already have an executable file, so we will use this
406 // and all arguments to this function are extra arguments
407 m_options.launch_info.GetArguments().AppendArguments (args);
408 }
409 else
410 {
411 // We don't have any file yet, so the first argument is our
412 // executable, and the rest are program arguments
413 const bool first_arg_is_executable = true;
Greg Clayton0c8446c2012-10-17 22:57:12 +0000414 m_options.launch_info.SetArguments (args, first_arg_is_executable);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000415 }
416 }
417
418 if (m_options.launch_info.GetExecutableFile ())
419 {
420 Debugger &debugger = m_interpreter.GetDebugger();
421
422 if (argc == 0)
Greg Clayton73844aa2012-08-22 17:17:09 +0000423 target->GetRunArguments(m_options.launch_info.GetArguments());
Greg Claytonb72d0f02011-04-12 05:54:46 +0000424
425 ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info,
426 debugger,
427 target,
428 debugger.GetListener(),
429 error));
430 if (process_sp && process_sp->IsAlive())
431 {
432 result.SetStatus (eReturnStatusSuccessFinishNoResult);
433 return true;
434 }
435
436 if (error.Success())
437 result.AppendError ("process launch failed");
438 else
439 result.AppendError (error.AsCString());
440 result.SetStatus (eReturnStatusFailed);
441 }
442 else
443 {
444 result.AppendError ("'platform process launch' uses the current target file and arguments, or the executable and its arguments can be specified in this command");
445 result.SetStatus (eReturnStatusFailed);
446 return false;
447 }
448 }
449 else
450 {
451 result.AppendError ("no platform is selected\n");
452 }
453 return result.Succeeded();
454 }
455
Greg Claytonb72d0f02011-04-12 05:54:46 +0000456protected:
457 ProcessLaunchCommandOptions m_options;
458};
459
Greg Claytoncb8977d2011-03-23 00:09:55 +0000460
461
Greg Clayton24bc5d92011-03-30 18:16:51 +0000462//----------------------------------------------------------------------
463// "platform process list"
464//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000465class CommandObjectPlatformProcessList : public CommandObjectParsed
Greg Clayton24bc5d92011-03-30 18:16:51 +0000466{
467public:
468 CommandObjectPlatformProcessList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000469 CommandObjectParsed (interpreter,
470 "platform process list",
471 "List processes on a remote platform by name, pid, or many other matching attributes.",
472 "platform process list",
473 0),
Greg Claytonf15996e2011-04-07 22:46:35 +0000474 m_options (interpreter)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000475 {
476 }
477
478 virtual
479 ~CommandObjectPlatformProcessList ()
480 {
481 }
482
Jim Inghamda26bd22012-06-08 21:56:10 +0000483 virtual Options *
484 GetOptions ()
485 {
486 return &m_options;
487 }
488
489protected:
Greg Clayton24bc5d92011-03-30 18:16:51 +0000490 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000491 DoExecute (Args& args, CommandReturnObject &result)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000492 {
493 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
494
495 if (platform_sp)
496 {
497 Error error;
498 if (args.GetArgumentCount() == 0)
499 {
500
501 if (platform_sp)
502 {
Greg Claytonff39f742011-04-01 00:29:43 +0000503 Stream &ostrm = result.GetOutputStream();
504
Greg Clayton24bc5d92011-03-30 18:16:51 +0000505 lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
506 if (pid != LLDB_INVALID_PROCESS_ID)
507 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000508 ProcessInstanceInfo proc_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000509 if (platform_sp->GetProcessInfo (pid, proc_info))
510 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000511 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
512 proc_info.DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000513 result.SetStatus (eReturnStatusSuccessFinishResult);
514 }
515 else
516 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000517 result.AppendErrorWithFormat ("no process found with pid = %" PRIu64 "\n", pid);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000518 result.SetStatus (eReturnStatusFailed);
519 }
520 }
521 else
522 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000523 ProcessInstanceInfoList proc_infos;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000524 const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000525 const char *match_desc = NULL;
526 const char *match_name = m_options.match_info.GetProcessInfo().GetName();
527 if (match_name && match_name[0])
528 {
529 switch (m_options.match_info.GetNameMatchType())
530 {
531 case eNameMatchIgnore: break;
532 case eNameMatchEquals: match_desc = "matched"; break;
533 case eNameMatchContains: match_desc = "contained"; break;
534 case eNameMatchStartsWith: match_desc = "started with"; break;
535 case eNameMatchEndsWith: match_desc = "ended with"; break;
536 case eNameMatchRegularExpression: match_desc = "matched the regular expression"; break;
537 }
538 }
539
Greg Clayton24bc5d92011-03-30 18:16:51 +0000540 if (matches == 0)
541 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000542 if (match_desc)
543 result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n",
544 match_desc,
545 match_name,
546 platform_sp->GetShortPluginName());
547 else
548 result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetShortPluginName());
549 result.SetStatus (eReturnStatusFailed);
550 }
551 else
552 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000553 result.AppendMessageWithFormat ("%u matching process%s found on \"%s\"",
554 matches,
555 matches > 1 ? "es were" : " was",
556 platform_sp->GetName());
557 if (match_desc)
558 result.AppendMessageWithFormat (" whose name %s \"%s\"",
559 match_desc,
560 match_name);
561 result.AppendMessageWithFormat ("\n");
562 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000563 for (uint32_t i=0; i<matches; ++i)
564 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000565 proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000566 }
567 }
568 }
569 }
570 }
571 else
572 {
573 result.AppendError ("invalid args: process list takes only options\n");
574 result.SetStatus (eReturnStatusFailed);
575 }
576 }
577 else
578 {
579 result.AppendError ("no platform is selected\n");
580 result.SetStatus (eReturnStatusFailed);
581 }
582 return result.Succeeded();
583 }
584
Greg Clayton24bc5d92011-03-30 18:16:51 +0000585 class CommandOptions : public Options
586 {
587 public:
588
Greg Claytonf15996e2011-04-07 22:46:35 +0000589 CommandOptions (CommandInterpreter &interpreter) :
590 Options (interpreter),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000591 match_info ()
592 {
593 }
594
595 virtual
596 ~CommandOptions ()
597 {
598 }
599
600 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000601 SetOptionValue (uint32_t option_idx, const char *option_arg)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000602 {
603 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000604 const int short_option = m_getopt_table[option_idx].val;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000605 bool success = false;
606
607 switch (short_option)
608 {
609 case 'p':
610 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
611 if (!success)
612 error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
613 break;
614
615 case 'P':
616 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
617 if (!success)
618 error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
619 break;
620
621 case 'u':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000622 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000623 if (!success)
624 error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
625 break;
626
627 case 'U':
628 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
629 if (!success)
630 error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
631 break;
632
633 case 'g':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000634 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000635 if (!success)
636 error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
637 break;
638
639 case 'G':
640 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
641 if (!success)
642 error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
643 break;
644
645 case 'a':
Greg Claytonf15996e2011-04-07 22:46:35 +0000646 match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg, m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform().get());
Greg Clayton24bc5d92011-03-30 18:16:51 +0000647 break;
648
649 case 'n':
Greg Clayton527154d2011-11-15 03:53:30 +0000650 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000651 match_info.SetNameMatchType (eNameMatchEquals);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000652 break;
653
654 case 'e':
Greg Clayton527154d2011-11-15 03:53:30 +0000655 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000656 match_info.SetNameMatchType (eNameMatchEndsWith);
657 break;
658
659 case 's':
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 (eNameMatchStartsWith);
662 break;
663
664 case 'c':
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 (eNameMatchContains);
667 break;
668
669 case 'r':
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 (eNameMatchRegularExpression);
672 break;
673
Greg Claytonb72d0f02011-04-12 05:54:46 +0000674 case 'A':
675 show_args = true;
676 break;
677
678 case 'v':
679 verbose = true;
680 break;
681
Greg Clayton24bc5d92011-03-30 18:16:51 +0000682 default:
683 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
684 break;
685 }
686
687 return error;
688 }
689
690 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000691 OptionParsingStarting ()
Greg Clayton24bc5d92011-03-30 18:16:51 +0000692 {
693 match_info.Clear();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000694 show_args = false;
695 verbose = false;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000696 }
697
698 const OptionDefinition*
699 GetDefinitions ()
700 {
701 return g_option_table;
702 }
703
704 // Options table: Required for subclasses of Options.
705
706 static OptionDefinition g_option_table[];
707
708 // Instance variables to hold the values for command options.
709
Greg Claytonb72d0f02011-04-12 05:54:46 +0000710 ProcessInstanceInfoMatch match_info;
711 bool show_args;
712 bool verbose;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000713 };
714 CommandOptions m_options;
715};
716
717OptionDefinition
718CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
719{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000720{ LLDB_OPT_SET_1, false, "pid" , 'p', required_argument, NULL, 0, eArgTypePid , "List the process info for a specific process ID." },
721{ LLDB_OPT_SET_2, true , "name" , 'n', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." },
722{ LLDB_OPT_SET_3, true , "ends-with" , 'e', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that end with a string." },
723{ LLDB_OPT_SET_4, true , "starts-with" , 's', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that start with a string." },
724{ LLDB_OPT_SET_5, true , "contains" , 'c', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that contain a string." },
725{ LLDB_OPT_SET_6, true , "regex" , 'r', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that match a regular expression." },
726{ ~LLDB_OPT_SET_1, false, "parent" , 'P', required_argument, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
727{ ~LLDB_OPT_SET_1, false, "uid" , 'u', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching user ID." },
728{ ~LLDB_OPT_SET_1, false, "euid" , 'U', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective user ID." },
729{ ~LLDB_OPT_SET_1, false, "gid" , 'g', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching group ID." },
730{ ~LLDB_OPT_SET_1, false, "egid" , 'G', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective group ID." },
731{ ~LLDB_OPT_SET_1, false, "arch" , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
732{ LLDB_OPT_SET_ALL, false, "show-args" , 'A', no_argument , NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." },
733{ LLDB_OPT_SET_ALL, false, "verbose" , 'v', no_argument , NULL, 0, eArgTypeNone , "Enable verbose output." },
734{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000735};
736
Greg Claytonff39f742011-04-01 00:29:43 +0000737//----------------------------------------------------------------------
738// "platform process info"
739//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000740class CommandObjectPlatformProcessInfo : public CommandObjectParsed
Greg Claytonff39f742011-04-01 00:29:43 +0000741{
742public:
743 CommandObjectPlatformProcessInfo (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000744 CommandObjectParsed (interpreter,
745 "platform process info",
746 "Get detailed information for one or more process by process ID.",
747 "platform process info <pid> [<pid> <pid> ...]",
748 0)
Greg Claytonff39f742011-04-01 00:29:43 +0000749 {
750 CommandArgumentEntry arg;
751 CommandArgumentData pid_args;
752
753 // Define the first (and only) variant of this arg.
754 pid_args.arg_type = eArgTypePid;
755 pid_args.arg_repetition = eArgRepeatStar;
756
757 // There is only one variant this argument could be; put it into the argument entry.
758 arg.push_back (pid_args);
759
760 // Push the data for the first argument into the m_arguments vector.
761 m_arguments.push_back (arg);
762 }
763
764 virtual
765 ~CommandObjectPlatformProcessInfo ()
766 {
767 }
768
Jim Inghamda26bd22012-06-08 21:56:10 +0000769protected:
Greg Claytonff39f742011-04-01 00:29:43 +0000770 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000771 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonff39f742011-04-01 00:29:43 +0000772 {
773 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
774 if (platform_sp)
775 {
776 const size_t argc = args.GetArgumentCount();
777 if (argc > 0)
778 {
779 Error error;
780
781 if (platform_sp->IsConnected())
782 {
783 Stream &ostrm = result.GetOutputStream();
784 bool success;
785 for (size_t i=0; i<argc; ++ i)
786 {
787 const char *arg = args.GetArgumentAtIndex(i);
788 lldb::pid_t pid = Args::StringToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success);
789 if (success)
790 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000791 ProcessInstanceInfo proc_info;
Greg Claytonff39f742011-04-01 00:29:43 +0000792 if (platform_sp->GetProcessInfo (pid, proc_info))
793 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000794 ostrm.Printf ("Process information for process %" PRIu64 ":\n", pid);
Greg Claytonff39f742011-04-01 00:29:43 +0000795 proc_info.Dump (ostrm, platform_sp.get());
796 }
797 else
798 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000799 ostrm.Printf ("error: no process information is available for process %" PRIu64 "\n", pid);
Greg Claytonff39f742011-04-01 00:29:43 +0000800 }
801 ostrm.EOL();
802 }
803 else
804 {
805 result.AppendErrorWithFormat ("invalid process ID argument '%s'", arg);
806 result.SetStatus (eReturnStatusFailed);
807 break;
808 }
809 }
810 }
811 else
812 {
813 // Not connected...
814 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName());
815 result.SetStatus (eReturnStatusFailed);
816 }
817 }
818 else
819 {
Johnny Chen1736fef2011-05-09 19:05:46 +0000820 // No args
821 result.AppendError ("one or more process id(s) must be specified");
Greg Claytonff39f742011-04-01 00:29:43 +0000822 result.SetStatus (eReturnStatusFailed);
823 }
824 }
825 else
826 {
827 result.AppendError ("no platform is currently selected");
828 result.SetStatus (eReturnStatusFailed);
829 }
830 return result.Succeeded();
831 }
832};
833
834
835
836
Greg Clayton24bc5d92011-03-30 18:16:51 +0000837class CommandObjectPlatformProcess : public CommandObjectMultiword
838{
839public:
840 //------------------------------------------------------------------
841 // Constructors and Destructors
842 //------------------------------------------------------------------
843 CommandObjectPlatformProcess (CommandInterpreter &interpreter) :
844 CommandObjectMultiword (interpreter,
845 "platform process",
846 "A set of commands to query, launch and attach to platform processes",
847 "platform process [attach|launch|list] ...")
848 {
849// LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
Greg Claytonb72d0f02011-04-12 05:54:46 +0000850 LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
Greg Claytonff39f742011-04-01 00:29:43 +0000851 LoadSubCommand ("info" , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000852 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
853
854 }
855
856 virtual
857 ~CommandObjectPlatformProcess ()
858 {
859 }
860
861private:
862 //------------------------------------------------------------------
863 // For CommandObjectPlatform only
864 //------------------------------------------------------------------
865 DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformProcess);
866};
Greg Claytonb1888f22011-03-19 01:12:21 +0000867
Greg Clayton97471182012-04-14 01:42:46 +0000868
Jim Inghamda26bd22012-06-08 21:56:10 +0000869class CommandObjectPlatformShell : public CommandObjectRaw
Greg Clayton97471182012-04-14 01:42:46 +0000870{
871public:
872 CommandObjectPlatformShell (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000873 CommandObjectRaw (interpreter,
874 "platform shell",
875 "Run a shell command on a the selected platform.",
876 "platform shell <shell-command>",
877 0)
Greg Clayton97471182012-04-14 01:42:46 +0000878 {
879 }
880
881 virtual
882 ~CommandObjectPlatformShell ()
883 {
884 }
885
Jim Inghamda26bd22012-06-08 21:56:10 +0000886protected:
Greg Clayton97471182012-04-14 01:42:46 +0000887 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000888 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Greg Clayton97471182012-04-14 01:42:46 +0000889 {
890 // TODO: Implement "Platform::RunShellCommand()" and switch over to using
891 // the current platform when it is in the interface.
892 const char *working_dir = NULL;
893 std::string output;
894 int status = -1;
895 int signo = -1;
896 Error error (Host::RunShellCommand (raw_command_line, working_dir, &status, &signo, &output, 10));
897 if (!output.empty())
898 result.GetOutputStream().PutCString(output.c_str());
899 if (status > 0)
900 {
901 if (signo > 0)
902 {
903 const char *signo_cstr = Host::GetSignalAsCString(signo);
904 if (signo_cstr)
905 result.GetOutputStream().Printf("error: command returned with status %i and signal %s\n", status, signo_cstr);
906 else
907 result.GetOutputStream().Printf("error: command returned with status %i and signal %i\n", status, signo);
908 }
909 else
910 result.GetOutputStream().Printf("error: command returned with status %i\n", status);
911 }
912
913 if (error.Fail())
914 {
915 result.AppendError(error.AsCString());
916 result.SetStatus (eReturnStatusFailed);
917 }
918 else
919 {
920 result.SetStatus (eReturnStatusSuccessFinishResult);
921 }
922 return true;
923 }
Greg Clayton97471182012-04-14 01:42:46 +0000924};
925
Greg Claytonb1888f22011-03-19 01:12:21 +0000926//----------------------------------------------------------------------
927// CommandObjectPlatform constructor
928//----------------------------------------------------------------------
929CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
930 CommandObjectMultiword (interpreter,
931 "platform",
932 "A set of commands to manage and create platforms.",
Greg Clayton143fcc32011-04-13 00:18:08 +0000933 "platform [connect|disconnect|info|list|status|select] ...")
Greg Claytonb1888f22011-03-19 01:12:21 +0000934{
Greg Claytonb1888f22011-03-19 01:12:21 +0000935 LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
Greg Clayton143fcc32011-04-13 00:18:08 +0000936 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000937 LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000938 LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
939 LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000940 LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
Greg Clayton97471182012-04-14 01:42:46 +0000941 LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000942}
943
944
945//----------------------------------------------------------------------
946// Destructor
947//----------------------------------------------------------------------
948CommandObjectPlatform::~CommandObjectPlatform()
949{
950}