1 //===-- CommandObjectExpression.cpp -----------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/lldb-python.h"
12 #include "CommandObjectExpression.h"
16 // Other libraries and framework includes
18 #include "lldb/Interpreter/Args.h"
19 #include "lldb/Core/Value.h"
20 #include "lldb/Core/InputReader.h"
21 #include "lldb/Core/ValueObjectVariable.h"
22 #include "lldb/DataFormatters/ValueObjectPrinter.h"
23 #include "lldb/Expression/ClangExpressionVariable.h"
24 #include "lldb/Expression/ClangUserExpression.h"
25 #include "lldb/Expression/ClangFunction.h"
26 #include "lldb/Expression/DWARFExpression.h"
27 #include "lldb/Host/Host.h"
28 #include "lldb/Core/Debugger.h"
29 #include "lldb/Interpreter/CommandInterpreter.h"
30 #include "lldb/Interpreter/CommandReturnObject.h"
31 #include "lldb/Target/ObjCLanguageRuntime.h"
32 #include "lldb/Symbol/ObjectFile.h"
33 #include "lldb/Symbol/Variable.h"
34 #include "lldb/Target/Process.h"
35 #include "lldb/Target/StackFrame.h"
36 #include "lldb/Target/Target.h"
37 #include "lldb/Target/Thread.h"
38 #include "llvm/ADT/StringRef.h"
41 using namespace lldb_private;
43 CommandObjectExpression::CommandOptions::CommandOptions () :
49 CommandObjectExpression::CommandOptions::~CommandOptions ()
53 static OptionEnumValueElement g_description_verbosity_type[] =
55 { eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact", "Only show the description string"},
56 { eLanguageRuntimeDescriptionDisplayVerbosityFull, "full", "Show the full output, including persistent variable's name and type"},
61 CommandObjectExpression::CommandOptions::g_option_table[] =
63 { 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."},
64 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
65 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."},
66 { 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)."},
67 { 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)."},
68 { 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."},
73 CommandObjectExpression::CommandOptions::GetNumDefinitions ()
75 return sizeof(g_option_table)/sizeof(OptionDefinition);
79 CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
81 const char *option_arg)
85 const int short_option = g_option_table[option_idx].short_option;
90 //if (language.SetLanguageFromCString (option_arg) == false)
92 // error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
100 result = Args::StringToBoolean(option_arg, true, &success);
102 error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
104 try_all_threads = result;
111 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
113 ignore_breakpoints = tmp_value;
115 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
122 result = Args::StringToUInt32(option_arg, 0, 0, &success);
126 error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
133 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
135 unwind_on_error = tmp_value;
137 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
144 m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
147 m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
148 if (!error.Success())
149 error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg);
154 unwind_on_error = false;
155 ignore_breakpoints = false;
159 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
167 CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
169 Process *process = interpreter.GetExecutionContext().GetProcessPtr();
172 ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
173 unwind_on_error = process->GetUnwindOnErrorInExpressions();
177 ignore_breakpoints = false;
178 unwind_on_error = true;
182 try_all_threads = true;
185 m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
188 const OptionDefinition*
189 CommandObjectExpression::CommandOptions::GetDefinitions ()
191 return g_option_table;
194 CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
195 CommandObjectRaw (interpreter,
197 "Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope.",
199 eFlagProcessMustBePaused | eFlagTryTargetAPILock),
200 m_option_group (interpreter),
201 m_format_options (eFormatDefault),
202 m_command_options (),
203 m_expr_line_count (0),
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\
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\
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");
227 CommandArgumentEntry arg;
228 CommandArgumentData expression_arg;
230 // Define the first (and only) variant of this arg.
231 expression_arg.arg_type = eArgTypeExpression;
232 expression_arg.arg_repetition = eArgRepeatPlain;
234 // There is only one variant this argument could be; put it into the argument entry.
235 arg.push_back (expression_arg);
237 // Push the data for the first argument into the m_arguments vector.
238 m_arguments.push_back (arg);
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();
247 CommandObjectExpression::~CommandObjectExpression ()
252 CommandObjectExpression::GetOptions ()
254 return &m_option_group;
258 CommandObjectExpression::MultiLineExpressionCallback
262 lldb::InputReaderAction notification,
267 CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton;
268 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
270 switch (notification)
272 case eInputReaderActivate:
275 StreamSP async_strm_sp(reader.GetDebugger().GetAsyncOutputStream());
278 async_strm_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
279 async_strm_sp->Flush();
283 case eInputReaderReactivate:
286 case eInputReaderDeactivate:
289 case eInputReaderAsynchronousOutputWritten:
292 case eInputReaderGotToken:
293 ++cmd_object_expr->m_expr_line_count;
294 if (bytes && bytes_len)
296 cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1);
300 reader.SetIsDone(true);
303 case eInputReaderInterrupt:
304 cmd_object_expr->m_expr_lines.clear();
305 reader.SetIsDone (true);
308 StreamSP async_strm_sp (reader.GetDebugger().GetAsyncOutputStream());
311 async_strm_sp->PutCString("Expression evaluation cancelled.\n");
312 async_strm_sp->Flush();
317 case eInputReaderEndOfFile:
318 reader.SetIsDone (true);
321 case eInputReaderDone:
322 if (cmd_object_expr->m_expr_lines.size() > 0)
324 StreamSP output_stream = reader.GetDebugger().GetAsyncOutputStream();
325 StreamSP error_stream = reader.GetDebugger().GetAsyncErrorStream();
326 cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(),
329 output_stream->Flush();
330 error_stream->Flush();
339 CommandObjectExpression::EvaluateExpression
342 Stream *output_stream,
343 Stream *error_stream,
344 CommandReturnObject *result
347 // Don't use m_exe_ctx as this might be called asynchronously
348 // after the command object DoExecute has finished when doing
349 // multi-line expression that use an input reader...
350 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
352 Target *target = exe_ctx.GetTargetPtr();
355 target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
359 lldb::ValueObjectSP result_valobj_sp;
361 ExecutionResults exe_results;
363 bool keep_in_memory = true;
365 EvaluateExpressionOptions options;
366 options.SetCoerceToId(m_varobj_options.use_objc);
367 options.SetUnwindOnError(m_command_options.unwind_on_error);
368 options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints);
369 options.SetKeepInMemory(keep_in_memory);
370 options.SetUseDynamic(m_varobj_options.use_dynamic);
371 options.SetTryAllThreads(m_command_options.try_all_threads);
372 options.SetDebug(m_command_options.debug);
374 if (m_command_options.timeout > 0)
375 options.SetTimeoutUsec(m_command_options.timeout);
377 exe_results = target->EvaluateExpression (expr,
378 exe_ctx.GetFramePtr(),
382 if (result_valobj_sp)
384 Format format = m_format_options.GetFormat();
386 if (result_valobj_sp->GetError().Success())
388 if (format != eFormatVoid)
390 if (format != eFormatDefault)
391 result_valobj_sp->SetFormat (format);
393 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
395 result_valobj_sp->Dump(*output_stream,options);
398 result->SetStatus (eReturnStatusSuccessFinishResult);
403 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
405 if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
407 error_stream->PutCString("(void)\n");
411 result->SetStatus (eReturnStatusSuccessFinishResult);
415 const char *error_cstr = result_valobj_sp->GetError().AsCString();
416 if (error_cstr && error_cstr[0])
418 const size_t error_cstr_len = strlen (error_cstr);
419 const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
420 if (strstr(error_cstr, "error:") != error_cstr)
421 error_stream->PutCString ("error: ");
422 error_stream->Write(error_cstr, error_cstr_len);
423 if (!ends_with_newline)
428 error_stream->PutCString ("error: unknown error\n");
432 result->SetStatus (eReturnStatusFailed);
439 error_stream->Printf ("error: invalid execution context for expression\n");
447 CommandObjectExpression::DoExecute
450 CommandReturnObject &result
453 m_option_group.NotifyOptionParsingStarting();
455 const char * expr = NULL;
457 if (command[0] == '\0')
459 m_expr_lines.clear();
460 m_expr_line_count = 0;
462 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
465 Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
467 eInputReaderGranularityLine, // token size, to pass to callback function
470 true)); // echo input
473 m_interpreter.GetDebugger().PushInputReader (reader_sp);
474 result.SetStatus (eReturnStatusSuccessFinishNoResult);
478 result.AppendError (err.AsCString());
479 result.SetStatus (eReturnStatusFailed);
484 result.AppendError("out of memory");
485 result.SetStatus (eReturnStatusFailed);
487 return result.Succeeded();
490 if (command[0] == '-')
492 // We have some options and these options MUST end with --.
493 const char *end_options = NULL;
494 const char *s = command;
497 end_options = ::strstr (s, "--");
500 end_options += 2; // Get past the "--"
501 if (::isspace (end_options[0]))
504 while (::isspace (*expr))
514 Args args (command, end_options - command);
515 if (!ParseOptions (args, result))
518 Error error (m_option_group.NotifyOptionParsingFinished());
521 result.AppendError (error.AsCString());
522 result.SetStatus (eReturnStatusFailed);
531 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
534 result.SetStatus (eReturnStatusFailed);