blob: c9f776ed7eecd526a9134fa4292ea8b0a58289e8 [file] [log] [blame]
Greg Claytonb1888f22011-03-19 01:12:21 +00001//===-- CommandObjectPlatform.cpp -------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectPlatform.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/DataExtractor.h"
17#include "lldb/Core/Debugger.h"
18#include "lldb/Core/PluginManager.h"
19#include "lldb/Interpreter/Args.h"
20#include "lldb/Interpreter/CommandInterpreter.h"
21#include "lldb/Interpreter/CommandReturnObject.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000022#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000023#include "lldb/Target/ExecutionContext.h"
24#include "lldb/Target/Platform.h"
Greg Claytonf15996e2011-04-07 22:46:35 +000025#include "lldb/Target/Process.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000026
27using namespace lldb;
28using namespace lldb_private;
29
Greg Clayton143fcc32011-04-13 00:18:08 +000030
Greg Claytonb1888f22011-03-19 01:12:21 +000031//----------------------------------------------------------------------
Greg Claytonabe0fed2011-04-18 08:33:37 +000032// "platform select <platform-name>"
Greg Claytonb1888f22011-03-19 01:12:21 +000033//----------------------------------------------------------------------
Greg Clayton143fcc32011-04-13 00:18:08 +000034class CommandObjectPlatformSelect : public CommandObject
Greg Claytonb1888f22011-03-19 01:12:21 +000035{
36public:
Greg Clayton143fcc32011-04-13 00:18:08 +000037 CommandObjectPlatformSelect (CommandInterpreter &interpreter) :
Greg Claytonb1888f22011-03-19 01:12:21 +000038 CommandObject (interpreter,
Greg Clayton143fcc32011-04-13 00:18:08 +000039 "platform select",
40 "Create a platform if needed and select it as the current platform.",
41 "platform select <platform-name>",
Greg Claytonf15996e2011-04-07 22:46:35 +000042 0),
Greg Clayton143fcc32011-04-13 00:18:08 +000043 m_option_group (interpreter),
44 m_platform_options (false) // Don't include the "--platform" option by passing false
Greg Claytonb1888f22011-03-19 01:12:21 +000045 {
Greg Clayton5e342f52011-04-13 22:47:15 +000046 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, 1);
Greg Clayton143fcc32011-04-13 00:18:08 +000047 m_option_group.Finalize();
Greg Claytonb1888f22011-03-19 01:12:21 +000048 }
49
50 virtual
Greg Clayton143fcc32011-04-13 00:18:08 +000051 ~CommandObjectPlatformSelect ()
Greg Claytonb1888f22011-03-19 01:12:21 +000052 {
53 }
54
55 virtual bool
56 Execute (Args& args, CommandReturnObject &result)
57 {
Greg Claytonb1888f22011-03-19 01:12:21 +000058 if (args.GetArgumentCount() == 1)
59 {
Greg Clayton5e342f52011-04-13 22:47:15 +000060 const char *platform_name = args.GetArgumentAtIndex (0);
61 if (platform_name && platform_name[0])
62 {
63 const bool select = true;
Greg Claytonabe0fed2011-04-18 08:33:37 +000064 m_platform_options.SetPlatformName (platform_name);
Greg Clayton5e342f52011-04-13 22:47:15 +000065 Error error;
66 PlatformSP platform_sp (m_platform_options.CreatePlatformWithOptions (m_interpreter, select, error));
67 if (platform_sp)
68 {
69 platform_sp->GetStatus (result.GetOutputStream());
70 result.SetStatus (eReturnStatusSuccessFinishResult);
71 }
72 else
73 {
74 result.AppendError(error.AsCString());
75 result.SetStatus (eReturnStatusFailed);
76 }
77 }
78 else
79 {
80 result.AppendError ("invalid platform name");
81 result.SetStatus (eReturnStatusFailed);
82 }
Greg Claytonb1888f22011-03-19 01:12:21 +000083 }
84 else
85 {
Greg Clayton24bc5d92011-03-30 18:16:51 +000086 result.AppendError ("platform create takes a platform name as an argument\n");
Greg Claytonb1888f22011-03-19 01:12:21 +000087 result.SetStatus (eReturnStatusFailed);
88 }
89 return result.Succeeded();
90 }
91
Greg Claytonabe0fed2011-04-18 08:33:37 +000092
93 virtual int
94 HandleCompletion (Args &input,
95 int &cursor_index,
96 int &cursor_char_position,
97 int match_start_point,
98 int max_return_elements,
99 bool &word_complete,
100 StringList &matches)
101 {
102 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
103 completion_str.erase (cursor_char_position);
104
105 CommandCompletions::PlatformPluginNames (m_interpreter,
106 completion_str.c_str(),
107 match_start_point,
108 max_return_elements,
109 NULL,
110 word_complete,
111 matches);
112 return matches.GetSize();
113 }
114
Greg Claytonb1888f22011-03-19 01:12:21 +0000115 virtual Options *
116 GetOptions ()
117 {
Greg Clayton143fcc32011-04-13 00:18:08 +0000118 return &m_option_group;
Greg Claytonb1888f22011-03-19 01:12:21 +0000119 }
120
121protected:
Greg Clayton143fcc32011-04-13 00:18:08 +0000122 OptionGroupOptions m_option_group;
Greg Claytonabe0fed2011-04-18 08:33:37 +0000123 OptionGroupPlatform m_platform_options;
Greg Claytonb1888f22011-03-19 01:12:21 +0000124};
125
126//----------------------------------------------------------------------
127// "platform list"
128//----------------------------------------------------------------------
129class CommandObjectPlatformList : public CommandObject
130{
131public:
132 CommandObjectPlatformList (CommandInterpreter &interpreter) :
133 CommandObject (interpreter,
134 "platform list",
135 "List all platforms that are available.",
136 NULL,
137 0)
138 {
139 }
140
141 virtual
142 ~CommandObjectPlatformList ()
143 {
144 }
145
146 virtual bool
147 Execute (Args& args, CommandReturnObject &result)
148 {
149 Stream &ostrm = result.GetOutputStream();
150 ostrm.Printf("Available platforms:\n");
151
152 PlatformSP host_platform_sp (Platform::GetDefaultPlatform());
153 ostrm.Printf ("%s: %s\n",
154 host_platform_sp->GetShortPluginName(),
155 host_platform_sp->GetDescription());
156
157 uint32_t idx;
158 for (idx = 0; 1; ++idx)
159 {
160 const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (idx);
161 if (plugin_name == NULL)
162 break;
163 const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (idx);
164 if (plugin_desc == NULL)
165 break;
166 ostrm.Printf("%s: %s\n", plugin_name, plugin_desc);
167 }
168
169 if (idx == 0)
170 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000171 result.AppendError ("no platforms are available\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000172 result.SetStatus (eReturnStatusFailed);
173 }
Johnny Chen08150312011-03-30 21:19:59 +0000174 else
175 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonb1888f22011-03-19 01:12:21 +0000176 return result.Succeeded();
177 }
178};
179
180//----------------------------------------------------------------------
181// "platform status"
182//----------------------------------------------------------------------
183class CommandObjectPlatformStatus : public CommandObject
184{
185public:
186 CommandObjectPlatformStatus (CommandInterpreter &interpreter) :
187 CommandObject (interpreter,
188 "platform status",
189 "Display status for the currently selected platform.",
190 NULL,
191 0)
192 {
193 }
194
195 virtual
196 ~CommandObjectPlatformStatus ()
197 {
198 }
199
200 virtual bool
201 Execute (Args& args, CommandReturnObject &result)
202 {
203 Stream &ostrm = result.GetOutputStream();
204
Greg Claytonff39f742011-04-01 00:29:43 +0000205 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
206 if (platform_sp)
Greg Claytonb1888f22011-03-19 01:12:21 +0000207 {
Greg Claytonff39f742011-04-01 00:29:43 +0000208 platform_sp->GetStatus (ostrm);
Greg Claytonb1888f22011-03-19 01:12:21 +0000209 result.SetStatus (eReturnStatusSuccessFinishResult);
210 }
211 else
212 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000213 result.AppendError ("no platform us currently selected\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000214 result.SetStatus (eReturnStatusFailed);
215 }
216 return result.Succeeded();
217 }
218};
219
Greg Claytoncb8977d2011-03-23 00:09:55 +0000220//----------------------------------------------------------------------
221// "platform connect <connect-url>"
222//----------------------------------------------------------------------
223class CommandObjectPlatformConnect : public CommandObject
224{
225public:
226 CommandObjectPlatformConnect (CommandInterpreter &interpreter) :
227 CommandObject (interpreter,
228 "platform connect",
229 "Connect a platform by name to be the currently selected platform.",
230 "platform connect <connect-url>",
231 0)
232 {
233 }
234
235 virtual
236 ~CommandObjectPlatformConnect ()
237 {
238 }
239
240 virtual bool
241 Execute (Args& args, CommandReturnObject &result)
242 {
243 Stream &ostrm = result.GetOutputStream();
244
Greg Claytonff39f742011-04-01 00:29:43 +0000245 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
246 if (platform_sp)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000247 {
Greg Claytonff39f742011-04-01 00:29:43 +0000248 Error error (platform_sp->ConnectRemote (args));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000249 if (error.Success())
250 {
Greg Claytonff39f742011-04-01 00:29:43 +0000251 platform_sp->GetStatus (ostrm);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000252 result.SetStatus (eReturnStatusSuccessFinishResult);
253 }
254 else
255 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000256 result.AppendErrorWithFormat ("%s\n", error.AsCString());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000257 result.SetStatus (eReturnStatusFailed);
258 }
259 }
260 else
261 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000262 result.AppendError ("no platform us currently selected\n");
Greg Claytoncb8977d2011-03-23 00:09:55 +0000263 result.SetStatus (eReturnStatusFailed);
264 }
265 return result.Succeeded();
266 }
267};
268
269//----------------------------------------------------------------------
270// "platform disconnect"
271//----------------------------------------------------------------------
272class CommandObjectPlatformDisconnect : public CommandObject
273{
274public:
275 CommandObjectPlatformDisconnect (CommandInterpreter &interpreter) :
276 CommandObject (interpreter,
277 "platform disconnect",
278 "Disconnect a platform by name to be the currently selected platform.",
279 "platform disconnect",
280 0)
281 {
282 }
283
284 virtual
285 ~CommandObjectPlatformDisconnect ()
286 {
287 }
288
289 virtual bool
290 Execute (Args& args, CommandReturnObject &result)
291 {
Greg Claytonff39f742011-04-01 00:29:43 +0000292 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
293 if (platform_sp)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000294 {
295 if (args.GetArgumentCount() == 0)
296 {
297 Error error;
298
Greg Claytonff39f742011-04-01 00:29:43 +0000299 if (platform_sp->IsConnected())
Greg Claytoncb8977d2011-03-23 00:09:55 +0000300 {
301 // Cache the instance name if there is one since we are
302 // about to disconnect and the name might go with it.
Greg Claytonff39f742011-04-01 00:29:43 +0000303 const char *hostname_cstr = platform_sp->GetHostname();
Greg Clayton58e26e02011-03-24 04:28:38 +0000304 std::string hostname;
305 if (hostname_cstr)
306 hostname.assign (hostname_cstr);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000307
Greg Claytonff39f742011-04-01 00:29:43 +0000308 error = platform_sp->DisconnectRemote ();
Greg Claytoncb8977d2011-03-23 00:09:55 +0000309 if (error.Success())
310 {
311 Stream &ostrm = result.GetOutputStream();
Greg Clayton58e26e02011-03-24 04:28:38 +0000312 if (hostname.empty())
Greg Claytonff39f742011-04-01 00:29:43 +0000313 ostrm.Printf ("Disconnected from \"%s\"\n", platform_sp->GetShortPluginName());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000314 else
Greg Clayton58e26e02011-03-24 04:28:38 +0000315 ostrm.Printf ("Disconnected from \"%s\"\n", hostname.c_str());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000316 result.SetStatus (eReturnStatusSuccessFinishResult);
317 }
318 else
319 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000320 result.AppendErrorWithFormat ("%s", error.AsCString());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000321 result.SetStatus (eReturnStatusFailed);
322 }
323 }
324 else
325 {
326 // Not connected...
Greg Claytonff39f742011-04-01 00:29:43 +0000327 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000328 result.SetStatus (eReturnStatusFailed);
329 }
330 }
331 else
332 {
333 // Bad args
334 result.AppendError ("\"platform disconnect\" doesn't take any arguments");
335 result.SetStatus (eReturnStatusFailed);
336 }
337 }
338 else
339 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000340 result.AppendError ("no platform is currently selected");
Greg Claytoncb8977d2011-03-23 00:09:55 +0000341 result.SetStatus (eReturnStatusFailed);
342 }
343 return result.Succeeded();
344 }
345};
Greg Claytonb72d0f02011-04-12 05:54:46 +0000346//----------------------------------------------------------------------
347// "platform process launch"
348//----------------------------------------------------------------------
349class CommandObjectPlatformProcessLaunch : public CommandObject
350{
351public:
352 CommandObjectPlatformProcessLaunch (CommandInterpreter &interpreter) :
353 CommandObject (interpreter,
354 "platform process launch",
355 "Launch a new process on a remote platform.",
356 "platform process launch program",
357 0),
358 m_options (interpreter)
359 {
360 }
361
362 virtual
363 ~CommandObjectPlatformProcessLaunch ()
364 {
365 }
366
367 virtual bool
368 Execute (Args& args, CommandReturnObject &result)
369 {
370 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
371
372 if (platform_sp)
373 {
374 Error error;
375 const uint32_t argc = args.GetArgumentCount();
Greg Clayton567e7f32011-09-22 04:58:26 +0000376 Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
Greg Claytonabb33022011-11-08 02:43:13 +0000377 if (target == NULL)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000378 {
Greg Claytonabb33022011-11-08 02:43:13 +0000379 result.AppendError ("invalid target, create a debug target using the 'target create' command");
380 result.SetStatus (eReturnStatusFailed);
381 return false;
382 }
383
384 Module *exe_module = target->GetExecutableModulePointer();
385 if (exe_module)
386 {
387 m_options.launch_info.GetExecutableFile () = exe_module->GetFileSpec();
388 char exe_path[PATH_MAX];
389 if (m_options.launch_info.GetExecutableFile ().GetPath (exe_path, sizeof(exe_path)))
390 m_options.launch_info.GetArguments().AppendArgument (exe_path);
391 m_options.launch_info.GetArchitecture() = exe_module->GetArchitecture();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000392 }
393
394 if (argc > 0)
395 {
396 if (m_options.launch_info.GetExecutableFile ())
397 {
398 // We already have an executable file, so we will use this
399 // and all arguments to this function are extra arguments
400 m_options.launch_info.GetArguments().AppendArguments (args);
401 }
402 else
403 {
404 // We don't have any file yet, so the first argument is our
405 // executable, and the rest are program arguments
406 const bool first_arg_is_executable = true;
Greg Clayton36bc5ea2011-11-03 21:22:33 +0000407 m_options.launch_info.SetArguments (args,
408 first_arg_is_executable,
409 first_arg_is_executable);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000410 }
411 }
412
413 if (m_options.launch_info.GetExecutableFile ())
414 {
415 Debugger &debugger = m_interpreter.GetDebugger();
416
417 if (argc == 0)
418 {
Greg Claytonabb33022011-11-08 02:43:13 +0000419 const Args &target_settings_args = target->GetRunArguments();
420 if (target_settings_args.GetArgumentCount())
421 m_options.launch_info.GetArguments() = target_settings_args;
Greg Claytonb72d0f02011-04-12 05:54:46 +0000422 }
423
424 ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info,
425 debugger,
426 target,
427 debugger.GetListener(),
428 error));
429 if (process_sp && process_sp->IsAlive())
430 {
431 result.SetStatus (eReturnStatusSuccessFinishNoResult);
432 return true;
433 }
434
435 if (error.Success())
436 result.AppendError ("process launch failed");
437 else
438 result.AppendError (error.AsCString());
439 result.SetStatus (eReturnStatusFailed);
440 }
441 else
442 {
443 result.AppendError ("'platform process launch' uses the current target file and arguments, or the executable and its arguments can be specified in this command");
444 result.SetStatus (eReturnStatusFailed);
445 return false;
446 }
447 }
448 else
449 {
450 result.AppendError ("no platform is selected\n");
451 }
452 return result.Succeeded();
453 }
454
455 virtual Options *
456 GetOptions ()
457 {
458 return &m_options;
459 }
460
461protected:
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//----------------------------------------------------------------------
470class CommandObjectPlatformProcessList : public CommandObject
471{
472public:
473 CommandObjectPlatformProcessList (CommandInterpreter &interpreter) :
Greg Claytonf15996e2011-04-07 22:46:35 +0000474 CommandObject (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),
479 m_options (interpreter)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000480 {
481 }
482
483 virtual
484 ~CommandObjectPlatformProcessList ()
485 {
486 }
487
488 virtual bool
489 Execute (Args& args, CommandReturnObject &result)
490 {
491 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
492
493 if (platform_sp)
494 {
495 Error error;
496 if (args.GetArgumentCount() == 0)
497 {
498
499 if (platform_sp)
500 {
Greg Claytonff39f742011-04-01 00:29:43 +0000501 Stream &ostrm = result.GetOutputStream();
502
Greg Clayton24bc5d92011-03-30 18:16:51 +0000503 lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
504 if (pid != LLDB_INVALID_PROCESS_ID)
505 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000506 ProcessInstanceInfo proc_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000507 if (platform_sp->GetProcessInfo (pid, proc_info))
508 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000509 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
510 proc_info.DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000511 result.SetStatus (eReturnStatusSuccessFinishResult);
512 }
513 else
514 {
515 result.AppendErrorWithFormat ("no process found with pid = %i\n", pid);
516 result.SetStatus (eReturnStatusFailed);
517 }
518 }
519 else
520 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000521 ProcessInstanceInfoList proc_infos;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000522 const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000523 const char *match_desc = NULL;
524 const char *match_name = m_options.match_info.GetProcessInfo().GetName();
525 if (match_name && match_name[0])
526 {
527 switch (m_options.match_info.GetNameMatchType())
528 {
529 case eNameMatchIgnore: break;
530 case eNameMatchEquals: match_desc = "matched"; break;
531 case eNameMatchContains: match_desc = "contained"; break;
532 case eNameMatchStartsWith: match_desc = "started with"; break;
533 case eNameMatchEndsWith: match_desc = "ended with"; break;
534 case eNameMatchRegularExpression: match_desc = "matched the regular expression"; break;
535 }
536 }
537
Greg Clayton24bc5d92011-03-30 18:16:51 +0000538 if (matches == 0)
539 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000540 if (match_desc)
541 result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n",
542 match_desc,
543 match_name,
544 platform_sp->GetShortPluginName());
545 else
546 result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetShortPluginName());
547 result.SetStatus (eReturnStatusFailed);
548 }
549 else
550 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000551 result.AppendMessageWithFormat ("%u matching process%s found on \"%s\"",
552 matches,
553 matches > 1 ? "es were" : " was",
554 platform_sp->GetName());
555 if (match_desc)
556 result.AppendMessageWithFormat (" whose name %s \"%s\"",
557 match_desc,
558 match_name);
559 result.AppendMessageWithFormat ("\n");
560 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000561 for (uint32_t i=0; i<matches; ++i)
562 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000563 proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000564 }
565 }
566 }
567 }
568 }
569 else
570 {
571 result.AppendError ("invalid args: process list takes only options\n");
572 result.SetStatus (eReturnStatusFailed);
573 }
574 }
575 else
576 {
577 result.AppendError ("no platform is selected\n");
578 result.SetStatus (eReturnStatusFailed);
579 }
580 return result.Succeeded();
581 }
582
583 virtual Options *
584 GetOptions ()
585 {
586 return &m_options;
587 }
588
589protected:
590
591 class CommandOptions : public Options
592 {
593 public:
594
Greg Claytonf15996e2011-04-07 22:46:35 +0000595 CommandOptions (CommandInterpreter &interpreter) :
596 Options (interpreter),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000597 match_info ()
598 {
599 }
600
601 virtual
602 ~CommandOptions ()
603 {
604 }
605
606 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000607 SetOptionValue (uint32_t option_idx, const char *option_arg)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000608 {
609 Error error;
610 char short_option = (char) m_getopt_table[option_idx].val;
611 bool success = false;
612
613 switch (short_option)
614 {
615 case 'p':
616 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
617 if (!success)
618 error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
619 break;
620
621 case 'P':
622 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
623 if (!success)
624 error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
625 break;
626
627 case 'u':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000628 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000629 if (!success)
630 error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
631 break;
632
633 case 'U':
634 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
635 if (!success)
636 error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
637 break;
638
639 case 'g':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000640 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000641 if (!success)
642 error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
643 break;
644
645 case 'G':
646 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
647 if (!success)
648 error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
649 break;
650
651 case 'a':
Greg Claytonf15996e2011-04-07 22:46:35 +0000652 match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg, m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform().get());
Greg Clayton24bc5d92011-03-30 18:16:51 +0000653 break;
654
655 case 'n':
Greg Clayton527154d2011-11-15 03:53:30 +0000656 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000657 match_info.SetNameMatchType (eNameMatchEquals);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000658 break;
659
660 case 'e':
Greg Clayton527154d2011-11-15 03:53:30 +0000661 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000662 match_info.SetNameMatchType (eNameMatchEndsWith);
663 break;
664
665 case 's':
Greg Clayton527154d2011-11-15 03:53:30 +0000666 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000667 match_info.SetNameMatchType (eNameMatchStartsWith);
668 break;
669
670 case 'c':
Greg Clayton527154d2011-11-15 03:53:30 +0000671 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000672 match_info.SetNameMatchType (eNameMatchContains);
673 break;
674
675 case 'r':
Greg Clayton527154d2011-11-15 03:53:30 +0000676 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000677 match_info.SetNameMatchType (eNameMatchRegularExpression);
678 break;
679
Greg Claytonb72d0f02011-04-12 05:54:46 +0000680 case 'A':
681 show_args = true;
682 break;
683
684 case 'v':
685 verbose = true;
686 break;
687
Greg Clayton24bc5d92011-03-30 18:16:51 +0000688 default:
689 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
690 break;
691 }
692
693 return error;
694 }
695
696 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000697 OptionParsingStarting ()
Greg Clayton24bc5d92011-03-30 18:16:51 +0000698 {
699 match_info.Clear();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000700 show_args = false;
701 verbose = false;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000702 }
703
704 const OptionDefinition*
705 GetDefinitions ()
706 {
707 return g_option_table;
708 }
709
710 // Options table: Required for subclasses of Options.
711
712 static OptionDefinition g_option_table[];
713
714 // Instance variables to hold the values for command options.
715
Greg Claytonb72d0f02011-04-12 05:54:46 +0000716 ProcessInstanceInfoMatch match_info;
717 bool show_args;
718 bool verbose;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000719 };
720 CommandOptions m_options;
721};
722
723OptionDefinition
724CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
725{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000726{ LLDB_OPT_SET_1, false, "pid" , 'p', required_argument, NULL, 0, eArgTypePid , "List the process info for a specific process ID." },
727{ LLDB_OPT_SET_2, true , "name" , 'n', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." },
728{ LLDB_OPT_SET_3, true , "ends-with" , 'e', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that end with a string." },
729{ LLDB_OPT_SET_4, true , "starts-with" , 's', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that start with a string." },
730{ LLDB_OPT_SET_5, true , "contains" , 'c', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that contain a string." },
731{ LLDB_OPT_SET_6, true , "regex" , 'r', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that match a regular expression." },
732{ ~LLDB_OPT_SET_1, false, "parent" , 'P', required_argument, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
733{ ~LLDB_OPT_SET_1, false, "uid" , 'u', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching user ID." },
734{ ~LLDB_OPT_SET_1, false, "euid" , 'U', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective user ID." },
735{ ~LLDB_OPT_SET_1, false, "gid" , 'g', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching group ID." },
736{ ~LLDB_OPT_SET_1, false, "egid" , 'G', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective group ID." },
737{ ~LLDB_OPT_SET_1, false, "arch" , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
738{ LLDB_OPT_SET_ALL, false, "show-args" , 'A', no_argument , NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." },
739{ LLDB_OPT_SET_ALL, false, "verbose" , 'v', no_argument , NULL, 0, eArgTypeNone , "Enable verbose output." },
740{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000741};
742
Greg Claytonff39f742011-04-01 00:29:43 +0000743//----------------------------------------------------------------------
744// "platform process info"
745//----------------------------------------------------------------------
746class CommandObjectPlatformProcessInfo : public CommandObject
747{
748public:
749 CommandObjectPlatformProcessInfo (CommandInterpreter &interpreter) :
750 CommandObject (interpreter,
751 "platform process info",
752 "Get detailed information for one or more process by process ID.",
753 "platform process info <pid> [<pid> <pid> ...]",
754 0)
755 {
756 CommandArgumentEntry arg;
757 CommandArgumentData pid_args;
758
759 // Define the first (and only) variant of this arg.
760 pid_args.arg_type = eArgTypePid;
761 pid_args.arg_repetition = eArgRepeatStar;
762
763 // There is only one variant this argument could be; put it into the argument entry.
764 arg.push_back (pid_args);
765
766 // Push the data for the first argument into the m_arguments vector.
767 m_arguments.push_back (arg);
768 }
769
770 virtual
771 ~CommandObjectPlatformProcessInfo ()
772 {
773 }
774
775 virtual bool
776 Execute (Args& args, CommandReturnObject &result)
777 {
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 {
799 ostrm.Printf ("Process information for process %i:\n", pid);
800 proc_info.Dump (ostrm, platform_sp.get());
801 }
802 else
803 {
804 ostrm.Printf ("error: no process information is available for process %i\n", pid);
805 }
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
873//----------------------------------------------------------------------
874// CommandObjectPlatform constructor
875//----------------------------------------------------------------------
876CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
877 CommandObjectMultiword (interpreter,
878 "platform",
879 "A set of commands to manage and create platforms.",
Greg Clayton143fcc32011-04-13 00:18:08 +0000880 "platform [connect|disconnect|info|list|status|select] ...")
Greg Claytonb1888f22011-03-19 01:12:21 +0000881{
Greg Claytonb1888f22011-03-19 01:12:21 +0000882 LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
Greg Clayton143fcc32011-04-13 00:18:08 +0000883 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000884 LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000885 LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
886 LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000887 LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000888}
889
890
891//----------------------------------------------------------------------
892// Destructor
893//----------------------------------------------------------------------
894CommandObjectPlatform::~CommandObjectPlatform()
895{
896}