blob: d18d34e1494f7781559c038e44a3a7da8d5a1815 [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"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Core/Timer.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Interpreter/CommandInterpreter.h"
23#include "lldb/Interpreter/CommandReturnObject.h"
24#include "lldb/Target/Process.h"
25#include "lldb/Target/StackFrame.h"
26#include "lldb/Target/Thread.h"
Jim Inghamd60d94a2011-03-11 03:53:59 +000027#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028
29using namespace lldb;
30using namespace lldb_private;
31
32#pragma mark CommandObjectTargetImageSearchPaths
33
34class CommandObjectTargetImageSearchPathsAdd : public CommandObject
35{
36public:
37
Greg Clayton238c0a12010-09-18 01:14:36 +000038 CommandObjectTargetImageSearchPathsAdd (CommandInterpreter &interpreter) :
39 CommandObject (interpreter,
40 "target image-search-paths add",
Chris Lattner24943d22010-06-08 16:52:24 +000041 "Add new image search paths substitution pairs to the current target.",
Caroline Tice43b014a2010-10-04 22:28:36 +000042 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +000043 {
Caroline Tice43b014a2010-10-04 22:28:36 +000044 CommandArgumentEntry arg;
45 CommandArgumentData old_prefix_arg;
46 CommandArgumentData new_prefix_arg;
47
48 // Define the first variant of this arg pair.
49 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
50 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
51
52 // Define the first variant of this arg pair.
53 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
54 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
55
56 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
57 // must always occur together, they are treated as two variants of one argument rather than two independent
58 // arguments. Push them both into the first argument position for m_arguments...
59
60 arg.push_back (old_prefix_arg);
61 arg.push_back (new_prefix_arg);
62
63 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +000064 }
65
66 ~CommandObjectTargetImageSearchPathsAdd ()
67 {
68 }
69
70 bool
Greg Clayton238c0a12010-09-18 01:14:36 +000071 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +000072 CommandReturnObject &result)
73 {
Greg Clayton238c0a12010-09-18 01:14:36 +000074 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +000075 if (target)
76 {
77 uint32_t argc = command.GetArgumentCount();
78 if (argc & 1)
79 {
80 result.AppendError ("add requires an even number of arguments");
81 result.SetStatus (eReturnStatusFailed);
82 }
83 else
84 {
85 for (uint32_t i=0; i<argc; i+=2)
86 {
87 const char *from = command.GetArgumentAtIndex(i);
88 const char *to = command.GetArgumentAtIndex(i+1);
89
90 if (from[0] && to[0])
91 {
92 bool last_pair = ((argc - i) == 2);
Greg Clayton63094e02010-06-23 01:19:29 +000093 target->GetImageSearchPathList().Append (ConstString(from),
94 ConstString(to),
95 last_pair); // Notify if this is the last pair
Johnny Chen4d661352011-02-03 00:30:19 +000096 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +000097 }
98 else
99 {
100 if (from[0])
101 result.AppendError ("<path-prefix> can't be empty");
102 else
103 result.AppendError ("<new-path-prefix> can't be empty");
104 result.SetStatus (eReturnStatusFailed);
105 }
106 }
107 }
108 }
109 else
110 {
111 result.AppendError ("invalid target");
112 result.SetStatus (eReturnStatusFailed);
113 }
114 return result.Succeeded();
115 }
116};
117
118class CommandObjectTargetImageSearchPathsClear : public CommandObject
119{
120public:
121
Greg Clayton238c0a12010-09-18 01:14:36 +0000122 CommandObjectTargetImageSearchPathsClear (CommandInterpreter &interpreter) :
123 CommandObject (interpreter,
124 "target image-search-paths clear",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000125 "Clear all current image search path substitution pairs from the current target.",
Chris Lattner24943d22010-06-08 16:52:24 +0000126 "target image-search-paths clear")
127 {
128 }
129
130 ~CommandObjectTargetImageSearchPathsClear ()
131 {
132 }
133
134 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000135 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000136 CommandReturnObject &result)
137 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000138 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000139 if (target)
140 {
141 bool notify = true;
142 target->GetImageSearchPathList().Clear(notify);
Johnny Chen4d661352011-02-03 00:30:19 +0000143 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000144 }
145 else
146 {
147 result.AppendError ("invalid target");
148 result.SetStatus (eReturnStatusFailed);
149 }
150 return result.Succeeded();
151 }
152};
153
154class CommandObjectTargetImageSearchPathsInsert : public CommandObject
155{
156public:
157
Greg Clayton238c0a12010-09-18 01:14:36 +0000158 CommandObjectTargetImageSearchPathsInsert (CommandInterpreter &interpreter) :
159 CommandObject (interpreter,
160 "target image-search-paths insert",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000161 "Insert a new image search path substitution pair into the current target at the specified index.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000162 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000163 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000164 CommandArgumentEntry arg1;
165 CommandArgumentEntry arg2;
166 CommandArgumentData index_arg;
167 CommandArgumentData old_prefix_arg;
168 CommandArgumentData new_prefix_arg;
169
170 // Define the first and only variant of this arg.
171 index_arg.arg_type = eArgTypeIndex;
172 index_arg.arg_repetition = eArgRepeatPlain;
173
174 // Put the one and only variant into the first arg for m_arguments:
175 arg1.push_back (index_arg);
176
177 // Define the first variant of this arg pair.
178 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
179 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
180
181 // Define the first variant of this arg pair.
182 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
183 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
184
185 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
186 // must always occur together, they are treated as two variants of one argument rather than two independent
187 // arguments. Push them both into the same argument position for m_arguments...
188
189 arg2.push_back (old_prefix_arg);
190 arg2.push_back (new_prefix_arg);
191
192 // Add arguments to m_arguments.
193 m_arguments.push_back (arg1);
194 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +0000195 }
196
197 ~CommandObjectTargetImageSearchPathsInsert ()
198 {
199 }
200
201 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000202 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000203 CommandReturnObject &result)
204 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000205 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000206 if (target)
207 {
208 uint32_t argc = command.GetArgumentCount();
209 // check for at least 3 arguments and an odd nubmer of parameters
210 if (argc >= 3 && argc & 1)
211 {
212 bool success = false;
213
214 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
215
216 if (!success)
217 {
218 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
219 result.SetStatus (eReturnStatusFailed);
220 return result.Succeeded();
221 }
222
223 // shift off the index
224 command.Shift();
225 argc = command.GetArgumentCount();
226
227 for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
228 {
229 const char *from = command.GetArgumentAtIndex(i);
230 const char *to = command.GetArgumentAtIndex(i+1);
231
232 if (from[0] && to[0])
233 {
234 bool last_pair = ((argc - i) == 2);
235 target->GetImageSearchPathList().Insert (ConstString(from),
236 ConstString(to),
237 insert_idx,
238 last_pair);
Johnny Chen4d661352011-02-03 00:30:19 +0000239 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000240 }
241 else
242 {
243 if (from[0])
244 result.AppendError ("<path-prefix> can't be empty");
245 else
246 result.AppendError ("<new-path-prefix> can't be empty");
247 result.SetStatus (eReturnStatusFailed);
248 return false;
249 }
250 }
251 }
252 else
253 {
254 result.AppendError ("insert requires at least three arguments");
255 result.SetStatus (eReturnStatusFailed);
256 return result.Succeeded();
257 }
258
259 }
260 else
261 {
262 result.AppendError ("invalid target");
263 result.SetStatus (eReturnStatusFailed);
264 }
265 return result.Succeeded();
266 }
267};
268
269class CommandObjectTargetImageSearchPathsList : public CommandObject
270{
271public:
272
Greg Clayton238c0a12010-09-18 01:14:36 +0000273 CommandObjectTargetImageSearchPathsList (CommandInterpreter &interpreter) :
274 CommandObject (interpreter,
275 "target image-search-paths list",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000276 "List all current image search path substitution pairs in the current target.",
Chris Lattner24943d22010-06-08 16:52:24 +0000277 "target image-search-paths list")
278 {
279 }
280
281 ~CommandObjectTargetImageSearchPathsList ()
282 {
283 }
284
285 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000286 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000287 CommandReturnObject &result)
288 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000289 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000290 if (target)
291 {
292 if (command.GetArgumentCount() != 0)
293 {
294 result.AppendError ("list takes no arguments");
295 result.SetStatus (eReturnStatusFailed);
296 return result.Succeeded();
297 }
298
299 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
Johnny Chen4d661352011-02-03 00:30:19 +0000300 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000301 }
302 else
303 {
304 result.AppendError ("invalid target");
305 result.SetStatus (eReturnStatusFailed);
306 }
307 return result.Succeeded();
308 }
309};
310
311class CommandObjectTargetImageSearchPathsQuery : public CommandObject
312{
313public:
314
Greg Clayton238c0a12010-09-18 01:14:36 +0000315 CommandObjectTargetImageSearchPathsQuery (CommandInterpreter &interpreter) :
316 CommandObject (interpreter,
317 "target image-search-paths query",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000318 "Transform a path using the first applicable image search path.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000319 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000320 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000321 CommandArgumentEntry arg;
322 CommandArgumentData path_arg;
323
324 // Define the first (and only) variant of this arg.
325 path_arg.arg_type = eArgTypePath;
326 path_arg.arg_repetition = eArgRepeatPlain;
327
328 // There is only one variant this argument could be; put it into the argument entry.
329 arg.push_back (path_arg);
330
331 // Push the data for the first argument into the m_arguments vector.
332 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000333 }
334
335 ~CommandObjectTargetImageSearchPathsQuery ()
336 {
337 }
338
339 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000340 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000341 CommandReturnObject &result)
342 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000343 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000344 if (target)
345 {
346 if (command.GetArgumentCount() != 1)
347 {
348 result.AppendError ("query requires one argument");
349 result.SetStatus (eReturnStatusFailed);
350 return result.Succeeded();
351 }
352
353 ConstString orig(command.GetArgumentAtIndex(0));
354 ConstString transformed;
355 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
356 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
357 else
358 result.GetOutputStream().Printf("%s\n", orig.GetCString());
Johnny Chen4d661352011-02-03 00:30:19 +0000359
360 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000361 }
362 else
363 {
364 result.AppendError ("invalid target");
365 result.SetStatus (eReturnStatusFailed);
366 }
367 return result.Succeeded();
368 }
369};
370
371// TODO: implement the target select later when we start doing multiple targets
372//#pragma mark CommandObjectTargetSelect
373//
374////-------------------------------------------------------------------------
375//// CommandObjectTargetSelect
376////-------------------------------------------------------------------------
377//
378//class CommandObjectTargetSelect : public CommandObject
379//{
380//public:
381//
382// CommandObjectTargetSelect () :
Greg Clayton238c0a12010-09-18 01:14:36 +0000383// CommandObject (interpreter,
384// frame select",
Chris Lattner24943d22010-06-08 16:52:24 +0000385// "Select the current frame by index in the current thread.",
386// "frame select <frame-index>")
387// {
388// }
389//
390// ~CommandObjectTargetSelect ()
391// {
392// }
393//
394// bool
395// Execute (Args& command,
Greg Clayton63094e02010-06-23 01:19:29 +0000396// Debugger *context,
Greg Clayton238c0a12010-09-18 01:14:36 +0000397// CommandInterpreter &m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000398// CommandReturnObject &result)
399// {
400// ExecutionContext exe_ctx (context->GetExecutionContext());
401// if (exe_ctx.thread)
402// {
403// if (command.GetArgumentCount() == 1)
404// {
405// const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
406//
407// const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount();
408// const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
409// if (frame_idx < num_frames)
410// {
Jim Inghamc8332952010-08-26 21:32:51 +0000411// exe_ctx.thread->SetSelectedFrameByIndex (frame_idx);
412// exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000413//
414// if (exe_ctx.frame)
415// {
416// if (DisplayFrameForExecutionContext (exe_ctx.thread,
417// exe_ctx.frame,
Greg Clayton238c0a12010-09-18 01:14:36 +0000418// m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000419// result.GetOutputStream(),
420// true,
421// true,
422// 3,
423// 3))
424// {
425// result.SetStatus (eReturnStatusSuccessFinishResult);
426// return result.Succeeded();
427// }
428// }
429// }
430// if (frame_idx == UINT32_MAX)
431// result.AppendErrorWithFormat ("Invalid frame index: %s.\n", frame_idx_cstr);
432// else
433// result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
434// }
435// else
436// {
437// result.AppendError ("invalid arguments");
438// result.AppendErrorWithFormat ("Usage: %s\n", m_cmd_syntax.c_str());
439// }
440// }
441// else
442// {
443// result.AppendError ("no current thread");
444// }
445// result.SetStatus (eReturnStatusFailed);
446// return false;
447// }
448//};
449
450
Jim Inghamd60d94a2011-03-11 03:53:59 +0000451#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner24943d22010-06-08 16:52:24 +0000452
453//-------------------------------------------------------------------------
454// CommandObjectMultiwordImageSearchPaths
455//-------------------------------------------------------------------------
456
457class CommandObjectMultiwordImageSearchPaths : public CommandObjectMultiword
458{
459public:
460
Greg Clayton63094e02010-06-23 01:19:29 +0000461 CommandObjectMultiwordImageSearchPaths (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000462 CommandObjectMultiword (interpreter,
463 "target image-search-paths",
Chris Lattner24943d22010-06-08 16:52:24 +0000464 "A set of commands for operating on debugger target image search paths.",
465 "target image-search-paths <subcommand> [<subcommand-options>]")
466 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000467 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetImageSearchPathsAdd (interpreter)));
468 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetImageSearchPathsClear (interpreter)));
469 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetImageSearchPathsInsert (interpreter)));
470 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetImageSearchPathsList (interpreter)));
471 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetImageSearchPathsQuery (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +0000472 }
473
474 ~CommandObjectMultiwordImageSearchPaths()
475 {
476 }
477};
478
Jim Inghamd60d94a2011-03-11 03:53:59 +0000479#pragma mark CommandObjectTargetStopHookAdd
480
481//-------------------------------------------------------------------------
482// CommandObjectTargetStopHookAdd
483//-------------------------------------------------------------------------
484
485class CommandObjectTargetStopHookAdd : public CommandObject
486{
487public:
488
489 class CommandOptions : public Options
490 {
491 public:
492 CommandOptions () :
493 Options(),
494 m_line_start(0),
495 m_line_end (UINT_MAX),
496 m_func_name_type_mask (eFunctionNameTypeAuto),
497 m_sym_ctx_specified (false),
498 m_thread_specified (false)
499 {
500 }
501
502 ~CommandOptions () {}
503
504 const lldb::OptionDefinition*
505 GetDefinitions ()
506 {
507 return g_option_table;
508 }
509
510 virtual Error
511 SetOptionValue (int option_idx, const char *option_arg)
512 {
513 Error error;
514 char short_option = (char) m_getopt_table[option_idx].val;
515 bool success;
516
517 switch (short_option)
518 {
519 case 'c':
520 m_class_name = option_arg;
521 m_sym_ctx_specified = true;
522 break;
523
524 case 'e':
525 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
526 if (!success)
527 {
528 error.SetErrorStringWithFormat ("Invalid end line number: \"%s\".", option_arg);
529 break;
530 }
531 m_sym_ctx_specified = true;
532 break;
533
534 case 'l':
535 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
536 if (!success)
537 {
538 error.SetErrorStringWithFormat ("Invalid start line number: \"%s\".", option_arg);
539 break;
540 }
541 m_sym_ctx_specified = true;
542 break;
543
544 case 'n':
545 m_function_name = option_arg;
546 m_func_name_type_mask |= eFunctionNameTypeAuto;
547 m_sym_ctx_specified = true;
548 break;
549
550 case 'f':
551 m_file_name = option_arg;
552 m_sym_ctx_specified = true;
553 break;
554 case 's':
555 m_module_name = option_arg;
556 m_sym_ctx_specified = true;
557 break;
558 case 't' :
559 {
560 m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
561 if (m_thread_id == LLDB_INVALID_THREAD_ID)
562 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
563 m_thread_specified = true;
564 }
565 break;
566 case 'T':
567 m_thread_name = option_arg;
568 m_thread_specified = true;
569 break;
570 case 'q':
571 m_queue_name = option_arg;
572 m_thread_specified = true;
573 break;
574 case 'x':
575 {
576 m_thread_index = Args::StringToUInt32(optarg, UINT32_MAX, 0);
577 if (m_thread_id == UINT32_MAX)
578 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
579 m_thread_specified = true;
580 }
581 break;
582 default:
583 error.SetErrorStringWithFormat ("Unrecognized option %c.");
584 break;
585 }
586 return error;
587 }
588
589 void
590 ResetOptionValues ()
591 {
592 m_class_name.clear();
593 m_function_name.clear();
594 m_line_start = 0;
595 m_line_end = UINT_MAX;
596 m_file_name.clear();
597 m_module_name.clear();
598 m_func_name_type_mask = eFunctionNameTypeAuto;
599 m_thread_id = LLDB_INVALID_THREAD_ID;
600 m_thread_index = UINT32_MAX;
601 m_thread_name.clear();
602 m_queue_name.clear();
603
604 m_sym_ctx_specified = false;
605 m_thread_specified = false;
606 }
607
608
609 static lldb::OptionDefinition g_option_table[];
610
611 std::string m_class_name;
612 std::string m_function_name;
613 uint32_t m_line_start;
614 uint32_t m_line_end;
615 std::string m_file_name;
616 std::string m_module_name;
617 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
618 lldb::tid_t m_thread_id;
619 uint32_t m_thread_index;
620 std::string m_thread_name;
621 std::string m_queue_name;
622 bool m_sym_ctx_specified;
623 bool m_thread_specified;
624
625 };
626
627 Options *
628 GetOptions ()
629 {
630 return &m_options;
631 }
632
633 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
634 CommandObject (interpreter,
635 "target stop-hook add ",
636 "Add a hook to be executed when the target stops.",
637 "target stop-hook add")
638 {
639 }
640
641 ~CommandObjectTargetStopHookAdd ()
642 {
643 }
644
645 static size_t
646 ReadCommandsCallbackFunction (void *baton,
647 InputReader &reader,
648 lldb::InputReaderAction notification,
649 const char *bytes,
650 size_t bytes_len)
651 {
652 File &out_file = reader.GetDebugger().GetOutputFile();
653 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
654
655 switch (notification)
656 {
657 case eInputReaderActivate:
658 out_file.Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end.");
659 if (reader.GetPrompt())
660 out_file.Printf ("%s", reader.GetPrompt());
661 out_file.Flush();
662 break;
663
664 case eInputReaderDeactivate:
665 break;
666
667 case eInputReaderReactivate:
668 if (reader.GetPrompt())
669 {
670 out_file.Printf ("%s", reader.GetPrompt());
671 out_file.Flush();
672 }
673 break;
674
675 case eInputReaderGotToken:
676 if (bytes && bytes_len && baton)
677 {
678 StringList *commands = new_stop_hook->GetCommandPointer();
679 if (commands)
680 {
681 commands->AppendString (bytes, bytes_len);
682 }
683 }
684 if (!reader.IsDone() && reader.GetPrompt())
685 {
686 out_file.Printf ("%s", reader.GetPrompt());
687 out_file.Flush();
688 }
689 break;
690
691 case eInputReaderInterrupt:
692 {
693 // Finish, and cancel the stop hook.
694 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
695 out_file.Printf ("Stop hook cancelled.\n");
696
697 reader.SetIsDone (true);
698 }
699 break;
700
701 case eInputReaderEndOfFile:
702 reader.SetIsDone (true);
703 break;
704
705 case eInputReaderDone:
706 out_file.Printf ("Stop hook #%d added.\n", new_stop_hook->GetID());
707 break;
708 }
709
710 return bytes_len;
711 }
712
713 bool
714 Execute (Args& command,
715 CommandReturnObject &result)
716 {
717 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
718 if (target)
719 {
720 Target::StopHookSP new_hook_sp;
721 target->AddStopHook (new_hook_sp);
722
723 // First step, make the specifier.
724 std::auto_ptr<SymbolContextSpecifier> specifier_ap;
725 if (m_options.m_sym_ctx_specified)
726 {
727 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
728
729 if (!m_options.m_module_name.empty())
730 {
731 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
732 }
733
734 if (!m_options.m_class_name.empty())
735 {
736 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
737 }
738
739 if (!m_options.m_file_name.empty())
740 {
741 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
742 }
743
744 if (m_options.m_line_start != 0)
745 {
746 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
747 }
748
749 if (m_options.m_line_end != UINT_MAX)
750 {
751 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
752 }
753
754 if (!m_options.m_function_name.empty())
755 {
756 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
757 }
758 }
759
760 if (specifier_ap.get())
761 new_hook_sp->SetSpecifier (specifier_ap.release());
762
763 // Next see if any of the thread options have been entered:
764
765 if (m_options.m_thread_specified)
766 {
767 ThreadSpec *thread_spec = new ThreadSpec();
768
769 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
770 {
771 thread_spec->SetTID (m_options.m_thread_id);
772 }
773
774 if (m_options.m_thread_index != UINT32_MAX)
775 thread_spec->SetIndex (m_options.m_thread_index);
776
777 if (!m_options.m_thread_name.empty())
778 thread_spec->SetName (m_options.m_thread_name.c_str());
779
780 if (!m_options.m_queue_name.empty())
781 thread_spec->SetQueueName (m_options.m_queue_name.c_str());
782
783 new_hook_sp->SetThreadSpecifier (thread_spec);
784
785 }
786 // Next gather up the command list, we'll push an input reader and suck the data from that directly into
787 // the new stop hook's command string.
788
789 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
790 if (!reader_sp)
791 {
792 result.AppendError("out of memory");
793 result.SetStatus (eReturnStatusFailed);
794 target->RemoveStopHookByID (new_hook_sp->GetID());
795 return false;
796 }
797
798 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
799 new_hook_sp.get(), // baton
800 eInputReaderGranularityLine, // token size, to pass to callback function
801 "DONE", // end token
802 "> ", // prompt
803 true)); // echo input
804 if (!err.Success())
805 {
806 result.AppendError (err.AsCString());
807 result.SetStatus (eReturnStatusFailed);
808 target->RemoveStopHookByID (new_hook_sp->GetID());
809 return false;
810 }
811 m_interpreter.GetDebugger().PushInputReader (reader_sp);
812
813 result.SetStatus (eReturnStatusSuccessFinishNoResult);
814 }
815 else
816 {
817 result.AppendError ("invalid target");
818 result.SetStatus (eReturnStatusFailed);
819 }
820
821 return result.Succeeded();
822 }
823private:
824 CommandOptions m_options;
825};
826
827lldb::OptionDefinition
828CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
829{
830 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
831 "Set the module within which the stop-hook is to be run."},
832 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex,
833 "The stop hook is run only for the thread whose index matches this argument."},
834 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID,
835 "The stop hook is run only for the thread whose TID matches this argument."},
836 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName,
837 "The stop hook is run only for the thread whose thread name matches this argument."},
838 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
839 "The stop hook is run only for threads in the queue whose name is given by this argument."},
840 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
841 "Specify the source file within which the stop-hook is to be run." },
842 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
843 "Set the start of the line range for which the stop-hook is to be run."},
844 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
845 "Set the end of the line range for which the stop-hook is to be run."},
846 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName,
847 "Specify the class within which the stop-hook is to be run." },
848 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
849 "Set the function name within which the stop hook will be run." },
850 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
851};
852
853#pragma mark CommandObjectTargetStopHookDelete
854
855//-------------------------------------------------------------------------
856// CommandObjectTargetStopHookDelete
857//-------------------------------------------------------------------------
858
859class CommandObjectTargetStopHookDelete : public CommandObject
860{
861public:
862
863 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
864 CommandObject (interpreter,
865 "target stop-hook delete [<id>]",
866 "Delete a stop-hook.",
867 "target stop-hook delete")
868 {
869 }
870
871 ~CommandObjectTargetStopHookDelete ()
872 {
873 }
874
875 bool
876 Execute (Args& command,
877 CommandReturnObject &result)
878 {
879 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
880 if (target)
881 {
882 // FIXME: see if we can use the breakpoint id style parser?
883 size_t num_args = command.GetArgumentCount();
884 if (num_args == 0)
885 {
886 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
887 {
888 result.SetStatus (eReturnStatusFailed);
889 return false;
890 }
891 else
892 {
893 target->RemoveAllStopHooks();
894 }
895 }
896 else
897 {
898 bool success;
899 for (size_t i = 0; i < num_args; i++)
900 {
901 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
902 if (!success)
903 {
904 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".", command.GetArgumentAtIndex(i));
905 result.SetStatus(eReturnStatusFailed);
906 return false;
907 }
908 success = target->RemoveStopHookByID (user_id);
909 if (!success)
910 {
911 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".", command.GetArgumentAtIndex(i));
912 result.SetStatus(eReturnStatusFailed);
913 return false;
914 }
915 }
916 }
917 result.SetStatus (eReturnStatusSuccessFinishNoResult);
918 }
919 else
920 {
921 result.AppendError ("invalid target");
922 result.SetStatus (eReturnStatusFailed);
923 }
924
925 return result.Succeeded();
926 }
927};
928#pragma mark CommandObjectTargetStopHookEnableDisable
929
930//-------------------------------------------------------------------------
931// CommandObjectTargetStopHookEnableDisable
932//-------------------------------------------------------------------------
933
934class CommandObjectTargetStopHookEnableDisable : public CommandObject
935{
936public:
937
938 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
939 CommandObject (interpreter,
940 name,
941 help,
942 syntax),
943 m_enable (enable)
944 {
945 }
946
947 ~CommandObjectTargetStopHookEnableDisable ()
948 {
949 }
950
951 bool
952 Execute (Args& command,
953 CommandReturnObject &result)
954 {
955 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
956 if (target)
957 {
958 // FIXME: see if we can use the breakpoint id style parser?
959 size_t num_args = command.GetArgumentCount();
960 bool success;
961
962 if (num_args == 0)
963 {
964 target->SetAllStopHooksActiveState (m_enable);
965 }
966 else
967 {
968 for (size_t i = 0; i < num_args; i++)
969 {
970 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
971 if (!success)
972 {
973 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".", command.GetArgumentAtIndex(i));
974 result.SetStatus(eReturnStatusFailed);
975 return false;
976 }
977 success = target->SetStopHookActiveStateByID (user_id, m_enable);
978 if (!success)
979 {
980 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".", command.GetArgumentAtIndex(i));
981 result.SetStatus(eReturnStatusFailed);
982 return false;
983 }
984 }
985 }
986 result.SetStatus (eReturnStatusSuccessFinishNoResult);
987 }
988 else
989 {
990 result.AppendError ("invalid target");
991 result.SetStatus (eReturnStatusFailed);
992 }
993 return result.Succeeded();
994 }
995private:
996 bool m_enable;
997};
998
999#pragma mark CommandObjectTargetStopHookList
1000
1001//-------------------------------------------------------------------------
1002// CommandObjectTargetStopHookList
1003//-------------------------------------------------------------------------
1004
1005class CommandObjectTargetStopHookList : public CommandObject
1006{
1007public:
1008
1009 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
1010 CommandObject (interpreter,
1011 "target stop-hook list [<type>]",
1012 "List all stop-hooks.",
1013 "target stop-hook list")
1014 {
1015 }
1016
1017 ~CommandObjectTargetStopHookList ()
1018 {
1019 }
1020
1021 bool
1022 Execute (Args& command,
1023 CommandReturnObject &result)
1024 {
1025 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1026 if (target)
1027 {
1028 bool notify = true;
1029 target->GetImageSearchPathList().Clear(notify);
1030 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1031 }
1032 else
1033 {
1034 result.AppendError ("invalid target");
1035 result.SetStatus (eReturnStatusFailed);
1036 }
1037
1038 size_t num_hooks = target->GetNumStopHooks ();
1039 if (num_hooks == 0)
1040 {
1041 result.GetOutputStream().PutCString ("No stop hooks.\n");
1042 }
1043 else
1044 {
1045 for (size_t i = 0; i < num_hooks; i++)
1046 {
1047 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
1048 if (i > 0)
1049 result.GetOutputStream().PutCString ("\n");
1050 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
1051 }
1052 }
1053 return result.Succeeded();
1054 }
1055};
1056
1057#pragma mark CommandObjectMultiwordTargetStopHooks
1058//-------------------------------------------------------------------------
1059// CommandObjectMultiwordTargetStopHooks
1060//-------------------------------------------------------------------------
1061
1062class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
1063{
1064public:
1065
1066 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
1067 CommandObjectMultiword (interpreter,
1068 "target stop-hook",
1069 "A set of commands for operating on debugger target stop-hooks.",
1070 "target stop-hook <subcommand> [<subcommand-options>]")
1071 {
1072 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
1073 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
1074 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
1075 false,
1076 "target stop-hook disable [<id>]",
1077 "Disable a stop-hook.",
1078 "target stop-hook disable")));
1079 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
1080 true,
1081 "target stop-hook enable [<id>]",
1082 "Enable a stop-hook.",
1083 "target stop-hook enable")));
1084 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
1085 }
1086
1087 ~CommandObjectMultiwordTargetStopHooks()
1088 {
1089 }
1090};
1091
1092
Chris Lattner24943d22010-06-08 16:52:24 +00001093
1094#pragma mark CommandObjectMultiwordTarget
1095
1096//-------------------------------------------------------------------------
1097// CommandObjectMultiwordTarget
1098//-------------------------------------------------------------------------
1099
Greg Clayton63094e02010-06-23 01:19:29 +00001100CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001101 CommandObjectMultiword (interpreter,
1102 "target",
Chris Lattner24943d22010-06-08 16:52:24 +00001103 "A set of commands for operating on debugger targets.",
1104 "target <subcommand> [<subcommand-options>]")
1105{
Greg Clayton238c0a12010-09-18 01:14:36 +00001106 LoadSubCommand ("image-search-paths", CommandObjectSP (new CommandObjectMultiwordImageSearchPaths (interpreter)));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001107 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001108}
1109
1110CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
1111{
1112}
1113