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/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"
40 using namespace lldb_private;
42 CommandObjectExpression::CommandOptions::CommandOptions () :
48 CommandObjectExpression::CommandOptions::~CommandOptions ()
52 static OptionEnumValueElement g_description_verbosity_type[] =
54 { eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact", "Only show the description string"},
55 { eLanguageRuntimeDescriptionDisplayVerbosityFull, "full", "Show the full output, including persistent variable's name and type"},
60 CommandObjectExpression::CommandOptions::g_option_table[] =
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."},
72 CommandObjectExpression::CommandOptions::GetNumDefinitions ()
74 return sizeof(g_option_table)/sizeof(OptionDefinition);
78 CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
80 const char *option_arg)
84 const int short_option = g_option_table[option_idx].short_option;
89 //if (language.SetLanguageFromCString (option_arg) == false)
91 // error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
99 result = Args::StringToBoolean(option_arg, true, &success);
101 error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
103 try_all_threads = result;
110 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
112 ignore_breakpoints = tmp_value;
114 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
121 result = Args::StringToUInt32(option_arg, 0, 0, &success);
125 error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
132 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
134 unwind_on_error = tmp_value;
136 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
143 m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
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);
153 unwind_on_error = false;
154 ignore_breakpoints = false;
158 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
166 CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
168 Process *process = interpreter.GetExecutionContext().GetProcessPtr();
171 ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
172 unwind_on_error = process->GetUnwindOnErrorInExpressions();
176 ignore_breakpoints = false;
177 unwind_on_error = true;
181 try_all_threads = true;
184 m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
187 const OptionDefinition*
188 CommandObjectExpression::CommandOptions::GetDefinitions ()
190 return g_option_table;
193 CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
194 CommandObjectRaw (interpreter,
196 "Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope.",
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),
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::EvaluateExpression
261 Stream *output_stream,
262 Stream *error_stream,
263 CommandReturnObject *result
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());
271 Target *target = exe_ctx.GetTargetPtr();
274 target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
278 lldb::ValueObjectSP result_valobj_sp;
280 ExecutionResults exe_results;
282 bool keep_in_memory = true;
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);
293 if (m_command_options.timeout > 0)
294 options.SetTimeoutUsec(m_command_options.timeout);
296 options.SetTimeoutUsec(0);
298 exe_results = target->EvaluateExpression (expr,
299 exe_ctx.GetFramePtr(),
303 if (result_valobj_sp)
305 Format format = m_format_options.GetFormat();
307 if (result_valobj_sp->GetError().Success())
309 if (format != eFormatVoid)
311 if (format != eFormatDefault)
312 result_valobj_sp->SetFormat (format);
314 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
316 result_valobj_sp->Dump(*output_stream,options);
319 result->SetStatus (eReturnStatusSuccessFinishResult);
324 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
326 if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
328 error_stream->PutCString("(void)\n");
332 result->SetStatus (eReturnStatusSuccessFinishResult);
336 const char *error_cstr = result_valobj_sp->GetError().AsCString();
337 if (error_cstr && error_cstr[0])
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)
349 error_stream->PutCString ("error: unknown error\n");
353 result->SetStatus (eReturnStatusFailed);
360 error_stream->Printf ("error: invalid execution context for expression\n");
368 CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
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());
376 EvaluateExpression (line.c_str(),
386 CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler,
391 if (line_idx == UINT32_MAX)
393 // Remove the last line from "lines" so it doesn't appear
394 // in our final expression
397 return LineStatus::Done;
399 else if (line_idx + 1 == lines.GetSize())
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;
406 return LineStatus::Success;
410 CommandObjectExpression::DoExecute
413 CommandReturnObject &result
416 m_option_group.NotifyOptionParsingStarting();
418 const char * expr = NULL;
420 if (command[0] == '\0')
422 m_expr_lines.clear();
423 m_expr_line_count = 0;
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
433 StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
436 output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
439 debugger.PushIOHandler(io_handler_sp);
440 return result.Succeeded();
443 if (command[0] == '-')
445 // We have some options and these options MUST end with --.
446 const char *end_options = NULL;
447 const char *s = command;
450 end_options = ::strstr (s, "--");
453 end_options += 2; // Get past the "--"
454 if (::isspace (end_options[0]))
457 while (::isspace (*expr))
467 Args args (command, end_options - command);
468 if (!ParseOptions (args, result))
471 Error error (m_option_group.NotifyOptionParsingFinished());
474 result.AppendError (error.AsCString());
475 result.SetStatus (eReturnStatusFailed);
484 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
487 result.SetStatus (eReturnStatusFailed);