blob: 730a1b3dd014044bc4884ed18db11a4aff34e330 [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 Claytonf15996e2011-04-07 22:46:35 +000022#include "lldb/Interpreter/Options.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
30//----------------------------------------------------------------------
31// "platform create <platform-name>"
32//----------------------------------------------------------------------
33class CommandObjectPlatformCreate : public CommandObject
34{
35public:
36 CommandObjectPlatformCreate (CommandInterpreter &interpreter) :
37 CommandObject (interpreter,
38 "platform create",
39 "Create a platform instance by name and select it as the current platform.",
40 "platform create <platform-name>",
Greg Claytonf15996e2011-04-07 22:46:35 +000041 0),
42 m_options (interpreter)
Greg Claytonb1888f22011-03-19 01:12:21 +000043 {
44 }
45
46 virtual
47 ~CommandObjectPlatformCreate ()
48 {
49 }
50
51 virtual bool
52 Execute (Args& args, CommandReturnObject &result)
53 {
54 Error error;
55 if (args.GetArgumentCount() == 1)
56 {
57 PlatformSP platform_sp (Platform::Create (args.GetArgumentAtIndex (0), error));
58
59 if (platform_sp)
60 {
61 m_interpreter.GetDebugger().GetPlatformList().Append (platform_sp, true);
62 if (m_options.os_version_major != UINT32_MAX)
63 {
64 platform_sp->SetOSVersion (m_options.os_version_major,
65 m_options.os_version_minor,
66 m_options.os_version_update);
67 }
68
69 platform_sp->GetStatus (result.GetOutputStream());
70 }
71 }
72 else
73 {
Greg Clayton24bc5d92011-03-30 18:16:51 +000074 result.AppendError ("platform create takes a platform name as an argument\n");
Greg Claytonb1888f22011-03-19 01:12:21 +000075 result.SetStatus (eReturnStatusFailed);
76 }
77 return result.Succeeded();
78 }
79
80 virtual Options *
81 GetOptions ()
82 {
83 return &m_options;
84 }
85
86protected:
87
88 class CommandOptions : public Options
89 {
90 public:
91
Greg Claytonf15996e2011-04-07 22:46:35 +000092 CommandOptions (CommandInterpreter &interpreter) :
93 Options (interpreter),
Greg Claytonb1888f22011-03-19 01:12:21 +000094 os_version_major (UINT32_MAX),
95 os_version_minor (UINT32_MAX),
96 os_version_update (UINT32_MAX)
97 {
98 }
99
100 virtual
101 ~CommandOptions ()
102 {
103 }
104
105 virtual Error
106 SetOptionValue (int option_idx, const char *option_arg)
107 {
108 Error error;
109 char short_option = (char) m_getopt_table[option_idx].val;
110
111 switch (short_option)
112 {
113 case 'v':
114 if (Args::StringToVersion (option_arg,
115 os_version_major,
116 os_version_minor,
117 os_version_update) == option_arg)
118 {
119 error.SetErrorStringWithFormat ("invalid version string '%s'", option_arg);
120 }
121 break;
122
123 default:
124 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
125 break;
126 }
127
128 return error;
129 }
130
131 void
132 ResetOptionValues ()
133 {
134 os_version_major = UINT32_MAX;
135 os_version_minor = UINT32_MAX;
136 os_version_update = UINT32_MAX;
137 }
138
Greg Claytonb3448432011-03-24 21:19:54 +0000139 const OptionDefinition*
Greg Claytonb1888f22011-03-19 01:12:21 +0000140 GetDefinitions ()
141 {
142 return g_option_table;
143 }
144
145 // Options table: Required for subclasses of Options.
146
Greg Claytonb3448432011-03-24 21:19:54 +0000147 static OptionDefinition g_option_table[];
Greg Claytonb1888f22011-03-19 01:12:21 +0000148
149 // Instance variables to hold the values for command options.
150
151 uint32_t os_version_major;
152 uint32_t os_version_minor;
153 uint32_t os_version_update;
154 };
155 CommandOptions m_options;
156};
157
Greg Claytonb3448432011-03-24 21:19:54 +0000158OptionDefinition
Greg Claytonb1888f22011-03-19 01:12:21 +0000159CommandObjectPlatformCreate::CommandOptions::g_option_table[] =
160{
161 { LLDB_OPT_SET_ALL, false, "sdk-version", 'v', required_argument, NULL, 0, eArgTypeNone, "Specify the initial SDK version to use prior to connecting." },
162 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
163};
164
165//----------------------------------------------------------------------
166// "platform list"
167//----------------------------------------------------------------------
168class CommandObjectPlatformList : public CommandObject
169{
170public:
171 CommandObjectPlatformList (CommandInterpreter &interpreter) :
172 CommandObject (interpreter,
173 "platform list",
174 "List all platforms that are available.",
175 NULL,
176 0)
177 {
178 }
179
180 virtual
181 ~CommandObjectPlatformList ()
182 {
183 }
184
185 virtual bool
186 Execute (Args& args, CommandReturnObject &result)
187 {
188 Stream &ostrm = result.GetOutputStream();
189 ostrm.Printf("Available platforms:\n");
190
191 PlatformSP host_platform_sp (Platform::GetDefaultPlatform());
192 ostrm.Printf ("%s: %s\n",
193 host_platform_sp->GetShortPluginName(),
194 host_platform_sp->GetDescription());
195
196 uint32_t idx;
197 for (idx = 0; 1; ++idx)
198 {
199 const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (idx);
200 if (plugin_name == NULL)
201 break;
202 const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (idx);
203 if (plugin_desc == NULL)
204 break;
205 ostrm.Printf("%s: %s\n", plugin_name, plugin_desc);
206 }
207
208 if (idx == 0)
209 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000210 result.AppendError ("no platforms are available\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000211 result.SetStatus (eReturnStatusFailed);
212 }
Johnny Chen08150312011-03-30 21:19:59 +0000213 else
214 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonb1888f22011-03-19 01:12:21 +0000215 return result.Succeeded();
216 }
217};
218
219//----------------------------------------------------------------------
220// "platform status"
221//----------------------------------------------------------------------
222class CommandObjectPlatformStatus : public CommandObject
223{
224public:
225 CommandObjectPlatformStatus (CommandInterpreter &interpreter) :
226 CommandObject (interpreter,
227 "platform status",
228 "Display status for the currently selected platform.",
229 NULL,
230 0)
231 {
232 }
233
234 virtual
235 ~CommandObjectPlatformStatus ()
236 {
237 }
238
239 virtual bool
240 Execute (Args& args, CommandReturnObject &result)
241 {
242 Stream &ostrm = result.GetOutputStream();
243
Greg Claytonff39f742011-04-01 00:29:43 +0000244 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
245 if (platform_sp)
Greg Claytonb1888f22011-03-19 01:12:21 +0000246 {
Greg Claytonff39f742011-04-01 00:29:43 +0000247 platform_sp->GetStatus (ostrm);
Greg Claytonb1888f22011-03-19 01:12:21 +0000248 result.SetStatus (eReturnStatusSuccessFinishResult);
249 }
250 else
251 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000252 result.AppendError ("no platform us currently selected\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000253 result.SetStatus (eReturnStatusFailed);
254 }
255 return result.Succeeded();
256 }
257};
258
259
260//----------------------------------------------------------------------
261// "platform select <platform-name>"
262//----------------------------------------------------------------------
263class CommandObjectPlatformSelect : public CommandObject
264{
265public:
266 CommandObjectPlatformSelect (CommandInterpreter &interpreter) :
267 CommandObject (interpreter,
268 "platform select",
269 "Select a platform by name to be the currently selected platform.",
270 "platform select <platform-name>",
271 0)
272 {
273 }
274
275 virtual
276 ~CommandObjectPlatformSelect ()
277 {
278 }
279
280 virtual bool
281 Execute (Args& args, CommandReturnObject &result)
282 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000283 result.AppendError ("command not implemented\n");
Greg Claytonb1888f22011-03-19 01:12:21 +0000284 result.SetStatus (eReturnStatusFailed);
285 return result.Succeeded();
286 }
287};
288
289
Greg Claytoncb8977d2011-03-23 00:09:55 +0000290//----------------------------------------------------------------------
291// "platform connect <connect-url>"
292//----------------------------------------------------------------------
293class CommandObjectPlatformConnect : public CommandObject
294{
295public:
296 CommandObjectPlatformConnect (CommandInterpreter &interpreter) :
297 CommandObject (interpreter,
298 "platform connect",
299 "Connect a platform by name to be the currently selected platform.",
300 "platform connect <connect-url>",
301 0)
302 {
303 }
304
305 virtual
306 ~CommandObjectPlatformConnect ()
307 {
308 }
309
310 virtual bool
311 Execute (Args& args, CommandReturnObject &result)
312 {
313 Stream &ostrm = result.GetOutputStream();
314
Greg Claytonff39f742011-04-01 00:29:43 +0000315 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
316 if (platform_sp)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000317 {
Greg Claytonff39f742011-04-01 00:29:43 +0000318 Error error (platform_sp->ConnectRemote (args));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000319 if (error.Success())
320 {
Greg Claytonff39f742011-04-01 00:29:43 +0000321 platform_sp->GetStatus (ostrm);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000322 result.SetStatus (eReturnStatusSuccessFinishResult);
323 }
324 else
325 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000326 result.AppendErrorWithFormat ("%s\n", error.AsCString());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000327 result.SetStatus (eReturnStatusFailed);
328 }
329 }
330 else
331 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000332 result.AppendError ("no platform us currently selected\n");
Greg Claytoncb8977d2011-03-23 00:09:55 +0000333 result.SetStatus (eReturnStatusFailed);
334 }
335 return result.Succeeded();
336 }
337};
338
339//----------------------------------------------------------------------
340// "platform disconnect"
341//----------------------------------------------------------------------
342class CommandObjectPlatformDisconnect : public CommandObject
343{
344public:
345 CommandObjectPlatformDisconnect (CommandInterpreter &interpreter) :
346 CommandObject (interpreter,
347 "platform disconnect",
348 "Disconnect a platform by name to be the currently selected platform.",
349 "platform disconnect",
350 0)
351 {
352 }
353
354 virtual
355 ~CommandObjectPlatformDisconnect ()
356 {
357 }
358
359 virtual bool
360 Execute (Args& args, CommandReturnObject &result)
361 {
Greg Claytonff39f742011-04-01 00:29:43 +0000362 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
363 if (platform_sp)
Greg Claytoncb8977d2011-03-23 00:09:55 +0000364 {
365 if (args.GetArgumentCount() == 0)
366 {
367 Error error;
368
Greg Claytonff39f742011-04-01 00:29:43 +0000369 if (platform_sp->IsConnected())
Greg Claytoncb8977d2011-03-23 00:09:55 +0000370 {
371 // Cache the instance name if there is one since we are
372 // about to disconnect and the name might go with it.
Greg Claytonff39f742011-04-01 00:29:43 +0000373 const char *hostname_cstr = platform_sp->GetHostname();
Greg Clayton58e26e02011-03-24 04:28:38 +0000374 std::string hostname;
375 if (hostname_cstr)
376 hostname.assign (hostname_cstr);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000377
Greg Claytonff39f742011-04-01 00:29:43 +0000378 error = platform_sp->DisconnectRemote ();
Greg Claytoncb8977d2011-03-23 00:09:55 +0000379 if (error.Success())
380 {
381 Stream &ostrm = result.GetOutputStream();
Greg Clayton58e26e02011-03-24 04:28:38 +0000382 if (hostname.empty())
Greg Claytonff39f742011-04-01 00:29:43 +0000383 ostrm.Printf ("Disconnected from \"%s\"\n", platform_sp->GetShortPluginName());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000384 else
Greg Clayton58e26e02011-03-24 04:28:38 +0000385 ostrm.Printf ("Disconnected from \"%s\"\n", hostname.c_str());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000386 result.SetStatus (eReturnStatusSuccessFinishResult);
387 }
388 else
389 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000390 result.AppendErrorWithFormat ("%s", error.AsCString());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000391 result.SetStatus (eReturnStatusFailed);
392 }
393 }
394 else
395 {
396 // Not connected...
Greg Claytonff39f742011-04-01 00:29:43 +0000397 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName());
Greg Claytoncb8977d2011-03-23 00:09:55 +0000398 result.SetStatus (eReturnStatusFailed);
399 }
400 }
401 else
402 {
403 // Bad args
404 result.AppendError ("\"platform disconnect\" doesn't take any arguments");
405 result.SetStatus (eReturnStatusFailed);
406 }
407 }
408 else
409 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000410 result.AppendError ("no platform is currently selected");
Greg Claytoncb8977d2011-03-23 00:09:55 +0000411 result.SetStatus (eReturnStatusFailed);
412 }
413 return result.Succeeded();
414 }
415};
Greg Claytonb72d0f02011-04-12 05:54:46 +0000416//----------------------------------------------------------------------
417// "platform process launch"
418//----------------------------------------------------------------------
419class CommandObjectPlatformProcessLaunch : public CommandObject
420{
421public:
422 CommandObjectPlatformProcessLaunch (CommandInterpreter &interpreter) :
423 CommandObject (interpreter,
424 "platform process launch",
425 "Launch a new process on a remote platform.",
426 "platform process launch program",
427 0),
428 m_options (interpreter)
429 {
430 }
431
432 virtual
433 ~CommandObjectPlatformProcessLaunch ()
434 {
435 }
436
437 virtual bool
438 Execute (Args& args, CommandReturnObject &result)
439 {
440 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
441
442 if (platform_sp)
443 {
444 Error error;
445 const uint32_t argc = args.GetArgumentCount();
446 Target *target = m_interpreter.GetExecutionContext().target;
447 ModuleSP exe_module_sp;
448 if (target)
449 {
450 exe_module_sp = target->GetExecutableModule();
451 if (exe_module_sp)
452 {
453 m_options.launch_info.GetExecutableFile () = exe_module_sp->GetFileSpec();
454 char exe_path[PATH_MAX];
455 if (m_options.launch_info.GetExecutableFile ().GetPath (exe_path, sizeof(exe_path)))
456 m_options.launch_info.GetArguments().AppendArgument (exe_path);
457 m_options.launch_info.GetArchitecture() = exe_module_sp->GetArchitecture();
458 }
459 }
460
461 if (argc > 0)
462 {
463 if (m_options.launch_info.GetExecutableFile ())
464 {
465 // We already have an executable file, so we will use this
466 // and all arguments to this function are extra arguments
467 m_options.launch_info.GetArguments().AppendArguments (args);
468 }
469 else
470 {
471 // We don't have any file yet, so the first argument is our
472 // executable, and the rest are program arguments
473 const bool first_arg_is_executable = true;
474 m_options.launch_info.SetArgumentsFromArgs (args,
475 first_arg_is_executable,
476 first_arg_is_executable);
477 }
478 }
479
480 if (m_options.launch_info.GetExecutableFile ())
481 {
482 Debugger &debugger = m_interpreter.GetDebugger();
483
484 if (argc == 0)
485 {
486 lldb::UserSettingsControllerSP process_usc_sp (Process::GetSettingsController ());
487 if (process_usc_sp)
488 {
489 SettableVariableType type;
490 StringList settings_args (process_usc_sp->GetVariable ("process.run-args",
491 type,
492 m_interpreter.GetDebugger().GetInstanceName().GetCString(),
493 error));
494 if (error.Success())
495 {
496 const size_t num_settings_args = settings_args.GetSize();
497 for (size_t i=0; i<num_settings_args; ++i)
498 m_options.launch_info.GetArguments().AppendArgument (settings_args.GetStringAtIndex(i));
499 }
500 }
501 }
502
503 ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info,
504 debugger,
505 target,
506 debugger.GetListener(),
507 error));
508 if (process_sp && process_sp->IsAlive())
509 {
510 result.SetStatus (eReturnStatusSuccessFinishNoResult);
511 return true;
512 }
513
514 if (error.Success())
515 result.AppendError ("process launch failed");
516 else
517 result.AppendError (error.AsCString());
518 result.SetStatus (eReturnStatusFailed);
519 }
520 else
521 {
522 result.AppendError ("'platform process launch' uses the current target file and arguments, or the executable and its arguments can be specified in this command");
523 result.SetStatus (eReturnStatusFailed);
524 return false;
525 }
526 }
527 else
528 {
529 result.AppendError ("no platform is selected\n");
530 }
531 return result.Succeeded();
532 }
533
534 virtual Options *
535 GetOptions ()
536 {
537 return &m_options;
538 }
539
540protected:
541 ProcessLaunchCommandOptions m_options;
542};
543
Greg Claytoncb8977d2011-03-23 00:09:55 +0000544
545
Greg Clayton24bc5d92011-03-30 18:16:51 +0000546//----------------------------------------------------------------------
547// "platform process list"
548//----------------------------------------------------------------------
549class CommandObjectPlatformProcessList : public CommandObject
550{
551public:
552 CommandObjectPlatformProcessList (CommandInterpreter &interpreter) :
Greg Claytonf15996e2011-04-07 22:46:35 +0000553 CommandObject (interpreter,
554 "platform process list",
555 "List processes on a remote platform by name, pid, or many other matching attributes.",
556 "platform process list",
557 0),
558 m_options (interpreter)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000559 {
560 }
561
562 virtual
563 ~CommandObjectPlatformProcessList ()
564 {
565 }
566
567 virtual bool
568 Execute (Args& args, CommandReturnObject &result)
569 {
570 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
571
572 if (platform_sp)
573 {
574 Error error;
575 if (args.GetArgumentCount() == 0)
576 {
577
578 if (platform_sp)
579 {
Greg Claytonff39f742011-04-01 00:29:43 +0000580 Stream &ostrm = result.GetOutputStream();
581
Greg Clayton24bc5d92011-03-30 18:16:51 +0000582 lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
583 if (pid != LLDB_INVALID_PROCESS_ID)
584 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000585 ProcessInstanceInfo proc_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000586 if (platform_sp->GetProcessInfo (pid, proc_info))
587 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000588 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
589 proc_info.DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000590 result.SetStatus (eReturnStatusSuccessFinishResult);
591 }
592 else
593 {
594 result.AppendErrorWithFormat ("no process found with pid = %i\n", pid);
595 result.SetStatus (eReturnStatusFailed);
596 }
597 }
598 else
599 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000600 ProcessInstanceInfoList proc_infos;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000601 const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000602 const char *match_desc = NULL;
603 const char *match_name = m_options.match_info.GetProcessInfo().GetName();
604 if (match_name && match_name[0])
605 {
606 switch (m_options.match_info.GetNameMatchType())
607 {
608 case eNameMatchIgnore: break;
609 case eNameMatchEquals: match_desc = "matched"; break;
610 case eNameMatchContains: match_desc = "contained"; break;
611 case eNameMatchStartsWith: match_desc = "started with"; break;
612 case eNameMatchEndsWith: match_desc = "ended with"; break;
613 case eNameMatchRegularExpression: match_desc = "matched the regular expression"; break;
614 }
615 }
616
Greg Clayton24bc5d92011-03-30 18:16:51 +0000617 if (matches == 0)
618 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000619 if (match_desc)
620 result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n",
621 match_desc,
622 match_name,
623 platform_sp->GetShortPluginName());
624 else
625 result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetShortPluginName());
626 result.SetStatus (eReturnStatusFailed);
627 }
628 else
629 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000630 result.AppendMessageWithFormat ("%u matching process%s found on \"%s\"",
631 matches,
632 matches > 1 ? "es were" : " was",
633 platform_sp->GetName());
634 if (match_desc)
635 result.AppendMessageWithFormat (" whose name %s \"%s\"",
636 match_desc,
637 match_name);
638 result.AppendMessageWithFormat ("\n");
639 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000640 for (uint32_t i=0; i<matches; ++i)
641 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000642 proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000643 }
644 }
645 }
646 }
647 }
648 else
649 {
650 result.AppendError ("invalid args: process list takes only options\n");
651 result.SetStatus (eReturnStatusFailed);
652 }
653 }
654 else
655 {
656 result.AppendError ("no platform is selected\n");
657 result.SetStatus (eReturnStatusFailed);
658 }
659 return result.Succeeded();
660 }
661
662 virtual Options *
663 GetOptions ()
664 {
665 return &m_options;
666 }
667
668protected:
669
670 class CommandOptions : public Options
671 {
672 public:
673
Greg Claytonf15996e2011-04-07 22:46:35 +0000674 CommandOptions (CommandInterpreter &interpreter) :
675 Options (interpreter),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000676 match_info ()
677 {
678 }
679
680 virtual
681 ~CommandOptions ()
682 {
683 }
684
685 virtual Error
686 SetOptionValue (int option_idx, const char *option_arg)
687 {
688 Error error;
689 char short_option = (char) m_getopt_table[option_idx].val;
690 bool success = false;
691
692 switch (short_option)
693 {
694 case 'p':
695 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
696 if (!success)
697 error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
698 break;
699
700 case 'P':
701 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
702 if (!success)
703 error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
704 break;
705
706 case 'u':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000707 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000708 if (!success)
709 error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
710 break;
711
712 case 'U':
713 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
714 if (!success)
715 error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
716 break;
717
718 case 'g':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000719 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000720 if (!success)
721 error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
722 break;
723
724 case 'G':
725 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
726 if (!success)
727 error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
728 break;
729
730 case 'a':
Greg Claytonf15996e2011-04-07 22:46:35 +0000731 match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg, m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform().get());
Greg Clayton24bc5d92011-03-30 18:16:51 +0000732 break;
733
734 case 'n':
735 match_info.GetProcessInfo().SetName (option_arg);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000736 match_info.SetNameMatchType (eNameMatchEquals);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000737 break;
738
739 case 'e':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000740 match_info.GetProcessInfo().SetName (option_arg);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000741 match_info.SetNameMatchType (eNameMatchEndsWith);
742 break;
743
744 case 's':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000745 match_info.GetProcessInfo().SetName (option_arg);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000746 match_info.SetNameMatchType (eNameMatchStartsWith);
747 break;
748
749 case 'c':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000750 match_info.GetProcessInfo().SetName (option_arg);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000751 match_info.SetNameMatchType (eNameMatchContains);
752 break;
753
754 case 'r':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000755 match_info.GetProcessInfo().SetName (option_arg);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000756 match_info.SetNameMatchType (eNameMatchRegularExpression);
757 break;
758
Greg Claytonb72d0f02011-04-12 05:54:46 +0000759 case 'A':
760 show_args = true;
761 break;
762
763 case 'v':
764 verbose = true;
765 break;
766
Greg Clayton24bc5d92011-03-30 18:16:51 +0000767 default:
768 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
769 break;
770 }
771
772 return error;
773 }
774
775 void
776 ResetOptionValues ()
777 {
778 match_info.Clear();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000779 show_args = false;
780 verbose = false;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000781 }
782
783 const OptionDefinition*
784 GetDefinitions ()
785 {
786 return g_option_table;
787 }
788
789 // Options table: Required for subclasses of Options.
790
791 static OptionDefinition g_option_table[];
792
793 // Instance variables to hold the values for command options.
794
Greg Claytonb72d0f02011-04-12 05:54:46 +0000795 ProcessInstanceInfoMatch match_info;
796 bool show_args;
797 bool verbose;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000798 };
799 CommandOptions m_options;
800};
801
802OptionDefinition
803CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
804{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000805{ LLDB_OPT_SET_1, false, "pid" , 'p', required_argument, NULL, 0, eArgTypePid , "List the process info for a specific process ID." },
806{ LLDB_OPT_SET_2, true , "name" , 'n', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." },
807{ LLDB_OPT_SET_3, true , "ends-with" , 'e', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that end with a string." },
808{ LLDB_OPT_SET_4, true , "starts-with" , 's', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that start with a string." },
809{ LLDB_OPT_SET_5, true , "contains" , 'c', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that contain a string." },
810{ LLDB_OPT_SET_6, true , "regex" , 'r', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that match a regular expression." },
811{ ~LLDB_OPT_SET_1, false, "parent" , 'P', required_argument, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
812{ ~LLDB_OPT_SET_1, false, "uid" , 'u', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching user ID." },
813{ ~LLDB_OPT_SET_1, false, "euid" , 'U', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective user ID." },
814{ ~LLDB_OPT_SET_1, false, "gid" , 'g', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching group ID." },
815{ ~LLDB_OPT_SET_1, false, "egid" , 'G', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective group ID." },
816{ ~LLDB_OPT_SET_1, false, "arch" , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
817{ LLDB_OPT_SET_ALL, false, "show-args" , 'A', no_argument , NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." },
818{ LLDB_OPT_SET_ALL, false, "verbose" , 'v', no_argument , NULL, 0, eArgTypeNone , "Enable verbose output." },
819{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000820};
821
Greg Claytonff39f742011-04-01 00:29:43 +0000822//----------------------------------------------------------------------
823// "platform process info"
824//----------------------------------------------------------------------
825class CommandObjectPlatformProcessInfo : public CommandObject
826{
827public:
828 CommandObjectPlatformProcessInfo (CommandInterpreter &interpreter) :
829 CommandObject (interpreter,
830 "platform process info",
831 "Get detailed information for one or more process by process ID.",
832 "platform process info <pid> [<pid> <pid> ...]",
833 0)
834 {
835 CommandArgumentEntry arg;
836 CommandArgumentData pid_args;
837
838 // Define the first (and only) variant of this arg.
839 pid_args.arg_type = eArgTypePid;
840 pid_args.arg_repetition = eArgRepeatStar;
841
842 // There is only one variant this argument could be; put it into the argument entry.
843 arg.push_back (pid_args);
844
845 // Push the data for the first argument into the m_arguments vector.
846 m_arguments.push_back (arg);
847 }
848
849 virtual
850 ~CommandObjectPlatformProcessInfo ()
851 {
852 }
853
854 virtual bool
855 Execute (Args& args, CommandReturnObject &result)
856 {
857 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
858 if (platform_sp)
859 {
860 const size_t argc = args.GetArgumentCount();
861 if (argc > 0)
862 {
863 Error error;
864
865 if (platform_sp->IsConnected())
866 {
867 Stream &ostrm = result.GetOutputStream();
868 bool success;
869 for (size_t i=0; i<argc; ++ i)
870 {
871 const char *arg = args.GetArgumentAtIndex(i);
872 lldb::pid_t pid = Args::StringToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success);
873 if (success)
874 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000875 ProcessInstanceInfo proc_info;
Greg Claytonff39f742011-04-01 00:29:43 +0000876 if (platform_sp->GetProcessInfo (pid, proc_info))
877 {
878 ostrm.Printf ("Process information for process %i:\n", pid);
879 proc_info.Dump (ostrm, platform_sp.get());
880 }
881 else
882 {
883 ostrm.Printf ("error: no process information is available for process %i\n", pid);
884 }
885 ostrm.EOL();
886 }
887 else
888 {
889 result.AppendErrorWithFormat ("invalid process ID argument '%s'", arg);
890 result.SetStatus (eReturnStatusFailed);
891 break;
892 }
893 }
894 }
895 else
896 {
897 // Not connected...
898 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName());
899 result.SetStatus (eReturnStatusFailed);
900 }
901 }
902 else
903 {
904 // Bad args
905 result.AppendError ("\"platform disconnect\" doesn't take any arguments");
906 result.SetStatus (eReturnStatusFailed);
907 }
908 }
909 else
910 {
911 result.AppendError ("no platform is currently selected");
912 result.SetStatus (eReturnStatusFailed);
913 }
914 return result.Succeeded();
915 }
916};
917
918
919
920
Greg Clayton24bc5d92011-03-30 18:16:51 +0000921class CommandObjectPlatformProcess : public CommandObjectMultiword
922{
923public:
924 //------------------------------------------------------------------
925 // Constructors and Destructors
926 //------------------------------------------------------------------
927 CommandObjectPlatformProcess (CommandInterpreter &interpreter) :
928 CommandObjectMultiword (interpreter,
929 "platform process",
930 "A set of commands to query, launch and attach to platform processes",
931 "platform process [attach|launch|list] ...")
932 {
933// LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
Greg Claytonb72d0f02011-04-12 05:54:46 +0000934 LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
Greg Claytonff39f742011-04-01 00:29:43 +0000935 LoadSubCommand ("info" , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000936 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
937
938 }
939
940 virtual
941 ~CommandObjectPlatformProcess ()
942 {
943 }
944
945private:
946 //------------------------------------------------------------------
947 // For CommandObjectPlatform only
948 //------------------------------------------------------------------
949 DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformProcess);
950};
Greg Claytonb1888f22011-03-19 01:12:21 +0000951
952//----------------------------------------------------------------------
953// CommandObjectPlatform constructor
954//----------------------------------------------------------------------
955CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
956 CommandObjectMultiword (interpreter,
957 "platform",
958 "A set of commands to manage and create platforms.",
Greg Claytonff39f742011-04-01 00:29:43 +0000959 "platform [connect|create|disconnect|info|list|status|select] ...")
Greg Claytonb1888f22011-03-19 01:12:21 +0000960{
961 LoadSubCommand ("create", CommandObjectSP (new CommandObjectPlatformCreate (interpreter)));
962 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
963 LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
964 LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000965 LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
966 LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000967 LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000968}
969
970
971//----------------------------------------------------------------------
972// Destructor
973//----------------------------------------------------------------------
974CommandObjectPlatform::~CommandObjectPlatform()
975{
976}