blob: 6e47ff8b036b0f6577905e4e073fb6210cbdcc9c [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
Jason Molenda32949382013-04-05 02:59:09 +0000210 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
211 PlatformSP platform_sp;
212 if (target)
213 {
214 platform_sp = target->GetPlatform();
215 }
216 if (!platform_sp)
217 {
218 platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
219 }
Greg Claytonff39f742011-04-01 00:29:43 +0000220 if (platform_sp)
Greg Claytonb1888f22011-03-19 01:12:21 +0000221 {
Greg Claytonff39f742011-04-01 00:29:43 +0000222 platform_sp->GetStatus (ostrm);
Greg Claytonb1888f22011-03-19 01:12:21 +0000223 result.SetStatus (eReturnStatusSuccessFinishResult);
224 }
225 else
226 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000227 result.AppendError ("no platform us currently selected\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000228 result.SetStatus (eReturnStatusFailed);
229 }
230 return result.Succeeded();
231 }
232};
233
Greg Claytoncb8977d2011-03-23 00:09:55 +0000234//----------------------------------------------------------------------
235// "platform connect <connect-url>"
236//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000237class CommandObjectPlatformConnect : public CommandObjectParsed
Greg Claytoncb8977d2011-03-23 00:09:55 +0000238{
239public:
240 CommandObjectPlatformConnect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000241 CommandObjectParsed (interpreter,
242 "platform connect",
243 "Connect a platform by name to be the currently selected platform.",
244 "platform connect <connect-url>",
245 0)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000246 {
247 }
248
249 virtual
250 ~CommandObjectPlatformConnect ()
251 {
252 }
253
Jim Inghamda26bd22012-06-08 21:56:10 +0000254protected:
Greg Claytoncb8977d2011-03-23 00:09:55 +0000255 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000256 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000257 {
258 Stream &ostrm = result.GetOutputStream();
259
Greg Claytonff39f742011-04-01 00:29:43 +0000260 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
261 if (platform_sp)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000262 {
Greg Claytonff39f742011-04-01 00:29:43 +0000263 Error error (platform_sp->ConnectRemote (args));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000264 if (error.Success())
265 {
Greg Claytonff39f742011-04-01 00:29:43 +0000266 platform_sp->GetStatus (ostrm);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000267 result.SetStatus (eReturnStatusSuccessFinishResult);
268 }
269 else
270 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000271 result.AppendErrorWithFormat ("%s\n", error.AsCString());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000272 result.SetStatus (eReturnStatusFailed);
273 }
274 }
275 else
276 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000277 result.AppendError ("no platform us currently selected\n");
Greg Claytoncb8977d2011-03-23 00:09:55 +0000278 result.SetStatus (eReturnStatusFailed);
279 }
280 return result.Succeeded();
281 }
282};
283
284//----------------------------------------------------------------------
285// "platform disconnect"
286//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000287class CommandObjectPlatformDisconnect : public CommandObjectParsed
Greg Claytoncb8977d2011-03-23 00:09:55 +0000288{
289public:
290 CommandObjectPlatformDisconnect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000291 CommandObjectParsed (interpreter,
292 "platform disconnect",
293 "Disconnect a platform by name to be the currently selected platform.",
294 "platform disconnect",
295 0)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000296 {
297 }
298
299 virtual
300 ~CommandObjectPlatformDisconnect ()
301 {
302 }
303
Jim Inghamda26bd22012-06-08 21:56:10 +0000304protected:
Greg Claytoncb8977d2011-03-23 00:09:55 +0000305 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000306 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000307 {
Greg Claytonff39f742011-04-01 00:29:43 +0000308 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
309 if (platform_sp)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000310 {
311 if (args.GetArgumentCount() == 0)
312 {
313 Error error;
314
Greg Claytonff39f742011-04-01 00:29:43 +0000315 if (platform_sp->IsConnected())
Greg Claytoncb8977d2011-03-23 00:09:55 +0000316 {
317 // Cache the instance name if there is one since we are
318 // about to disconnect and the name might go with it.
Greg Claytonff39f742011-04-01 00:29:43 +0000319 const char *hostname_cstr = platform_sp->GetHostname();
Greg Clayton58e26e02011-03-24 04:28:38 +0000320 std::string hostname;
321 if (hostname_cstr)
322 hostname.assign (hostname_cstr);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000323
Greg Claytonff39f742011-04-01 00:29:43 +0000324 error = platform_sp->DisconnectRemote ();
Greg Claytoncb8977d2011-03-23 00:09:55 +0000325 if (error.Success())
326 {
327 Stream &ostrm = result.GetOutputStream();
Greg Clayton58e26e02011-03-24 04:28:38 +0000328 if (hostname.empty())
Greg Claytonff39f742011-04-01 00:29:43 +0000329 ostrm.Printf ("Disconnected from \"%s\"\n", platform_sp->GetShortPluginName());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000330 else
Greg Clayton58e26e02011-03-24 04:28:38 +0000331 ostrm.Printf ("Disconnected from \"%s\"\n", hostname.c_str());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000332 result.SetStatus (eReturnStatusSuccessFinishResult);
333 }
334 else
335 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000336 result.AppendErrorWithFormat ("%s", error.AsCString());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000337 result.SetStatus (eReturnStatusFailed);
338 }
339 }
340 else
341 {
342 // Not connected...
Greg Claytonff39f742011-04-01 00:29:43 +0000343 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000344 result.SetStatus (eReturnStatusFailed);
345 }
346 }
347 else
348 {
349 // Bad args
350 result.AppendError ("\"platform disconnect\" doesn't take any arguments");
351 result.SetStatus (eReturnStatusFailed);
352 }
353 }
354 else
355 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000356 result.AppendError ("no platform is currently selected");
Greg Claytoncb8977d2011-03-23 00:09:55 +0000357 result.SetStatus (eReturnStatusFailed);
358 }
359 return result.Succeeded();
360 }
361};
Greg Claytonb72d0f02011-04-12 05:54:46 +0000362//----------------------------------------------------------------------
363// "platform process launch"
364//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000365class CommandObjectPlatformProcessLaunch : public CommandObjectParsed
Greg Claytonb72d0f02011-04-12 05:54:46 +0000366{
367public:
368 CommandObjectPlatformProcessLaunch (CommandInterpreter &interpreter) :
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000369 CommandObjectParsed (interpreter,
Jim Inghamda26bd22012-06-08 21:56:10 +0000370 "platform process launch",
371 "Launch a new process on a remote platform.",
372 "platform process launch program",
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000373 eFlagRequiresTarget | eFlagTryTargetAPILock),
Greg Claytonb72d0f02011-04-12 05:54:46 +0000374 m_options (interpreter)
375 {
376 }
377
378 virtual
379 ~CommandObjectPlatformProcessLaunch ()
380 {
381 }
382
Jim Inghamda26bd22012-06-08 21:56:10 +0000383 virtual Options *
384 GetOptions ()
385 {
386 return &m_options;
387 }
388
389protected:
Greg Claytonb72d0f02011-04-12 05:54:46 +0000390 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000391 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000392 {
Jason Molenda32949382013-04-05 02:59:09 +0000393 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
394 PlatformSP platform_sp;
395 if (target)
396 {
397 platform_sp = target->GetPlatform();
398 }
399 if (!platform_sp)
400 {
401 platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
402 }
403
Greg Claytonb72d0f02011-04-12 05:54:46 +0000404 if (platform_sp)
405 {
406 Error error;
Greg Clayton36da2aa2013-01-25 18:06:21 +0000407 const size_t argc = args.GetArgumentCount();
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000408 Target *target = m_exe_ctx.GetTargetPtr();
Greg Claytonabb33022011-11-08 02:43:13 +0000409 Module *exe_module = target->GetExecutableModulePointer();
410 if (exe_module)
411 {
412 m_options.launch_info.GetExecutableFile () = exe_module->GetFileSpec();
413 char exe_path[PATH_MAX];
414 if (m_options.launch_info.GetExecutableFile ().GetPath (exe_path, sizeof(exe_path)))
415 m_options.launch_info.GetArguments().AppendArgument (exe_path);
416 m_options.launch_info.GetArchitecture() = exe_module->GetArchitecture();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000417 }
418
419 if (argc > 0)
420 {
421 if (m_options.launch_info.GetExecutableFile ())
422 {
423 // We already have an executable file, so we will use this
424 // and all arguments to this function are extra arguments
425 m_options.launch_info.GetArguments().AppendArguments (args);
426 }
427 else
428 {
429 // We don't have any file yet, so the first argument is our
430 // executable, and the rest are program arguments
431 const bool first_arg_is_executable = true;
Greg Clayton0c8446c2012-10-17 22:57:12 +0000432 m_options.launch_info.SetArguments (args, first_arg_is_executable);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000433 }
434 }
435
436 if (m_options.launch_info.GetExecutableFile ())
437 {
438 Debugger &debugger = m_interpreter.GetDebugger();
439
440 if (argc == 0)
Greg Clayton73844aa2012-08-22 17:17:09 +0000441 target->GetRunArguments(m_options.launch_info.GetArguments());
Greg Claytonb72d0f02011-04-12 05:54:46 +0000442
443 ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info,
444 debugger,
445 target,
446 debugger.GetListener(),
447 error));
448 if (process_sp && process_sp->IsAlive())
449 {
450 result.SetStatus (eReturnStatusSuccessFinishNoResult);
451 return true;
452 }
453
454 if (error.Success())
455 result.AppendError ("process launch failed");
456 else
457 result.AppendError (error.AsCString());
458 result.SetStatus (eReturnStatusFailed);
459 }
460 else
461 {
462 result.AppendError ("'platform process launch' uses the current target file and arguments, or the executable and its arguments can be specified in this command");
463 result.SetStatus (eReturnStatusFailed);
464 return false;
465 }
466 }
467 else
468 {
469 result.AppendError ("no platform is selected\n");
470 }
471 return result.Succeeded();
472 }
473
Greg Claytonb72d0f02011-04-12 05:54:46 +0000474protected:
475 ProcessLaunchCommandOptions m_options;
476};
477
Greg Claytoncb8977d2011-03-23 00:09:55 +0000478
479
Greg Clayton24bc5d92011-03-30 18:16:51 +0000480//----------------------------------------------------------------------
481// "platform process list"
482//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000483class CommandObjectPlatformProcessList : public CommandObjectParsed
Greg Clayton24bc5d92011-03-30 18:16:51 +0000484{
485public:
486 CommandObjectPlatformProcessList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000487 CommandObjectParsed (interpreter,
488 "platform process list",
489 "List processes on a remote platform by name, pid, or many other matching attributes.",
490 "platform process list",
491 0),
Greg Claytonf15996e2011-04-07 22:46:35 +0000492 m_options (interpreter)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000493 {
494 }
495
496 virtual
497 ~CommandObjectPlatformProcessList ()
498 {
499 }
500
Jim Inghamda26bd22012-06-08 21:56:10 +0000501 virtual Options *
502 GetOptions ()
503 {
504 return &m_options;
505 }
506
507protected:
Greg Clayton24bc5d92011-03-30 18:16:51 +0000508 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000509 DoExecute (Args& args, CommandReturnObject &result)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000510 {
Jason Molenda32949382013-04-05 02:59:09 +0000511 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
512 PlatformSP platform_sp;
513 if (target)
514 {
515 platform_sp = target->GetPlatform();
516 }
517 if (!platform_sp)
518 {
519 platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
520 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000521
522 if (platform_sp)
523 {
524 Error error;
525 if (args.GetArgumentCount() == 0)
526 {
527
528 if (platform_sp)
529 {
Greg Claytonff39f742011-04-01 00:29:43 +0000530 Stream &ostrm = result.GetOutputStream();
531
Greg Clayton24bc5d92011-03-30 18:16:51 +0000532 lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
533 if (pid != LLDB_INVALID_PROCESS_ID)
534 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000535 ProcessInstanceInfo proc_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000536 if (platform_sp->GetProcessInfo (pid, proc_info))
537 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000538 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
539 proc_info.DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000540 result.SetStatus (eReturnStatusSuccessFinishResult);
541 }
542 else
543 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000544 result.AppendErrorWithFormat ("no process found with pid = %" PRIu64 "\n", pid);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000545 result.SetStatus (eReturnStatusFailed);
546 }
547 }
548 else
549 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000550 ProcessInstanceInfoList proc_infos;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000551 const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000552 const char *match_desc = NULL;
553 const char *match_name = m_options.match_info.GetProcessInfo().GetName();
554 if (match_name && match_name[0])
555 {
556 switch (m_options.match_info.GetNameMatchType())
557 {
558 case eNameMatchIgnore: break;
559 case eNameMatchEquals: match_desc = "matched"; break;
560 case eNameMatchContains: match_desc = "contained"; break;
561 case eNameMatchStartsWith: match_desc = "started with"; break;
562 case eNameMatchEndsWith: match_desc = "ended with"; break;
563 case eNameMatchRegularExpression: match_desc = "matched the regular expression"; break;
564 }
565 }
566
Greg Clayton24bc5d92011-03-30 18:16:51 +0000567 if (matches == 0)
568 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000569 if (match_desc)
570 result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n",
571 match_desc,
572 match_name,
573 platform_sp->GetShortPluginName());
574 else
575 result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetShortPluginName());
576 result.SetStatus (eReturnStatusFailed);
577 }
578 else
579 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000580 result.AppendMessageWithFormat ("%u matching process%s found on \"%s\"",
581 matches,
582 matches > 1 ? "es were" : " was",
583 platform_sp->GetName());
584 if (match_desc)
585 result.AppendMessageWithFormat (" whose name %s \"%s\"",
586 match_desc,
587 match_name);
588 result.AppendMessageWithFormat ("\n");
589 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000590 for (uint32_t i=0; i<matches; ++i)
591 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000592 proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000593 }
594 }
595 }
596 }
597 }
598 else
599 {
600 result.AppendError ("invalid args: process list takes only options\n");
601 result.SetStatus (eReturnStatusFailed);
602 }
603 }
604 else
605 {
606 result.AppendError ("no platform is selected\n");
607 result.SetStatus (eReturnStatusFailed);
608 }
609 return result.Succeeded();
610 }
611
Greg Clayton24bc5d92011-03-30 18:16:51 +0000612 class CommandOptions : public Options
613 {
614 public:
615
Greg Claytonf15996e2011-04-07 22:46:35 +0000616 CommandOptions (CommandInterpreter &interpreter) :
617 Options (interpreter),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000618 match_info ()
619 {
620 }
621
622 virtual
623 ~CommandOptions ()
624 {
625 }
626
627 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000628 SetOptionValue (uint32_t option_idx, const char *option_arg)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000629 {
630 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000631 const int short_option = m_getopt_table[option_idx].val;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000632 bool success = false;
633
634 switch (short_option)
635 {
636 case 'p':
637 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
638 if (!success)
639 error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
640 break;
641
642 case 'P':
643 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
644 if (!success)
645 error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
646 break;
647
648 case 'u':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000649 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000650 if (!success)
651 error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
652 break;
653
654 case 'U':
655 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
656 if (!success)
657 error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
658 break;
659
660 case 'g':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000661 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000662 if (!success)
663 error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
664 break;
665
666 case 'G':
667 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
668 if (!success)
669 error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
670 break;
671
672 case 'a':
Greg Claytonf15996e2011-04-07 22:46:35 +0000673 match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg, m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform().get());
Greg Clayton24bc5d92011-03-30 18:16:51 +0000674 break;
675
676 case 'n':
Greg Clayton527154d2011-11-15 03:53:30 +0000677 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000678 match_info.SetNameMatchType (eNameMatchEquals);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000679 break;
680
681 case 'e':
Greg Clayton527154d2011-11-15 03:53:30 +0000682 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000683 match_info.SetNameMatchType (eNameMatchEndsWith);
684 break;
685
686 case 's':
Greg Clayton527154d2011-11-15 03:53:30 +0000687 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000688 match_info.SetNameMatchType (eNameMatchStartsWith);
689 break;
690
691 case 'c':
Greg Clayton527154d2011-11-15 03:53:30 +0000692 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000693 match_info.SetNameMatchType (eNameMatchContains);
694 break;
695
696 case 'r':
Greg Clayton527154d2011-11-15 03:53:30 +0000697 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000698 match_info.SetNameMatchType (eNameMatchRegularExpression);
699 break;
700
Greg Claytonb72d0f02011-04-12 05:54:46 +0000701 case 'A':
702 show_args = true;
703 break;
704
705 case 'v':
706 verbose = true;
707 break;
708
Greg Clayton24bc5d92011-03-30 18:16:51 +0000709 default:
710 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
711 break;
712 }
713
714 return error;
715 }
716
717 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000718 OptionParsingStarting ()
Greg Clayton24bc5d92011-03-30 18:16:51 +0000719 {
720 match_info.Clear();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000721 show_args = false;
722 verbose = false;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000723 }
724
725 const OptionDefinition*
726 GetDefinitions ()
727 {
728 return g_option_table;
729 }
730
731 // Options table: Required for subclasses of Options.
732
733 static OptionDefinition g_option_table[];
734
735 // Instance variables to hold the values for command options.
736
Greg Claytonb72d0f02011-04-12 05:54:46 +0000737 ProcessInstanceInfoMatch match_info;
738 bool show_args;
739 bool verbose;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000740 };
741 CommandOptions m_options;
742};
743
744OptionDefinition
745CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
746{
Greg Claytonba9b2ae2013-04-18 20:17:32 +0000747{ LLDB_OPT_SET_1 , true , "pid" , 'p', required_argument, NULL, 0, eArgTypePid , "List the process info for a specific process ID." },
748{ LLDB_OPT_SET_2 , true , "name" , 'n', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." },
749{ LLDB_OPT_SET_3 , true , "ends-with" , 'e', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that end with a string." },
750{ LLDB_OPT_SET_4 , true , "starts-with", 's', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that start with a string." },
751{ LLDB_OPT_SET_5 , true , "contains" , 'c', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that contain a string." },
752{ LLDB_OPT_SET_6 , true , "regex" , 'r', required_argument, NULL, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." },
753{ LLDB_OPT_SET_FROM_TO(2, 6), false, "parent" , 'P', required_argument, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
754{ LLDB_OPT_SET_FROM_TO(2, 6), false, "uid" , 'u', required_argument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching user ID." },
755{ LLDB_OPT_SET_FROM_TO(2, 6), false, "euid" , 'U', required_argument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective user ID." },
756{ LLDB_OPT_SET_FROM_TO(2, 6), false, "gid" , 'g', required_argument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching group ID." },
757{ LLDB_OPT_SET_FROM_TO(2, 6), false, "egid" , 'G', required_argument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective group ID." },
758{ LLDB_OPT_SET_FROM_TO(2, 6), false, "arch" , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
759{ LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args" , 'A', no_argument , NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." },
760{ LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose" , 'v', no_argument , NULL, 0, eArgTypeNone , "Enable verbose output." },
761{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000762};
763
Greg Claytonff39f742011-04-01 00:29:43 +0000764//----------------------------------------------------------------------
765// "platform process info"
766//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000767class CommandObjectPlatformProcessInfo : public CommandObjectParsed
Greg Claytonff39f742011-04-01 00:29:43 +0000768{
769public:
770 CommandObjectPlatformProcessInfo (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000771 CommandObjectParsed (interpreter,
772 "platform process info",
773 "Get detailed information for one or more process by process ID.",
774 "platform process info <pid> [<pid> <pid> ...]",
775 0)
Greg Claytonff39f742011-04-01 00:29:43 +0000776 {
777 CommandArgumentEntry arg;
778 CommandArgumentData pid_args;
779
780 // Define the first (and only) variant of this arg.
781 pid_args.arg_type = eArgTypePid;
782 pid_args.arg_repetition = eArgRepeatStar;
783
784 // There is only one variant this argument could be; put it into the argument entry.
785 arg.push_back (pid_args);
786
787 // Push the data for the first argument into the m_arguments vector.
788 m_arguments.push_back (arg);
789 }
790
791 virtual
792 ~CommandObjectPlatformProcessInfo ()
793 {
794 }
795
Jim Inghamda26bd22012-06-08 21:56:10 +0000796protected:
Greg Claytonff39f742011-04-01 00:29:43 +0000797 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000798 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonff39f742011-04-01 00:29:43 +0000799 {
Jason Molenda32949382013-04-05 02:59:09 +0000800 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
801 PlatformSP platform_sp;
802 if (target)
803 {
804 platform_sp = target->GetPlatform();
805 }
806 if (!platform_sp)
807 {
808 platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
809 }
810
Greg Claytonff39f742011-04-01 00:29:43 +0000811 if (platform_sp)
812 {
813 const size_t argc = args.GetArgumentCount();
814 if (argc > 0)
815 {
816 Error error;
817
818 if (platform_sp->IsConnected())
819 {
820 Stream &ostrm = result.GetOutputStream();
821 bool success;
822 for (size_t i=0; i<argc; ++ i)
823 {
824 const char *arg = args.GetArgumentAtIndex(i);
825 lldb::pid_t pid = Args::StringToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success);
826 if (success)
827 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000828 ProcessInstanceInfo proc_info;
Greg Claytonff39f742011-04-01 00:29:43 +0000829 if (platform_sp->GetProcessInfo (pid, proc_info))
830 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000831 ostrm.Printf ("Process information for process %" PRIu64 ":\n", pid);
Greg Claytonff39f742011-04-01 00:29:43 +0000832 proc_info.Dump (ostrm, platform_sp.get());
833 }
834 else
835 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000836 ostrm.Printf ("error: no process information is available for process %" PRIu64 "\n", pid);
Greg Claytonff39f742011-04-01 00:29:43 +0000837 }
838 ostrm.EOL();
839 }
840 else
841 {
842 result.AppendErrorWithFormat ("invalid process ID argument '%s'", arg);
843 result.SetStatus (eReturnStatusFailed);
844 break;
845 }
846 }
847 }
848 else
849 {
850 // Not connected...
851 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName());
852 result.SetStatus (eReturnStatusFailed);
853 }
854 }
855 else
856 {
Johnny Chen1736fef2011-05-09 19:05:46 +0000857 // No args
858 result.AppendError ("one or more process id(s) must be specified");
Greg Claytonff39f742011-04-01 00:29:43 +0000859 result.SetStatus (eReturnStatusFailed);
860 }
861 }
862 else
863 {
864 result.AppendError ("no platform is currently selected");
865 result.SetStatus (eReturnStatusFailed);
866 }
867 return result.Succeeded();
868 }
869};
870
871
872
873
Greg Clayton24bc5d92011-03-30 18:16:51 +0000874class CommandObjectPlatformProcess : public CommandObjectMultiword
875{
876public:
877 //------------------------------------------------------------------
878 // Constructors and Destructors
879 //------------------------------------------------------------------
880 CommandObjectPlatformProcess (CommandInterpreter &interpreter) :
881 CommandObjectMultiword (interpreter,
882 "platform process",
883 "A set of commands to query, launch and attach to platform processes",
884 "platform process [attach|launch|list] ...")
885 {
886// LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
Greg Claytonb72d0f02011-04-12 05:54:46 +0000887 LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
Greg Claytonff39f742011-04-01 00:29:43 +0000888 LoadSubCommand ("info" , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000889 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
890
891 }
892
893 virtual
894 ~CommandObjectPlatformProcess ()
895 {
896 }
897
898private:
899 //------------------------------------------------------------------
900 // For CommandObjectPlatform only
901 //------------------------------------------------------------------
902 DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformProcess);
903};
Greg Claytonb1888f22011-03-19 01:12:21 +0000904
Greg Clayton97471182012-04-14 01:42:46 +0000905
Jim Inghamda26bd22012-06-08 21:56:10 +0000906class CommandObjectPlatformShell : public CommandObjectRaw
Greg Clayton97471182012-04-14 01:42:46 +0000907{
908public:
909 CommandObjectPlatformShell (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000910 CommandObjectRaw (interpreter,
911 "platform shell",
912 "Run a shell command on a the selected platform.",
913 "platform shell <shell-command>",
914 0)
Greg Clayton97471182012-04-14 01:42:46 +0000915 {
916 }
917
918 virtual
919 ~CommandObjectPlatformShell ()
920 {
921 }
922
Jim Inghamda26bd22012-06-08 21:56:10 +0000923protected:
Greg Clayton97471182012-04-14 01:42:46 +0000924 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000925 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Greg Clayton97471182012-04-14 01:42:46 +0000926 {
927 // TODO: Implement "Platform::RunShellCommand()" and switch over to using
928 // the current platform when it is in the interface.
929 const char *working_dir = NULL;
930 std::string output;
931 int status = -1;
932 int signo = -1;
933 Error error (Host::RunShellCommand (raw_command_line, working_dir, &status, &signo, &output, 10));
934 if (!output.empty())
935 result.GetOutputStream().PutCString(output.c_str());
936 if (status > 0)
937 {
938 if (signo > 0)
939 {
940 const char *signo_cstr = Host::GetSignalAsCString(signo);
941 if (signo_cstr)
942 result.GetOutputStream().Printf("error: command returned with status %i and signal %s\n", status, signo_cstr);
943 else
944 result.GetOutputStream().Printf("error: command returned with status %i and signal %i\n", status, signo);
945 }
946 else
947 result.GetOutputStream().Printf("error: command returned with status %i\n", status);
948 }
949
950 if (error.Fail())
951 {
952 result.AppendError(error.AsCString());
953 result.SetStatus (eReturnStatusFailed);
954 }
955 else
956 {
957 result.SetStatus (eReturnStatusSuccessFinishResult);
958 }
959 return true;
960 }
Greg Clayton97471182012-04-14 01:42:46 +0000961};
962
Greg Claytonb1888f22011-03-19 01:12:21 +0000963//----------------------------------------------------------------------
964// CommandObjectPlatform constructor
965//----------------------------------------------------------------------
966CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
967 CommandObjectMultiword (interpreter,
968 "platform",
969 "A set of commands to manage and create platforms.",
Greg Clayton143fcc32011-04-13 00:18:08 +0000970 "platform [connect|disconnect|info|list|status|select] ...")
Greg Claytonb1888f22011-03-19 01:12:21 +0000971{
Greg Claytonb1888f22011-03-19 01:12:21 +0000972 LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
Greg Clayton143fcc32011-04-13 00:18:08 +0000973 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000974 LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000975 LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
976 LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000977 LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
Greg Clayton97471182012-04-14 01:42:46 +0000978 LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000979}
980
981
982//----------------------------------------------------------------------
983// Destructor
984//----------------------------------------------------------------------
985CommandObjectPlatform::~CommandObjectPlatform()
986{
987}