blob: ecc24a6a5a68f923f52cccadc7b33513253674e1 [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();
376 Target *target = m_interpreter.GetExecutionContext().target;
377 ModuleSP exe_module_sp;
378 if (target)
379 {
380 exe_module_sp = target->GetExecutableModule();
381 if (exe_module_sp)
382 {
383 m_options.launch_info.GetExecutableFile () = exe_module_sp->GetFileSpec();
384 char exe_path[PATH_MAX];
385 if (m_options.launch_info.GetExecutableFile ().GetPath (exe_path, sizeof(exe_path)))
386 m_options.launch_info.GetArguments().AppendArgument (exe_path);
387 m_options.launch_info.GetArchitecture() = exe_module_sp->GetArchitecture();
388 }
389 }
390
391 if (argc > 0)
392 {
393 if (m_options.launch_info.GetExecutableFile ())
394 {
395 // We already have an executable file, so we will use this
396 // and all arguments to this function are extra arguments
397 m_options.launch_info.GetArguments().AppendArguments (args);
398 }
399 else
400 {
401 // We don't have any file yet, so the first argument is our
402 // executable, and the rest are program arguments
403 const bool first_arg_is_executable = true;
404 m_options.launch_info.SetArgumentsFromArgs (args,
405 first_arg_is_executable,
406 first_arg_is_executable);
407 }
408 }
409
410 if (m_options.launch_info.GetExecutableFile ())
411 {
412 Debugger &debugger = m_interpreter.GetDebugger();
413
414 if (argc == 0)
415 {
416 lldb::UserSettingsControllerSP process_usc_sp (Process::GetSettingsController ());
417 if (process_usc_sp)
418 {
419 SettableVariableType type;
420 StringList settings_args (process_usc_sp->GetVariable ("process.run-args",
421 type,
422 m_interpreter.GetDebugger().GetInstanceName().GetCString(),
423 error));
424 if (error.Success())
425 {
426 const size_t num_settings_args = settings_args.GetSize();
427 for (size_t i=0; i<num_settings_args; ++i)
428 m_options.launch_info.GetArguments().AppendArgument (settings_args.GetStringAtIndex(i));
429 }
430 }
431 }
432
433 ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info,
434 debugger,
435 target,
436 debugger.GetListener(),
437 error));
438 if (process_sp && process_sp->IsAlive())
439 {
440 result.SetStatus (eReturnStatusSuccessFinishNoResult);
441 return true;
442 }
443
444 if (error.Success())
445 result.AppendError ("process launch failed");
446 else
447 result.AppendError (error.AsCString());
448 result.SetStatus (eReturnStatusFailed);
449 }
450 else
451 {
452 result.AppendError ("'platform process launch' uses the current target file and arguments, or the executable and its arguments can be specified in this command");
453 result.SetStatus (eReturnStatusFailed);
454 return false;
455 }
456 }
457 else
458 {
459 result.AppendError ("no platform is selected\n");
460 }
461 return result.Succeeded();
462 }
463
464 virtual Options *
465 GetOptions ()
466 {
467 return &m_options;
468 }
469
470protected:
471 ProcessLaunchCommandOptions m_options;
472};
473
Greg Claytoncb8977d2011-03-23 00:09:55 +0000474
475
Greg Clayton24bc5d92011-03-30 18:16:51 +0000476//----------------------------------------------------------------------
477// "platform process list"
478//----------------------------------------------------------------------
479class CommandObjectPlatformProcessList : public CommandObject
480{
481public:
482 CommandObjectPlatformProcessList (CommandInterpreter &interpreter) :
Greg Claytonf15996e2011-04-07 22:46:35 +0000483 CommandObject (interpreter,
484 "platform process list",
485 "List processes on a remote platform by name, pid, or many other matching attributes.",
486 "platform process list",
487 0),
488 m_options (interpreter)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000489 {
490 }
491
492 virtual
493 ~CommandObjectPlatformProcessList ()
494 {
495 }
496
497 virtual bool
498 Execute (Args& args, CommandReturnObject &result)
499 {
500 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
501
502 if (platform_sp)
503 {
504 Error error;
505 if (args.GetArgumentCount() == 0)
506 {
507
508 if (platform_sp)
509 {
Greg Claytonff39f742011-04-01 00:29:43 +0000510 Stream &ostrm = result.GetOutputStream();
511
Greg Clayton24bc5d92011-03-30 18:16:51 +0000512 lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
513 if (pid != LLDB_INVALID_PROCESS_ID)
514 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000515 ProcessInstanceInfo proc_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000516 if (platform_sp->GetProcessInfo (pid, proc_info))
517 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000518 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
519 proc_info.DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000520 result.SetStatus (eReturnStatusSuccessFinishResult);
521 }
522 else
523 {
524 result.AppendErrorWithFormat ("no process found with pid = %i\n", pid);
525 result.SetStatus (eReturnStatusFailed);
526 }
527 }
528 else
529 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000530 ProcessInstanceInfoList proc_infos;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000531 const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000532 const char *match_desc = NULL;
533 const char *match_name = m_options.match_info.GetProcessInfo().GetName();
534 if (match_name && match_name[0])
535 {
536 switch (m_options.match_info.GetNameMatchType())
537 {
538 case eNameMatchIgnore: break;
539 case eNameMatchEquals: match_desc = "matched"; break;
540 case eNameMatchContains: match_desc = "contained"; break;
541 case eNameMatchStartsWith: match_desc = "started with"; break;
542 case eNameMatchEndsWith: match_desc = "ended with"; break;
543 case eNameMatchRegularExpression: match_desc = "matched the regular expression"; break;
544 }
545 }
546
Greg Clayton24bc5d92011-03-30 18:16:51 +0000547 if (matches == 0)
548 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000549 if (match_desc)
550 result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n",
551 match_desc,
552 match_name,
553 platform_sp->GetShortPluginName());
554 else
555 result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetShortPluginName());
556 result.SetStatus (eReturnStatusFailed);
557 }
558 else
559 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000560 result.AppendMessageWithFormat ("%u matching process%s found on \"%s\"",
561 matches,
562 matches > 1 ? "es were" : " was",
563 platform_sp->GetName());
564 if (match_desc)
565 result.AppendMessageWithFormat (" whose name %s \"%s\"",
566 match_desc,
567 match_name);
568 result.AppendMessageWithFormat ("\n");
569 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000570 for (uint32_t i=0; i<matches; ++i)
571 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000572 proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000573 }
574 }
575 }
576 }
577 }
578 else
579 {
580 result.AppendError ("invalid args: process list takes only options\n");
581 result.SetStatus (eReturnStatusFailed);
582 }
583 }
584 else
585 {
586 result.AppendError ("no platform is selected\n");
587 result.SetStatus (eReturnStatusFailed);
588 }
589 return result.Succeeded();
590 }
591
592 virtual Options *
593 GetOptions ()
594 {
595 return &m_options;
596 }
597
598protected:
599
600 class CommandOptions : public Options
601 {
602 public:
603
Greg Claytonf15996e2011-04-07 22:46:35 +0000604 CommandOptions (CommandInterpreter &interpreter) :
605 Options (interpreter),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000606 match_info ()
607 {
608 }
609
610 virtual
611 ~CommandOptions ()
612 {
613 }
614
615 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000616 SetOptionValue (uint32_t option_idx, const char *option_arg)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000617 {
618 Error error;
619 char short_option = (char) m_getopt_table[option_idx].val;
620 bool success = false;
621
622 switch (short_option)
623 {
624 case 'p':
625 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
626 if (!success)
627 error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
628 break;
629
630 case 'P':
631 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
632 if (!success)
633 error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
634 break;
635
636 case 'u':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000637 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000638 if (!success)
639 error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
640 break;
641
642 case 'U':
643 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
644 if (!success)
645 error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
646 break;
647
648 case 'g':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000649 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000650 if (!success)
651 error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
652 break;
653
654 case 'G':
655 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
656 if (!success)
657 error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
658 break;
659
660 case 'a':
Greg Claytonf15996e2011-04-07 22:46:35 +0000661 match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg, m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform().get());
Greg Clayton24bc5d92011-03-30 18:16:51 +0000662 break;
663
664 case 'n':
665 match_info.GetProcessInfo().SetName (option_arg);
Greg Claytonb72d0f02011-04-12 05:54:46 +0000666 match_info.SetNameMatchType (eNameMatchEquals);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000667 break;
668
669 case 'e':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000670 match_info.GetProcessInfo().SetName (option_arg);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000671 match_info.SetNameMatchType (eNameMatchEndsWith);
672 break;
673
674 case 's':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000675 match_info.GetProcessInfo().SetName (option_arg);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000676 match_info.SetNameMatchType (eNameMatchStartsWith);
677 break;
678
679 case 'c':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000680 match_info.GetProcessInfo().SetName (option_arg);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000681 match_info.SetNameMatchType (eNameMatchContains);
682 break;
683
684 case 'r':
Greg Claytonb72d0f02011-04-12 05:54:46 +0000685 match_info.GetProcessInfo().SetName (option_arg);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000686 match_info.SetNameMatchType (eNameMatchRegularExpression);
687 break;
688
Greg Claytonb72d0f02011-04-12 05:54:46 +0000689 case 'A':
690 show_args = true;
691 break;
692
693 case 'v':
694 verbose = true;
695 break;
696
Greg Clayton24bc5d92011-03-30 18:16:51 +0000697 default:
698 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
699 break;
700 }
701
702 return error;
703 }
704
705 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000706 OptionParsingStarting ()
Greg Clayton24bc5d92011-03-30 18:16:51 +0000707 {
708 match_info.Clear();
Greg Claytonb72d0f02011-04-12 05:54:46 +0000709 show_args = false;
710 verbose = false;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000711 }
712
713 const OptionDefinition*
714 GetDefinitions ()
715 {
716 return g_option_table;
717 }
718
719 // Options table: Required for subclasses of Options.
720
721 static OptionDefinition g_option_table[];
722
723 // Instance variables to hold the values for command options.
724
Greg Claytonb72d0f02011-04-12 05:54:46 +0000725 ProcessInstanceInfoMatch match_info;
726 bool show_args;
727 bool verbose;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000728 };
729 CommandOptions m_options;
730};
731
732OptionDefinition
733CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
734{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000735{ LLDB_OPT_SET_1, false, "pid" , 'p', required_argument, NULL, 0, eArgTypePid , "List the process info for a specific process ID." },
736{ LLDB_OPT_SET_2, true , "name" , 'n', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." },
737{ LLDB_OPT_SET_3, true , "ends-with" , 'e', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that end with a string." },
738{ LLDB_OPT_SET_4, true , "starts-with" , 's', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that start with a string." },
739{ LLDB_OPT_SET_5, true , "contains" , 'c', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that contain a string." },
740{ LLDB_OPT_SET_6, true , "regex" , 'r', required_argument, NULL, 0, eArgTypeNone , "Find processes with executable basenames that match a regular expression." },
741{ ~LLDB_OPT_SET_1, false, "parent" , 'P', required_argument, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
742{ ~LLDB_OPT_SET_1, false, "uid" , 'u', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching user ID." },
743{ ~LLDB_OPT_SET_1, false, "euid" , 'U', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective user ID." },
744{ ~LLDB_OPT_SET_1, false, "gid" , 'g', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching group ID." },
745{ ~LLDB_OPT_SET_1, false, "egid" , 'G', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective group ID." },
746{ ~LLDB_OPT_SET_1, false, "arch" , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
747{ LLDB_OPT_SET_ALL, false, "show-args" , 'A', no_argument , NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." },
748{ LLDB_OPT_SET_ALL, false, "verbose" , 'v', no_argument , NULL, 0, eArgTypeNone , "Enable verbose output." },
749{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000750};
751
Greg Claytonff39f742011-04-01 00:29:43 +0000752//----------------------------------------------------------------------
753// "platform process info"
754//----------------------------------------------------------------------
755class CommandObjectPlatformProcessInfo : public CommandObject
756{
757public:
758 CommandObjectPlatformProcessInfo (CommandInterpreter &interpreter) :
759 CommandObject (interpreter,
760 "platform process info",
761 "Get detailed information for one or more process by process ID.",
762 "platform process info <pid> [<pid> <pid> ...]",
763 0)
764 {
765 CommandArgumentEntry arg;
766 CommandArgumentData pid_args;
767
768 // Define the first (and only) variant of this arg.
769 pid_args.arg_type = eArgTypePid;
770 pid_args.arg_repetition = eArgRepeatStar;
771
772 // There is only one variant this argument could be; put it into the argument entry.
773 arg.push_back (pid_args);
774
775 // Push the data for the first argument into the m_arguments vector.
776 m_arguments.push_back (arg);
777 }
778
779 virtual
780 ~CommandObjectPlatformProcessInfo ()
781 {
782 }
783
784 virtual bool
785 Execute (Args& args, CommandReturnObject &result)
786 {
787 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
788 if (platform_sp)
789 {
790 const size_t argc = args.GetArgumentCount();
791 if (argc > 0)
792 {
793 Error error;
794
795 if (platform_sp->IsConnected())
796 {
797 Stream &ostrm = result.GetOutputStream();
798 bool success;
799 for (size_t i=0; i<argc; ++ i)
800 {
801 const char *arg = args.GetArgumentAtIndex(i);
802 lldb::pid_t pid = Args::StringToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success);
803 if (success)
804 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000805 ProcessInstanceInfo proc_info;
Greg Claytonff39f742011-04-01 00:29:43 +0000806 if (platform_sp->GetProcessInfo (pid, proc_info))
807 {
808 ostrm.Printf ("Process information for process %i:\n", pid);
809 proc_info.Dump (ostrm, platform_sp.get());
810 }
811 else
812 {
813 ostrm.Printf ("error: no process information is available for process %i\n", pid);
814 }
815 ostrm.EOL();
816 }
817 else
818 {
819 result.AppendErrorWithFormat ("invalid process ID argument '%s'", arg);
820 result.SetStatus (eReturnStatusFailed);
821 break;
822 }
823 }
824 }
825 else
826 {
827 // Not connected...
828 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName());
829 result.SetStatus (eReturnStatusFailed);
830 }
831 }
832 else
833 {
Johnny Chen1736fef2011-05-09 19:05:46 +0000834 // No args
835 result.AppendError ("one or more process id(s) must be specified");
Greg Claytonff39f742011-04-01 00:29:43 +0000836 result.SetStatus (eReturnStatusFailed);
837 }
838 }
839 else
840 {
841 result.AppendError ("no platform is currently selected");
842 result.SetStatus (eReturnStatusFailed);
843 }
844 return result.Succeeded();
845 }
846};
847
848
849
850
Greg Clayton24bc5d92011-03-30 18:16:51 +0000851class CommandObjectPlatformProcess : public CommandObjectMultiword
852{
853public:
854 //------------------------------------------------------------------
855 // Constructors and Destructors
856 //------------------------------------------------------------------
857 CommandObjectPlatformProcess (CommandInterpreter &interpreter) :
858 CommandObjectMultiword (interpreter,
859 "platform process",
860 "A set of commands to query, launch and attach to platform processes",
861 "platform process [attach|launch|list] ...")
862 {
863// LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
Greg Claytonb72d0f02011-04-12 05:54:46 +0000864 LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
Greg Claytonff39f742011-04-01 00:29:43 +0000865 LoadSubCommand ("info" , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000866 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
867
868 }
869
870 virtual
871 ~CommandObjectPlatformProcess ()
872 {
873 }
874
875private:
876 //------------------------------------------------------------------
877 // For CommandObjectPlatform only
878 //------------------------------------------------------------------
879 DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformProcess);
880};
Greg Claytonb1888f22011-03-19 01:12:21 +0000881
882//----------------------------------------------------------------------
883// CommandObjectPlatform constructor
884//----------------------------------------------------------------------
885CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
886 CommandObjectMultiword (interpreter,
887 "platform",
888 "A set of commands to manage and create platforms.",
Greg Clayton143fcc32011-04-13 00:18:08 +0000889 "platform [connect|disconnect|info|list|status|select] ...")
Greg Claytonb1888f22011-03-19 01:12:21 +0000890{
Greg Claytonb1888f22011-03-19 01:12:21 +0000891 LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
Greg Clayton143fcc32011-04-13 00:18:08 +0000892 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000893 LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
Greg Claytoncb8977d2011-03-23 00:09:55 +0000894 LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
895 LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000896 LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
Greg Claytonb1888f22011-03-19 01:12:21 +0000897}
898
899
900//----------------------------------------------------------------------
901// Destructor
902//----------------------------------------------------------------------
903CommandObjectPlatform::~CommandObjectPlatform()
904{
905}