]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Commands/CommandObjectExpression.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / Commands / CommandObjectExpression.cpp
1 //===-- CommandObjectExpression.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 "lldb/lldb-python.h"
11
12 #include "CommandObjectExpression.h"
13
14 // C Includes
15 // C++ Includes
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/Interpreter/Args.h"
19 #include "lldb/Core/Value.h"
20 #include "lldb/Core/ValueObjectVariable.h"
21 #include "lldb/DataFormatters/ValueObjectPrinter.h"
22 #include "lldb/Expression/ClangExpressionVariable.h"
23 #include "lldb/Expression/ClangUserExpression.h"
24 #include "lldb/Expression/ClangFunction.h"
25 #include "lldb/Expression/DWARFExpression.h"
26 #include "lldb/Host/Host.h"
27 #include "lldb/Core/Debugger.h"
28 #include "lldb/Interpreter/CommandInterpreter.h"
29 #include "lldb/Interpreter/CommandReturnObject.h"
30 #include "lldb/Target/ObjCLanguageRuntime.h"
31 #include "lldb/Symbol/ObjectFile.h"
32 #include "lldb/Symbol/Variable.h"
33 #include "lldb/Target/Process.h"
34 #include "lldb/Target/StackFrame.h"
35 #include "lldb/Target/Target.h"
36 #include "lldb/Target/Thread.h"
37 #include "llvm/ADT/StringRef.h"
38
39 using namespace lldb;
40 using namespace lldb_private;
41
42 CommandObjectExpression::CommandOptions::CommandOptions () :
43     OptionGroup()
44 {
45 }
46
47
48 CommandObjectExpression::CommandOptions::~CommandOptions ()
49 {
50 }
51
52 static OptionEnumValueElement g_description_verbosity_type[] =
53 {
54     { eLanguageRuntimeDescriptionDisplayVerbosityCompact,      "compact",       "Only show the description string"},
55     { eLanguageRuntimeDescriptionDisplayVerbosityFull,         "full",          "Show the full output, including persistent variable's name and type"},
56     { 0, NULL, NULL }
57 };
58
59 OptionDefinition
60 CommandObjectExpression::CommandOptions::g_option_table[] =
61 {
62     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads",        'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean,    "Should we run all threads if the execution doesn't complete on one thread."},
63     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean,    "Ignore breakpoint hits while running expressions"},
64     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout",            't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger,  "Timeout value (in microseconds) for running the expression."},
65     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error",    'u', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean,    "Clean up program state if the expression causes a crash, or raises a signal.  Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."},
66     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug",              'g', OptionParser::eNoArgument      , NULL, 0, eArgTypeNone,       "When specified, debug the JIT code by setting a breakpoint on the first instruction and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."},
67     { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity,        "How verbose should the output of this expression be, if the object description is asked for."},
68 };
69
70
71 uint32_t
72 CommandObjectExpression::CommandOptions::GetNumDefinitions ()
73 {
74     return sizeof(g_option_table)/sizeof(OptionDefinition);
75 }
76
77 Error
78 CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
79                                                          uint32_t option_idx,
80                                                          const char *option_arg)
81 {
82     Error error;
83
84     const int short_option = g_option_table[option_idx].short_option;
85
86     switch (short_option)
87     {
88       //case 'l':
89       //if (language.SetLanguageFromCString (option_arg) == false)
90       //{
91       //    error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
92       //}
93       //break;
94
95     case 'a':
96         {
97             bool success;
98             bool result;
99             result = Args::StringToBoolean(option_arg, true, &success);
100             if (!success)
101                 error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
102             else
103                 try_all_threads = result;
104         }
105         break;
106         
107     case 'i':
108         {
109             bool success;
110             bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
111             if (success)
112                 ignore_breakpoints = tmp_value;
113             else
114                 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
115             break;
116         }
117     case 't':
118         {
119             bool success;
120             uint32_t result;
121             result = Args::StringToUInt32(option_arg, 0, 0, &success);
122             if (success)
123                 timeout = result;
124             else
125                 error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
126         }
127         break;
128         
129     case 'u':
130         {
131             bool success;
132             bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
133             if (success)
134                 unwind_on_error = tmp_value;
135             else
136                 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
137             break;
138         }
139             
140     case 'v':
141         if (!option_arg)
142         {
143             m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
144             break;
145         }
146         m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
147         if (!error.Success())
148             error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg);
149         break;
150     
151     case 'g':
152         debug = true;
153         unwind_on_error = false;
154         ignore_breakpoints = false;
155         break;
156
157     default:
158         error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
159         break;
160     }
161
162     return error;
163 }
164
165 void
166 CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
167 {
168     Process *process = interpreter.GetExecutionContext().GetProcessPtr();
169     if (process != NULL)
170     {
171         ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
172         unwind_on_error    = process->GetUnwindOnErrorInExpressions();
173     }
174     else
175     {
176         ignore_breakpoints = false;
177         unwind_on_error = true;
178     }
179     
180     show_summary = true;
181     try_all_threads = true;
182     timeout = 0;
183     debug = false;
184     m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
185 }
186
187 const OptionDefinition*
188 CommandObjectExpression::CommandOptions::GetDefinitions ()
189 {
190     return g_option_table;
191 }
192
193 CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
194     CommandObjectRaw (interpreter,
195                       "expression",
196                       "Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope.",
197                       NULL,
198                       eFlagProcessMustBePaused | eFlagTryTargetAPILock),
199     IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
200     m_option_group (interpreter),
201     m_format_options (eFormatDefault),
202     m_command_options (),
203     m_expr_line_count (0),
204     m_expr_lines ()
205 {
206   SetHelpLong(
207 "Timeouts:\n\
208     If the expression can be evaluated statically (without runnning code) then it will be.\n\
209     Otherwise, by default the expression will run on the current thread with a short timeout:\n\
210     currently .25 seconds.  If it doesn't return in that time, the evaluation will be interrupted\n\
211     and resumed with all threads running.  You can use the -a option to disable retrying on all\n\
212     threads.  You can use the -t option to set a shorter timeout.\n\
213 \n\
214 User defined variables:\n\
215     You can define your own variables for convenience or to be used in subsequent expressions.\n\
216     You define them the same way you would define variables in C.  If the first character of \n\
217     your user defined variable is a $, then the variable's value will be available in future\n\
218     expressions, otherwise it will just be available in the current expression.\n\
219 \n\
220 Examples: \n\
221 \n\
222    expr my_struct->a = my_array[3] \n\
223    expr -f bin -- (index * 8) + 5 \n\
224    expr unsigned int $foo = 5\n\
225    expr char c[] = \"foo\"; c[0]\n");
226
227     CommandArgumentEntry arg;
228     CommandArgumentData expression_arg;
229
230     // Define the first (and only) variant of this arg.
231     expression_arg.arg_type = eArgTypeExpression;
232     expression_arg.arg_repetition = eArgRepeatPlain;
233
234     // There is only one variant this argument could be; put it into the argument entry.
235     arg.push_back (expression_arg);
236
237     // Push the data for the first argument into the m_arguments vector.
238     m_arguments.push_back (arg);
239     
240     // Add the "--format" and "--gdb-format"
241     m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
242     m_option_group.Append (&m_command_options);
243     m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
244     m_option_group.Finalize();
245 }
246
247 CommandObjectExpression::~CommandObjectExpression ()
248 {
249 }
250
251 Options *
252 CommandObjectExpression::GetOptions ()
253 {
254     return &m_option_group;
255 }
256
257 bool
258 CommandObjectExpression::EvaluateExpression 
259 (
260     const char *expr, 
261     Stream *output_stream, 
262     Stream *error_stream,
263     CommandReturnObject *result
264 )
265 {
266     // Don't use m_exe_ctx as this might be called asynchronously
267     // after the command object DoExecute has finished when doing
268     // multi-line expression that use an input reader...
269     ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
270
271     Target *target = exe_ctx.GetTargetPtr();
272     
273     if (!target)
274         target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
275     
276     if (target)
277     {
278         lldb::ValueObjectSP result_valobj_sp;
279
280         ExecutionResults exe_results;
281         
282         bool keep_in_memory = true;
283
284         EvaluateExpressionOptions options;
285         options.SetCoerceToId(m_varobj_options.use_objc);
286         options.SetUnwindOnError(m_command_options.unwind_on_error);
287         options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints);
288         options.SetKeepInMemory(keep_in_memory);
289         options.SetUseDynamic(m_varobj_options.use_dynamic);
290         options.SetTryAllThreads(m_command_options.try_all_threads);
291         options.SetDebug(m_command_options.debug);
292         
293         if (m_command_options.timeout > 0)
294             options.SetTimeoutUsec(m_command_options.timeout);
295         else
296             options.SetTimeoutUsec(0);
297         
298         exe_results = target->EvaluateExpression (expr, 
299                                                   exe_ctx.GetFramePtr(),
300                                                   result_valobj_sp,
301                                                   options);
302
303         if (result_valobj_sp)
304         {
305             Format format = m_format_options.GetFormat();
306
307             if (result_valobj_sp->GetError().Success())
308             {
309                 if (format != eFormatVoid)
310                 {
311                     if (format != eFormatDefault)
312                         result_valobj_sp->SetFormat (format);
313
314                     DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
315
316                     result_valobj_sp->Dump(*output_stream,options);
317                     
318                     if (result)
319                         result->SetStatus (eReturnStatusSuccessFinishResult);
320                 }
321             }
322             else
323             {
324                 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
325                 {
326                     if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
327                     {
328                         error_stream->PutCString("(void)\n");
329                     }
330                     
331                     if (result)
332                         result->SetStatus (eReturnStatusSuccessFinishResult);
333                 }
334                 else
335                 {
336                     const char *error_cstr = result_valobj_sp->GetError().AsCString();
337                     if (error_cstr && error_cstr[0])
338                     {
339                         const size_t error_cstr_len = strlen (error_cstr);
340                         const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
341                         if (strstr(error_cstr, "error:") != error_cstr)
342                             error_stream->PutCString ("error: ");
343                         error_stream->Write(error_cstr, error_cstr_len);
344                         if (!ends_with_newline)
345                             error_stream->EOL();
346                     }
347                     else
348                     {
349                         error_stream->PutCString ("error: unknown error\n");
350                     }
351                     
352                     if (result)
353                         result->SetStatus (eReturnStatusFailed);
354                 }
355             }
356         }
357     }
358     else
359     {
360         error_stream->Printf ("error: invalid execution context for expression\n");
361         return false;
362     }
363         
364     return true;
365 }
366
367 void
368 CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
369 {
370     io_handler.SetIsDone(true);
371 //    StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream();
372 //    StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
373     StreamFileSP output_sp(io_handler.GetOutputStreamFile());
374     StreamFileSP error_sp(io_handler.GetErrorStreamFile());
375
376     EvaluateExpression (line.c_str(),
377                         output_sp.get(),
378                         error_sp.get());
379     if (output_sp)
380         output_sp->Flush();
381     if (error_sp)
382         error_sp->Flush();
383 }
384
385 LineStatus
386 CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler,
387                                                 StringList &lines,
388                                                 uint32_t line_idx,
389                                                 Error &error)
390 {
391     if (line_idx == UINT32_MAX)
392     {
393         // Remove the last line from "lines" so it doesn't appear
394         // in our final expression
395         lines.PopBack();
396         error.Clear();
397         return LineStatus::Done;
398     }
399     else if (line_idx + 1 == lines.GetSize())
400     {
401         // The last line was edited, if this line is empty, then we are done
402         // getting our multiple lines.
403         if (lines[line_idx].empty())
404             return LineStatus::Done;
405     }
406     return LineStatus::Success;
407 }
408
409 bool
410 CommandObjectExpression::DoExecute
411 (
412     const char *command,
413     CommandReturnObject &result
414 )
415 {
416     m_option_group.NotifyOptionParsingStarting();
417
418     const char * expr = NULL;
419
420     if (command[0] == '\0')
421     {
422         m_expr_lines.clear();
423         m_expr_line_count = 0;
424         
425         Debugger &debugger = GetCommandInterpreter().GetDebugger();
426         const bool multiple_lines = true; // Get multiple lines
427         IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
428                                                           "lldb-expr",      // Name of input reader for history
429                                                           NULL,             // No prompt
430                                                           multiple_lines,
431                                                           *this));
432         
433         StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
434         if (output_sp)
435         {
436             output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
437             output_sp->Flush();
438         }
439         debugger.PushIOHandler(io_handler_sp);
440         return result.Succeeded();
441     }
442
443     if (command[0] == '-')
444     {
445         // We have some options and these options MUST end with --.
446         const char *end_options = NULL;
447         const char *s = command;
448         while (s && s[0])
449         {
450             end_options = ::strstr (s, "--");
451             if (end_options)
452             {
453                 end_options += 2; // Get past the "--"
454                 if (::isspace (end_options[0]))
455                 {
456                     expr = end_options;
457                     while (::isspace (*expr))
458                         ++expr;
459                     break;
460                 }
461             }
462             s = end_options;
463         }
464
465         if (end_options)
466         {
467             Args args (command, end_options - command);
468             if (!ParseOptions (args, result))
469                 return false;
470             
471             Error error (m_option_group.NotifyOptionParsingFinished());
472             if (error.Fail())
473             {
474                 result.AppendError (error.AsCString());
475                 result.SetStatus (eReturnStatusFailed);
476                 return false;
477             }
478         }
479     }
480
481     if (expr == NULL)
482         expr = command;
483     
484     if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
485         return true;
486
487     result.SetStatus (eReturnStatusFailed);
488     return false;
489 }
490