blob: eea2a75bfb2012b7b618b33fad9a698cc4d4b0ce [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectTarget.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 "CommandObjectTarget.h"
11
12// C Includes
13#include <errno.h>
Greg Clayton81040f42011-02-01 01:13:32 +000014
Chris Lattner24943d22010-06-08 16:52:24 +000015// C++ Includes
16// Other libraries and framework includes
17// Project includes
Jim Ingham84cdc152010-06-15 19:49:27 +000018#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Core/Debugger.h"
Jim Inghamd60d94a2011-03-11 03:53:59 +000020#include "lldb/Core/InputReader.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000021#include "lldb/Core/State.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Core/Timer.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Interpreter/CommandInterpreter.h"
24#include "lldb/Interpreter/CommandReturnObject.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000025#include "lldb/Interpreter/OptionGroupArchitecture.h"
26#include "lldb/Interpreter/OptionGroupPlatform.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Target/Process.h"
28#include "lldb/Target/StackFrame.h"
29#include "lldb/Target/Thread.h"
Jim Inghamd60d94a2011-03-11 03:53:59 +000030#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000031
32using namespace lldb;
33using namespace lldb_private;
34
Greg Claytonabe0fed2011-04-18 08:33:37 +000035
36
37static void
38DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
39{
Greg Clayton52c8b6e2011-04-19 04:19:37 +000040 const ArchSpec &target_arch = target->GetArchitecture();
Greg Claytonabe0fed2011-04-18 08:33:37 +000041
42 ModuleSP exe_module_sp (target->GetExecutableModule ());
43 char exe_path[PATH_MAX];
44 bool exe_valid = false;
45 if (exe_module_sp)
46 exe_valid = exe_module_sp->GetFileSpec().GetPath (exe_path, sizeof(exe_path));
47
48 if (!exe_valid)
49 ::strcpy (exe_path, "<none>");
50
51 strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path);
52
53 uint32_t properties = 0;
54 if (target_arch.IsValid())
55 {
56 strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str());
57 properties++;
58 }
59 PlatformSP platform_sp (target->GetPlatform());
60 if (platform_sp)
61 strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName());
62
63 ProcessSP process_sp (target->GetProcessSP());
64 bool show_process_status = false;
65 if (process_sp)
66 {
67 lldb::pid_t pid = process_sp->GetID();
68 StateType state = process_sp->GetState();
69 if (show_stopped_process_status)
70 show_process_status = StateIsStoppedState(state);
71 const char *state_cstr = StateAsCString (state);
72 if (pid != LLDB_INVALID_PROCESS_ID)
73 strm.Printf ("%spid=%i", properties++ > 0 ? ", " : " ( ", pid);
74 strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
75 }
76 if (properties > 0)
77 strm.PutCString (" )\n");
78 else
79 strm.EOL();
80 if (show_process_status)
81 {
82 const bool only_threads_with_stop_reason = true;
83 const uint32_t start_frame = 0;
84 const uint32_t num_frames = 1;
85 const uint32_t num_frames_with_source = 1;
86 process_sp->GetStatus (strm);
87 process_sp->GetThreadStatus (strm,
88 only_threads_with_stop_reason,
89 start_frame,
90 num_frames,
91 num_frames_with_source);
92
93 }
94}
95
96static uint32_t
97DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm)
98{
99 const uint32_t num_targets = target_list.GetNumTargets();
100 if (num_targets)
101 {
102 TargetSP selected_target_sp (target_list.GetSelectedTarget());
103 strm.PutCString ("Current targets:\n");
104 for (uint32_t i=0; i<num_targets; ++i)
105 {
106 TargetSP target_sp (target_list.GetTargetAtIndex (i));
107 if (target_sp)
108 {
109 bool is_selected = target_sp.get() == selected_target_sp.get();
110 DumpTargetInfo (i,
111 target_sp.get(),
112 is_selected ? "* " : " ",
113 show_stopped_process_status,
114 strm);
115 }
116 }
117 }
118 return num_targets;
119}
120#pragma mark CommandObjectTargetCreate
121
122//-------------------------------------------------------------------------
123// "target create"
124//-------------------------------------------------------------------------
125
126class CommandObjectTargetCreate : public CommandObject
127{
128public:
129 CommandObjectTargetCreate(CommandInterpreter &interpreter) :
130 CommandObject (interpreter,
131 "target create",
132 "Create a target using the argument as the main executable.",
133 NULL),
134 m_option_group (interpreter),
135 m_file_options (),
136 m_platform_options(true) // Do include the "--platform" option in the platform settings by passing true
137 {
138 CommandArgumentEntry arg;
139 CommandArgumentData file_arg;
140
141 // Define the first (and only) variant of this arg.
142 file_arg.arg_type = eArgTypeFilename;
143 file_arg.arg_repetition = eArgRepeatPlain;
144
145 // There is only one variant this argument could be; put it into the argument entry.
146 arg.push_back (file_arg);
147
148 // Push the data for the first argument into the m_arguments vector.
149 m_arguments.push_back (arg);
150
151 m_option_group.Append (&m_file_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
152 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
153 m_option_group.Finalize();
154 }
155
156 ~CommandObjectTargetCreate ()
157 {
158 }
159
160 Options *
161 GetOptions ()
162 {
163 return &m_option_group;
164 }
165
166 bool
167 Execute (Args& command, CommandReturnObject &result)
168 {
169 const int argc = command.GetArgumentCount();
170 if (argc == 1)
171 {
172 const char *file_path = command.GetArgumentAtIndex(0);
173 Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
174 FileSpec file_spec (file_path, true);
175
176 bool select = true;
177 PlatformSP platform_sp;
178
179 Error error;
180
181 if (m_platform_options.PlatformWasSpecified ())
182 {
183 platform_sp = m_platform_options.CreatePlatformWithOptions(m_interpreter, select, error);
184 if (!platform_sp)
185 {
186 result.AppendError(error.AsCString());
187 result.SetStatus (eReturnStatusFailed);
188 return false;
189 }
190 }
191 ArchSpec file_arch;
192
193 const char *arch_cstr = m_file_options.GetArchitectureName();
194 if (arch_cstr)
195 {
196 if (!platform_sp)
197 platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
198 if (!m_file_options.GetArchitecture(platform_sp.get(), file_arch))
199 {
200 result.AppendErrorWithFormat("invalid architecture '%s'\n", arch_cstr);
201 result.SetStatus (eReturnStatusFailed);
202 return false;
203 }
204 }
205
206 if (! file_spec.Exists() && !file_spec.ResolveExecutableLocation())
207 {
208 result.AppendErrorWithFormat ("File '%s' does not exist.\n", file_path);
209 result.SetStatus (eReturnStatusFailed);
210 return false;
211 }
212
213 TargetSP target_sp;
214 Debugger &debugger = m_interpreter.GetDebugger();
215 error = debugger.GetTargetList().CreateTarget (debugger, file_spec, file_arch, true, target_sp);
216
217 if (target_sp)
218 {
219 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
220 result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName());
221 result.SetStatus (eReturnStatusSuccessFinishNoResult);
222 }
223 else
224 {
225 result.AppendError(error.AsCString());
226 result.SetStatus (eReturnStatusFailed);
227 }
228 }
229 else
230 {
231 result.AppendErrorWithFormat("'%s' takes exactly one executable path argument.\n", m_cmd_name.c_str());
232 result.SetStatus (eReturnStatusFailed);
233 }
234 return result.Succeeded();
235
236 }
237
238 int
239 HandleArgumentCompletion (Args &input,
240 int &cursor_index,
241 int &cursor_char_position,
242 OptionElementVector &opt_element_vector,
243 int match_start_point,
244 int max_return_elements,
245 bool &word_complete,
246 StringList &matches)
247 {
248 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
249 completion_str.erase (cursor_char_position);
250
251 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
252 CommandCompletions::eDiskFileCompletion,
253 completion_str.c_str(),
254 match_start_point,
255 max_return_elements,
256 NULL,
257 word_complete,
258 matches);
259 return matches.GetSize();
260 }
261private:
262 OptionGroupOptions m_option_group;
263 OptionGroupArchitecture m_file_options;
264 OptionGroupPlatform m_platform_options;
265
266};
267
268#pragma mark CommandObjectTargetList
269
270//----------------------------------------------------------------------
271// "target list"
272//----------------------------------------------------------------------
273
274class CommandObjectTargetList : public CommandObject
275{
276public:
277 CommandObjectTargetList (CommandInterpreter &interpreter) :
278 CommandObject (interpreter,
279 "target list",
280 "List all current targets in the current debug session.",
281 NULL,
282 0)
283 {
284 }
285
286 virtual
287 ~CommandObjectTargetList ()
288 {
289 }
290
291 virtual bool
292 Execute (Args& args, CommandReturnObject &result)
293 {
294 if (args.GetArgumentCount() == 0)
295 {
296 Stream &strm = result.GetOutputStream();
297
298 bool show_stopped_process_status = false;
299 if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0)
300 {
301 strm.PutCString ("No targets.\n");
302 }
Johnny Chen44dc9d32011-04-18 21:08:05 +0000303 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000304 }
305 else
306 {
307 result.AppendError ("the 'target list' command takes no arguments\n");
308 result.SetStatus (eReturnStatusFailed);
309 }
310 return result.Succeeded();
311 }
312};
313
314
315#pragma mark CommandObjectTargetSelect
316
317//----------------------------------------------------------------------
318// "target select"
319//----------------------------------------------------------------------
320
321class CommandObjectTargetSelect : public CommandObject
322{
323public:
324 CommandObjectTargetSelect (CommandInterpreter &interpreter) :
325 CommandObject (interpreter,
326 "target select",
327 "Select a target as the current target by target index.",
328 NULL,
329 0)
330 {
331 }
332
333 virtual
334 ~CommandObjectTargetSelect ()
335 {
336 }
337
338 virtual bool
339 Execute (Args& args, CommandReturnObject &result)
340 {
341 if (args.GetArgumentCount() == 1)
342 {
343 bool success = false;
344 const char *target_idx_arg = args.GetArgumentAtIndex(0);
345 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
346 if (success)
347 {
348 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
349 const uint32_t num_targets = target_list.GetNumTargets();
350 if (target_idx < num_targets)
351 {
352 TargetSP target_sp (target_list.GetTargetAtIndex (target_idx));
353 if (target_sp)
354 {
355 Stream &strm = result.GetOutputStream();
356 target_list.SetSelectedTarget (target_sp.get());
357 bool show_stopped_process_status = false;
358 DumpTargetList (target_list, show_stopped_process_status, strm);
Johnny Chen44dc9d32011-04-18 21:08:05 +0000359 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000360 }
361 else
362 {
363 result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx);
364 result.SetStatus (eReturnStatusFailed);
365 }
366 }
367 else
368 {
369 result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
370 target_idx,
371 num_targets - 1);
372 result.SetStatus (eReturnStatusFailed);
373 }
374 }
375 else
376 {
377 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg);
378 result.SetStatus (eReturnStatusFailed);
379 }
380 }
381 else
382 {
383 result.AppendError ("'target select' takes a single argument: a target index\n");
384 result.SetStatus (eReturnStatusFailed);
385 }
386 return result.Succeeded();
387 }
388};
389
390
Chris Lattner24943d22010-06-08 16:52:24 +0000391#pragma mark CommandObjectTargetImageSearchPaths
392
393class CommandObjectTargetImageSearchPathsAdd : public CommandObject
394{
395public:
396
Greg Clayton238c0a12010-09-18 01:14:36 +0000397 CommandObjectTargetImageSearchPathsAdd (CommandInterpreter &interpreter) :
398 CommandObject (interpreter,
399 "target image-search-paths add",
Chris Lattner24943d22010-06-08 16:52:24 +0000400 "Add new image search paths substitution pairs to the current target.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000401 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000402 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000403 CommandArgumentEntry arg;
404 CommandArgumentData old_prefix_arg;
405 CommandArgumentData new_prefix_arg;
406
407 // Define the first variant of this arg pair.
408 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
409 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
410
411 // Define the first variant of this arg pair.
412 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
413 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
414
415 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
416 // must always occur together, they are treated as two variants of one argument rather than two independent
417 // arguments. Push them both into the first argument position for m_arguments...
418
419 arg.push_back (old_prefix_arg);
420 arg.push_back (new_prefix_arg);
421
422 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000423 }
424
425 ~CommandObjectTargetImageSearchPathsAdd ()
426 {
427 }
428
429 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000430 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000431 CommandReturnObject &result)
432 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000433 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000434 if (target)
435 {
436 uint32_t argc = command.GetArgumentCount();
437 if (argc & 1)
438 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000439 result.AppendError ("add requires an even number of arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000440 result.SetStatus (eReturnStatusFailed);
441 }
442 else
443 {
444 for (uint32_t i=0; i<argc; i+=2)
445 {
446 const char *from = command.GetArgumentAtIndex(i);
447 const char *to = command.GetArgumentAtIndex(i+1);
448
449 if (from[0] && to[0])
450 {
451 bool last_pair = ((argc - i) == 2);
Greg Clayton63094e02010-06-23 01:19:29 +0000452 target->GetImageSearchPathList().Append (ConstString(from),
453 ConstString(to),
454 last_pair); // Notify if this is the last pair
Johnny Chen4d661352011-02-03 00:30:19 +0000455 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000456 }
457 else
458 {
459 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000460 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000461 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000462 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000463 result.SetStatus (eReturnStatusFailed);
464 }
465 }
466 }
467 }
468 else
469 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000470 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000471 result.SetStatus (eReturnStatusFailed);
472 }
473 return result.Succeeded();
474 }
475};
476
477class CommandObjectTargetImageSearchPathsClear : public CommandObject
478{
479public:
480
Greg Clayton238c0a12010-09-18 01:14:36 +0000481 CommandObjectTargetImageSearchPathsClear (CommandInterpreter &interpreter) :
482 CommandObject (interpreter,
483 "target image-search-paths clear",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000484 "Clear all current image search path substitution pairs from the current target.",
Chris Lattner24943d22010-06-08 16:52:24 +0000485 "target image-search-paths clear")
486 {
487 }
488
489 ~CommandObjectTargetImageSearchPathsClear ()
490 {
491 }
492
493 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000494 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000495 CommandReturnObject &result)
496 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000497 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000498 if (target)
499 {
500 bool notify = true;
501 target->GetImageSearchPathList().Clear(notify);
Johnny Chen4d661352011-02-03 00:30:19 +0000502 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000503 }
504 else
505 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000506 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000507 result.SetStatus (eReturnStatusFailed);
508 }
509 return result.Succeeded();
510 }
511};
512
513class CommandObjectTargetImageSearchPathsInsert : public CommandObject
514{
515public:
516
Greg Clayton238c0a12010-09-18 01:14:36 +0000517 CommandObjectTargetImageSearchPathsInsert (CommandInterpreter &interpreter) :
518 CommandObject (interpreter,
519 "target image-search-paths insert",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000520 "Insert a new image search path substitution pair into the current target at the specified index.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000521 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000522 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000523 CommandArgumentEntry arg1;
524 CommandArgumentEntry arg2;
525 CommandArgumentData index_arg;
526 CommandArgumentData old_prefix_arg;
527 CommandArgumentData new_prefix_arg;
528
529 // Define the first and only variant of this arg.
530 index_arg.arg_type = eArgTypeIndex;
531 index_arg.arg_repetition = eArgRepeatPlain;
532
533 // Put the one and only variant into the first arg for m_arguments:
534 arg1.push_back (index_arg);
535
536 // Define the first variant of this arg pair.
537 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
538 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
539
540 // Define the first variant of this arg pair.
541 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
542 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
543
544 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
545 // must always occur together, they are treated as two variants of one argument rather than two independent
546 // arguments. Push them both into the same argument position for m_arguments...
547
548 arg2.push_back (old_prefix_arg);
549 arg2.push_back (new_prefix_arg);
550
551 // Add arguments to m_arguments.
552 m_arguments.push_back (arg1);
553 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +0000554 }
555
556 ~CommandObjectTargetImageSearchPathsInsert ()
557 {
558 }
559
560 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000561 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000562 CommandReturnObject &result)
563 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000564 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000565 if (target)
566 {
567 uint32_t argc = command.GetArgumentCount();
568 // check for at least 3 arguments and an odd nubmer of parameters
569 if (argc >= 3 && argc & 1)
570 {
571 bool success = false;
572
573 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
574
575 if (!success)
576 {
577 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
578 result.SetStatus (eReturnStatusFailed);
579 return result.Succeeded();
580 }
581
582 // shift off the index
583 command.Shift();
584 argc = command.GetArgumentCount();
585
586 for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
587 {
588 const char *from = command.GetArgumentAtIndex(i);
589 const char *to = command.GetArgumentAtIndex(i+1);
590
591 if (from[0] && to[0])
592 {
593 bool last_pair = ((argc - i) == 2);
594 target->GetImageSearchPathList().Insert (ConstString(from),
595 ConstString(to),
596 insert_idx,
597 last_pair);
Johnny Chen4d661352011-02-03 00:30:19 +0000598 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000599 }
600 else
601 {
602 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000603 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000604 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000605 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000606 result.SetStatus (eReturnStatusFailed);
607 return false;
608 }
609 }
610 }
611 else
612 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000613 result.AppendError ("insert requires at least three arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000614 result.SetStatus (eReturnStatusFailed);
615 return result.Succeeded();
616 }
617
618 }
619 else
620 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000621 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000622 result.SetStatus (eReturnStatusFailed);
623 }
624 return result.Succeeded();
625 }
626};
627
628class CommandObjectTargetImageSearchPathsList : public CommandObject
629{
630public:
631
Greg Clayton238c0a12010-09-18 01:14:36 +0000632 CommandObjectTargetImageSearchPathsList (CommandInterpreter &interpreter) :
633 CommandObject (interpreter,
634 "target image-search-paths list",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000635 "List all current image search path substitution pairs in the current target.",
Chris Lattner24943d22010-06-08 16:52:24 +0000636 "target image-search-paths list")
637 {
638 }
639
640 ~CommandObjectTargetImageSearchPathsList ()
641 {
642 }
643
644 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000645 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000646 CommandReturnObject &result)
647 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000648 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000649 if (target)
650 {
651 if (command.GetArgumentCount() != 0)
652 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000653 result.AppendError ("list takes no arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000654 result.SetStatus (eReturnStatusFailed);
655 return result.Succeeded();
656 }
657
658 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
Johnny Chen4d661352011-02-03 00:30:19 +0000659 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000660 }
661 else
662 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000663 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000664 result.SetStatus (eReturnStatusFailed);
665 }
666 return result.Succeeded();
667 }
668};
669
670class CommandObjectTargetImageSearchPathsQuery : public CommandObject
671{
672public:
673
Greg Clayton238c0a12010-09-18 01:14:36 +0000674 CommandObjectTargetImageSearchPathsQuery (CommandInterpreter &interpreter) :
675 CommandObject (interpreter,
676 "target image-search-paths query",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000677 "Transform a path using the first applicable image search path.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000678 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000679 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000680 CommandArgumentEntry arg;
681 CommandArgumentData path_arg;
682
683 // Define the first (and only) variant of this arg.
684 path_arg.arg_type = eArgTypePath;
685 path_arg.arg_repetition = eArgRepeatPlain;
686
687 // There is only one variant this argument could be; put it into the argument entry.
688 arg.push_back (path_arg);
689
690 // Push the data for the first argument into the m_arguments vector.
691 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000692 }
693
694 ~CommandObjectTargetImageSearchPathsQuery ()
695 {
696 }
697
698 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000699 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000700 CommandReturnObject &result)
701 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000702 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000703 if (target)
704 {
705 if (command.GetArgumentCount() != 1)
706 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000707 result.AppendError ("query requires one argument\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000708 result.SetStatus (eReturnStatusFailed);
709 return result.Succeeded();
710 }
711
712 ConstString orig(command.GetArgumentAtIndex(0));
713 ConstString transformed;
714 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
715 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
716 else
717 result.GetOutputStream().Printf("%s\n", orig.GetCString());
Johnny Chen4d661352011-02-03 00:30:19 +0000718
719 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000720 }
721 else
722 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000723 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000724 result.SetStatus (eReturnStatusFailed);
725 }
726 return result.Succeeded();
727 }
728};
729
730// TODO: implement the target select later when we start doing multiple targets
731//#pragma mark CommandObjectTargetSelect
732//
733////-------------------------------------------------------------------------
734//// CommandObjectTargetSelect
735////-------------------------------------------------------------------------
736//
737//class CommandObjectTargetSelect : public CommandObject
738//{
739//public:
740//
741// CommandObjectTargetSelect () :
Greg Clayton238c0a12010-09-18 01:14:36 +0000742// CommandObject (interpreter,
743// frame select",
Chris Lattner24943d22010-06-08 16:52:24 +0000744// "Select the current frame by index in the current thread.",
745// "frame select <frame-index>")
746// {
747// }
748//
749// ~CommandObjectTargetSelect ()
750// {
751// }
752//
753// bool
754// Execute (Args& command,
Greg Clayton63094e02010-06-23 01:19:29 +0000755// Debugger *context,
Greg Clayton238c0a12010-09-18 01:14:36 +0000756// CommandInterpreter &m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000757// CommandReturnObject &result)
758// {
759// ExecutionContext exe_ctx (context->GetExecutionContext());
760// if (exe_ctx.thread)
761// {
762// if (command.GetArgumentCount() == 1)
763// {
764// const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
765//
766// const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount();
767// const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
768// if (frame_idx < num_frames)
769// {
Jim Inghamc8332952010-08-26 21:32:51 +0000770// exe_ctx.thread->SetSelectedFrameByIndex (frame_idx);
771// exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000772//
773// if (exe_ctx.frame)
774// {
775// if (DisplayFrameForExecutionContext (exe_ctx.thread,
776// exe_ctx.frame,
Greg Clayton238c0a12010-09-18 01:14:36 +0000777// m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000778// result.GetOutputStream(),
779// true,
780// true,
781// 3,
782// 3))
783// {
784// result.SetStatus (eReturnStatusSuccessFinishResult);
785// return result.Succeeded();
786// }
787// }
788// }
789// if (frame_idx == UINT32_MAX)
790// result.AppendErrorWithFormat ("Invalid frame index: %s.\n", frame_idx_cstr);
791// else
792// result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
793// }
794// else
795// {
796// result.AppendError ("invalid arguments");
797// result.AppendErrorWithFormat ("Usage: %s\n", m_cmd_syntax.c_str());
798// }
799// }
800// else
801// {
802// result.AppendError ("no current thread");
803// }
804// result.SetStatus (eReturnStatusFailed);
805// return false;
806// }
807//};
808
809
Jim Inghamd60d94a2011-03-11 03:53:59 +0000810#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner24943d22010-06-08 16:52:24 +0000811
812//-------------------------------------------------------------------------
813// CommandObjectMultiwordImageSearchPaths
814//-------------------------------------------------------------------------
815
816class CommandObjectMultiwordImageSearchPaths : public CommandObjectMultiword
817{
818public:
819
Greg Clayton63094e02010-06-23 01:19:29 +0000820 CommandObjectMultiwordImageSearchPaths (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000821 CommandObjectMultiword (interpreter,
822 "target image-search-paths",
Chris Lattner24943d22010-06-08 16:52:24 +0000823 "A set of commands for operating on debugger target image search paths.",
824 "target image-search-paths <subcommand> [<subcommand-options>]")
825 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000826 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetImageSearchPathsAdd (interpreter)));
827 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetImageSearchPathsClear (interpreter)));
828 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetImageSearchPathsInsert (interpreter)));
829 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetImageSearchPathsList (interpreter)));
830 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetImageSearchPathsQuery (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +0000831 }
832
833 ~CommandObjectMultiwordImageSearchPaths()
834 {
835 }
836};
837
Jim Inghamd60d94a2011-03-11 03:53:59 +0000838#pragma mark CommandObjectTargetStopHookAdd
839
840//-------------------------------------------------------------------------
841// CommandObjectTargetStopHookAdd
842//-------------------------------------------------------------------------
843
844class CommandObjectTargetStopHookAdd : public CommandObject
845{
846public:
847
848 class CommandOptions : public Options
849 {
850 public:
Greg Claytonf15996e2011-04-07 22:46:35 +0000851 CommandOptions (CommandInterpreter &interpreter) :
852 Options(interpreter),
Jim Inghamd60d94a2011-03-11 03:53:59 +0000853 m_line_start(0),
854 m_line_end (UINT_MAX),
855 m_func_name_type_mask (eFunctionNameTypeAuto),
856 m_sym_ctx_specified (false),
Johnny Chen60fe60e2011-05-02 23:47:55 +0000857 m_thread_specified (false),
858 m_use_one_liner (false),
859 m_one_liner()
Jim Inghamd60d94a2011-03-11 03:53:59 +0000860 {
861 }
862
863 ~CommandOptions () {}
864
Greg Claytonb3448432011-03-24 21:19:54 +0000865 const OptionDefinition*
Jim Inghamd60d94a2011-03-11 03:53:59 +0000866 GetDefinitions ()
867 {
868 return g_option_table;
869 }
870
871 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000872 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghamd60d94a2011-03-11 03:53:59 +0000873 {
874 Error error;
875 char short_option = (char) m_getopt_table[option_idx].val;
876 bool success;
877
878 switch (short_option)
879 {
880 case 'c':
881 m_class_name = option_arg;
882 m_sym_ctx_specified = true;
883 break;
884
885 case 'e':
886 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
887 if (!success)
888 {
889 error.SetErrorStringWithFormat ("Invalid end line number: \"%s\".", option_arg);
890 break;
891 }
892 m_sym_ctx_specified = true;
893 break;
894
895 case 'l':
896 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
897 if (!success)
898 {
899 error.SetErrorStringWithFormat ("Invalid start line number: \"%s\".", option_arg);
900 break;
901 }
902 m_sym_ctx_specified = true;
903 break;
904
905 case 'n':
906 m_function_name = option_arg;
907 m_func_name_type_mask |= eFunctionNameTypeAuto;
908 m_sym_ctx_specified = true;
909 break;
910
911 case 'f':
912 m_file_name = option_arg;
913 m_sym_ctx_specified = true;
914 break;
915 case 's':
916 m_module_name = option_arg;
917 m_sym_ctx_specified = true;
918 break;
919 case 't' :
920 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000921 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000922 if (m_thread_id == LLDB_INVALID_THREAD_ID)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000923 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000924 m_thread_specified = true;
925 }
926 break;
927 case 'T':
928 m_thread_name = option_arg;
929 m_thread_specified = true;
930 break;
931 case 'q':
932 m_queue_name = option_arg;
933 m_thread_specified = true;
934 break;
935 case 'x':
936 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000937 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000938 if (m_thread_id == UINT32_MAX)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000939 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000940 m_thread_specified = true;
941 }
942 break;
Johnny Chen60fe60e2011-05-02 23:47:55 +0000943 case 'o':
944 m_use_one_liner = true;
945 m_one_liner = option_arg;
946 break;
Jim Inghamd60d94a2011-03-11 03:53:59 +0000947 default:
948 error.SetErrorStringWithFormat ("Unrecognized option %c.");
949 break;
950 }
951 return error;
952 }
953
954 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000955 OptionParsingStarting ()
Jim Inghamd60d94a2011-03-11 03:53:59 +0000956 {
957 m_class_name.clear();
958 m_function_name.clear();
959 m_line_start = 0;
960 m_line_end = UINT_MAX;
961 m_file_name.clear();
962 m_module_name.clear();
963 m_func_name_type_mask = eFunctionNameTypeAuto;
964 m_thread_id = LLDB_INVALID_THREAD_ID;
965 m_thread_index = UINT32_MAX;
966 m_thread_name.clear();
967 m_queue_name.clear();
968
969 m_sym_ctx_specified = false;
970 m_thread_specified = false;
Johnny Chen60fe60e2011-05-02 23:47:55 +0000971
972 m_use_one_liner = false;
973 m_one_liner.clear();
Jim Inghamd60d94a2011-03-11 03:53:59 +0000974 }
975
976
Greg Claytonb3448432011-03-24 21:19:54 +0000977 static OptionDefinition g_option_table[];
Jim Inghamd60d94a2011-03-11 03:53:59 +0000978
979 std::string m_class_name;
980 std::string m_function_name;
981 uint32_t m_line_start;
982 uint32_t m_line_end;
983 std::string m_file_name;
984 std::string m_module_name;
985 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
986 lldb::tid_t m_thread_id;
987 uint32_t m_thread_index;
988 std::string m_thread_name;
989 std::string m_queue_name;
990 bool m_sym_ctx_specified;
991 bool m_thread_specified;
Johnny Chen60fe60e2011-05-02 23:47:55 +0000992 // Instance variables to hold the values for one_liner options.
993 bool m_use_one_liner;
994 std::string m_one_liner;
Jim Inghamd60d94a2011-03-11 03:53:59 +0000995 };
996
997 Options *
998 GetOptions ()
999 {
1000 return &m_options;
1001 }
1002
1003 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
1004 CommandObject (interpreter,
1005 "target stop-hook add ",
1006 "Add a hook to be executed when the target stops.",
Greg Claytonf15996e2011-04-07 22:46:35 +00001007 "target stop-hook add"),
1008 m_options (interpreter)
Jim Inghamd60d94a2011-03-11 03:53:59 +00001009 {
1010 }
1011
1012 ~CommandObjectTargetStopHookAdd ()
1013 {
1014 }
1015
1016 static size_t
1017 ReadCommandsCallbackFunction (void *baton,
1018 InputReader &reader,
1019 lldb::InputReaderAction notification,
1020 const char *bytes,
1021 size_t bytes_len)
1022 {
1023 File &out_file = reader.GetDebugger().GetOutputFile();
1024 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
1025
1026 switch (notification)
1027 {
1028 case eInputReaderActivate:
1029 out_file.Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end.");
1030 if (reader.GetPrompt())
1031 out_file.Printf ("%s", reader.GetPrompt());
1032 out_file.Flush();
1033 break;
1034
1035 case eInputReaderDeactivate:
1036 break;
1037
1038 case eInputReaderReactivate:
1039 if (reader.GetPrompt())
1040 {
1041 out_file.Printf ("%s", reader.GetPrompt());
1042 out_file.Flush();
1043 }
1044 break;
1045
Caroline Tice4a348082011-05-02 20:41:46 +00001046 case eInputReaderAsynchronousOutputWritten:
1047 break;
1048
Jim Inghamd60d94a2011-03-11 03:53:59 +00001049 case eInputReaderGotToken:
1050 if (bytes && bytes_len && baton)
1051 {
1052 StringList *commands = new_stop_hook->GetCommandPointer();
1053 if (commands)
1054 {
1055 commands->AppendString (bytes, bytes_len);
1056 }
1057 }
1058 if (!reader.IsDone() && reader.GetPrompt())
1059 {
1060 out_file.Printf ("%s", reader.GetPrompt());
1061 out_file.Flush();
1062 }
1063 break;
1064
1065 case eInputReaderInterrupt:
1066 {
1067 // Finish, and cancel the stop hook.
1068 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
1069 out_file.Printf ("Stop hook cancelled.\n");
1070
1071 reader.SetIsDone (true);
1072 }
1073 break;
1074
1075 case eInputReaderEndOfFile:
1076 reader.SetIsDone (true);
1077 break;
1078
1079 case eInputReaderDone:
1080 out_file.Printf ("Stop hook #%d added.\n", new_stop_hook->GetID());
1081 break;
1082 }
1083
1084 return bytes_len;
1085 }
1086
1087 bool
1088 Execute (Args& command,
1089 CommandReturnObject &result)
1090 {
1091 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1092 if (target)
1093 {
1094 Target::StopHookSP new_hook_sp;
1095 target->AddStopHook (new_hook_sp);
1096
1097 // First step, make the specifier.
1098 std::auto_ptr<SymbolContextSpecifier> specifier_ap;
1099 if (m_options.m_sym_ctx_specified)
1100 {
1101 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
1102
1103 if (!m_options.m_module_name.empty())
1104 {
1105 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
1106 }
1107
1108 if (!m_options.m_class_name.empty())
1109 {
1110 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
1111 }
1112
1113 if (!m_options.m_file_name.empty())
1114 {
1115 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
1116 }
1117
1118 if (m_options.m_line_start != 0)
1119 {
1120 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
1121 }
1122
1123 if (m_options.m_line_end != UINT_MAX)
1124 {
1125 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
1126 }
1127
1128 if (!m_options.m_function_name.empty())
1129 {
1130 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
1131 }
1132 }
1133
1134 if (specifier_ap.get())
1135 new_hook_sp->SetSpecifier (specifier_ap.release());
1136
1137 // Next see if any of the thread options have been entered:
1138
1139 if (m_options.m_thread_specified)
1140 {
1141 ThreadSpec *thread_spec = new ThreadSpec();
1142
1143 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
1144 {
1145 thread_spec->SetTID (m_options.m_thread_id);
1146 }
1147
1148 if (m_options.m_thread_index != UINT32_MAX)
1149 thread_spec->SetIndex (m_options.m_thread_index);
1150
1151 if (!m_options.m_thread_name.empty())
1152 thread_spec->SetName (m_options.m_thread_name.c_str());
1153
1154 if (!m_options.m_queue_name.empty())
1155 thread_spec->SetQueueName (m_options.m_queue_name.c_str());
1156
1157 new_hook_sp->SetThreadSpecifier (thread_spec);
1158
1159 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00001160 if (m_options.m_use_one_liner)
Jim Inghamd60d94a2011-03-11 03:53:59 +00001161 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00001162 // Use one-liner.
1163 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
Johnny Chen44953902011-05-03 00:06:12 +00001164 result.AppendMessageWithFormat("Stop hook #%d added.\n", new_hook_sp->GetID());
Jim Inghamd60d94a2011-03-11 03:53:59 +00001165 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00001166 else
Jim Inghamd60d94a2011-03-11 03:53:59 +00001167 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00001168 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into
1169 // the new stop hook's command string.
1170 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
1171 if (!reader_sp)
1172 {
1173 result.AppendError("out of memory\n");
1174 result.SetStatus (eReturnStatusFailed);
1175 target->RemoveStopHookByID (new_hook_sp->GetID());
1176 return false;
1177 }
1178
1179 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
1180 new_hook_sp.get(), // baton
1181 eInputReaderGranularityLine, // token size, to pass to callback function
1182 "DONE", // end token
1183 "> ", // prompt
1184 true)); // echo input
1185 if (!err.Success())
1186 {
1187 result.AppendError (err.AsCString());
1188 result.SetStatus (eReturnStatusFailed);
1189 target->RemoveStopHookByID (new_hook_sp->GetID());
1190 return false;
1191 }
1192 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Jim Inghamd60d94a2011-03-11 03:53:59 +00001193 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00001194 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1195 }
1196 else
1197 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001198 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001199 result.SetStatus (eReturnStatusFailed);
1200 }
1201
1202 return result.Succeeded();
1203 }
1204private:
1205 CommandOptions m_options;
1206};
1207
Greg Claytonb3448432011-03-24 21:19:54 +00001208OptionDefinition
Jim Inghamd60d94a2011-03-11 03:53:59 +00001209CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
1210{
Johnny Chen60fe60e2011-05-02 23:47:55 +00001211 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner,
1212 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
Jim Inghamd60d94a2011-03-11 03:53:59 +00001213 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
1214 "Set the module within which the stop-hook is to be run."},
1215 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex,
1216 "The stop hook is run only for the thread whose index matches this argument."},
1217 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID,
1218 "The stop hook is run only for the thread whose TID matches this argument."},
1219 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName,
1220 "The stop hook is run only for the thread whose thread name matches this argument."},
1221 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
1222 "The stop hook is run only for threads in the queue whose name is given by this argument."},
1223 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1224 "Specify the source file within which the stop-hook is to be run." },
1225 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
1226 "Set the start of the line range for which the stop-hook is to be run."},
1227 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
1228 "Set the end of the line range for which the stop-hook is to be run."},
1229 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName,
1230 "Specify the class within which the stop-hook is to be run." },
1231 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
1232 "Set the function name within which the stop hook will be run." },
1233 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1234};
1235
1236#pragma mark CommandObjectTargetStopHookDelete
1237
1238//-------------------------------------------------------------------------
1239// CommandObjectTargetStopHookDelete
1240//-------------------------------------------------------------------------
1241
1242class CommandObjectTargetStopHookDelete : public CommandObject
1243{
1244public:
1245
1246 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
1247 CommandObject (interpreter,
1248 "target stop-hook delete [<id>]",
1249 "Delete a stop-hook.",
1250 "target stop-hook delete")
1251 {
1252 }
1253
1254 ~CommandObjectTargetStopHookDelete ()
1255 {
1256 }
1257
1258 bool
1259 Execute (Args& command,
1260 CommandReturnObject &result)
1261 {
1262 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1263 if (target)
1264 {
1265 // FIXME: see if we can use the breakpoint id style parser?
1266 size_t num_args = command.GetArgumentCount();
1267 if (num_args == 0)
1268 {
1269 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
1270 {
1271 result.SetStatus (eReturnStatusFailed);
1272 return false;
1273 }
1274 else
1275 {
1276 target->RemoveAllStopHooks();
1277 }
1278 }
1279 else
1280 {
1281 bool success;
1282 for (size_t i = 0; i < num_args; i++)
1283 {
1284 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
1285 if (!success)
1286 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001287 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001288 result.SetStatus(eReturnStatusFailed);
1289 return false;
1290 }
1291 success = target->RemoveStopHookByID (user_id);
1292 if (!success)
1293 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001294 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001295 result.SetStatus(eReturnStatusFailed);
1296 return false;
1297 }
1298 }
1299 }
1300 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1301 }
1302 else
1303 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001304 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001305 result.SetStatus (eReturnStatusFailed);
1306 }
1307
1308 return result.Succeeded();
1309 }
1310};
1311#pragma mark CommandObjectTargetStopHookEnableDisable
1312
1313//-------------------------------------------------------------------------
1314// CommandObjectTargetStopHookEnableDisable
1315//-------------------------------------------------------------------------
1316
1317class CommandObjectTargetStopHookEnableDisable : public CommandObject
1318{
1319public:
1320
1321 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
1322 CommandObject (interpreter,
1323 name,
1324 help,
1325 syntax),
1326 m_enable (enable)
1327 {
1328 }
1329
1330 ~CommandObjectTargetStopHookEnableDisable ()
1331 {
1332 }
1333
1334 bool
1335 Execute (Args& command,
1336 CommandReturnObject &result)
1337 {
1338 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1339 if (target)
1340 {
1341 // FIXME: see if we can use the breakpoint id style parser?
1342 size_t num_args = command.GetArgumentCount();
1343 bool success;
1344
1345 if (num_args == 0)
1346 {
1347 target->SetAllStopHooksActiveState (m_enable);
1348 }
1349 else
1350 {
1351 for (size_t i = 0; i < num_args; i++)
1352 {
1353 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
1354 if (!success)
1355 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001356 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001357 result.SetStatus(eReturnStatusFailed);
1358 return false;
1359 }
1360 success = target->SetStopHookActiveStateByID (user_id, m_enable);
1361 if (!success)
1362 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001363 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001364 result.SetStatus(eReturnStatusFailed);
1365 return false;
1366 }
1367 }
1368 }
1369 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1370 }
1371 else
1372 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001373 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001374 result.SetStatus (eReturnStatusFailed);
1375 }
1376 return result.Succeeded();
1377 }
1378private:
1379 bool m_enable;
1380};
1381
1382#pragma mark CommandObjectTargetStopHookList
1383
1384//-------------------------------------------------------------------------
1385// CommandObjectTargetStopHookList
1386//-------------------------------------------------------------------------
1387
1388class CommandObjectTargetStopHookList : public CommandObject
1389{
1390public:
1391
1392 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
1393 CommandObject (interpreter,
1394 "target stop-hook list [<type>]",
1395 "List all stop-hooks.",
1396 "target stop-hook list")
1397 {
1398 }
1399
1400 ~CommandObjectTargetStopHookList ()
1401 {
1402 }
1403
1404 bool
1405 Execute (Args& command,
1406 CommandReturnObject &result)
1407 {
1408 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1409 if (target)
1410 {
1411 bool notify = true;
1412 target->GetImageSearchPathList().Clear(notify);
1413 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1414 }
1415 else
1416 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001417 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001418 result.SetStatus (eReturnStatusFailed);
1419 }
1420
1421 size_t num_hooks = target->GetNumStopHooks ();
1422 if (num_hooks == 0)
1423 {
1424 result.GetOutputStream().PutCString ("No stop hooks.\n");
1425 }
1426 else
1427 {
1428 for (size_t i = 0; i < num_hooks; i++)
1429 {
1430 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
1431 if (i > 0)
1432 result.GetOutputStream().PutCString ("\n");
1433 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
1434 }
1435 }
1436 return result.Succeeded();
1437 }
1438};
1439
1440#pragma mark CommandObjectMultiwordTargetStopHooks
1441//-------------------------------------------------------------------------
1442// CommandObjectMultiwordTargetStopHooks
1443//-------------------------------------------------------------------------
1444
1445class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
1446{
1447public:
1448
1449 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
1450 CommandObjectMultiword (interpreter,
1451 "target stop-hook",
1452 "A set of commands for operating on debugger target stop-hooks.",
1453 "target stop-hook <subcommand> [<subcommand-options>]")
1454 {
1455 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
1456 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
1457 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
1458 false,
1459 "target stop-hook disable [<id>]",
1460 "Disable a stop-hook.",
1461 "target stop-hook disable")));
1462 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
1463 true,
1464 "target stop-hook enable [<id>]",
1465 "Enable a stop-hook.",
1466 "target stop-hook enable")));
1467 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
1468 }
1469
1470 ~CommandObjectMultiwordTargetStopHooks()
1471 {
1472 }
1473};
1474
1475
Chris Lattner24943d22010-06-08 16:52:24 +00001476
1477#pragma mark CommandObjectMultiwordTarget
1478
1479//-------------------------------------------------------------------------
1480// CommandObjectMultiwordTarget
1481//-------------------------------------------------------------------------
1482
Greg Clayton63094e02010-06-23 01:19:29 +00001483CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001484 CommandObjectMultiword (interpreter,
1485 "target",
Chris Lattner24943d22010-06-08 16:52:24 +00001486 "A set of commands for operating on debugger targets.",
1487 "target <subcommand> [<subcommand-options>]")
1488{
Greg Claytonabe0fed2011-04-18 08:33:37 +00001489
1490 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
1491 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter)));
1492 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001493 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
Greg Claytonabe0fed2011-04-18 08:33:37 +00001494 LoadSubCommand ("image-search-paths", CommandObjectSP (new CommandObjectMultiwordImageSearchPaths (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001495}
1496
1497CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
1498{
1499}
1500
Greg Claytonabe0fed2011-04-18 08:33:37 +00001501