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