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/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 ()
53 CommandObjectExpression::CommandOptions::g_option_table[] =
55 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', required_argument, NULL, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."},
56 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', required_argument, NULL, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
57 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."},
58 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', required_argument, 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)."},
63 CommandObjectExpression::CommandOptions::GetNumDefinitions ()
65 return sizeof(g_option_table)/sizeof(OptionDefinition);
69 CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
71 const char *option_arg)
75 const int short_option = g_option_table[option_idx].short_option;
80 //if (language.SetLanguageFromCString (option_arg) == false)
82 // error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
90 result = Args::StringToBoolean(option_arg, true, &success);
92 error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
94 try_all_threads = result;
101 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
103 ignore_breakpoints = tmp_value;
105 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
112 result = Args::StringToUInt32(option_arg, 0, 0, &success);
116 error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
123 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
125 unwind_on_error = tmp_value;
127 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
131 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
139 CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
141 Process *process = interpreter.GetExecutionContext().GetProcessPtr();
144 ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
145 unwind_on_error = process->GetUnwindOnErrorInExpressions();
149 ignore_breakpoints = false;
150 unwind_on_error = true;
154 try_all_threads = true;
158 const OptionDefinition*
159 CommandObjectExpression::CommandOptions::GetDefinitions ()
161 return g_option_table;
164 CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
165 CommandObjectRaw (interpreter,
167 "Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope.",
169 eFlagProcessMustBePaused | eFlagTryTargetAPILock),
170 m_option_group (interpreter),
171 m_format_options (eFormatDefault),
172 m_command_options (),
173 m_expr_line_count (0),
178 If the expression can be evaluated statically (without runnning code) then it will be.\n\
179 Otherwise, by default the expression will run on the current thread with a short timeout:\n\
180 currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted\n\
181 and resumed with all threads running. You can use the -a option to disable retrying on all\n\
182 threads. You can use the -t option to set a shorter timeout.\n\
184 User defined variables:\n\
185 You can define your own variables for convenience or to be used in subsequent expressions.\n\
186 You define them the same way you would define variables in C. If the first character of \n\
187 your user defined variable is a $, then the variable's value will be available in future\n\
188 expressions, otherwise it will just be available in the current expression.\n\
192 expr my_struct->a = my_array[3] \n\
193 expr -f bin -- (index * 8) + 5 \n\
194 expr unsigned int $foo = 5\n\
195 expr char c[] = \"foo\"; c[0]\n");
197 CommandArgumentEntry arg;
198 CommandArgumentData expression_arg;
200 // Define the first (and only) variant of this arg.
201 expression_arg.arg_type = eArgTypeExpression;
202 expression_arg.arg_repetition = eArgRepeatPlain;
204 // There is only one variant this argument could be; put it into the argument entry.
205 arg.push_back (expression_arg);
207 // Push the data for the first argument into the m_arguments vector.
208 m_arguments.push_back (arg);
210 // Add the "--format" and "--gdb-format"
211 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
212 m_option_group.Append (&m_command_options);
213 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
214 m_option_group.Finalize();
217 CommandObjectExpression::~CommandObjectExpression ()
222 CommandObjectExpression::GetOptions ()
224 return &m_option_group;
228 CommandObjectExpression::MultiLineExpressionCallback
232 lldb::InputReaderAction notification,
237 CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton;
238 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
240 switch (notification)
242 case eInputReaderActivate:
245 StreamSP async_strm_sp(reader.GetDebugger().GetAsyncOutputStream());
248 async_strm_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
249 async_strm_sp->Flush();
253 case eInputReaderReactivate:
256 case eInputReaderDeactivate:
259 case eInputReaderAsynchronousOutputWritten:
262 case eInputReaderGotToken:
263 ++cmd_object_expr->m_expr_line_count;
264 if (bytes && bytes_len)
266 cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1);
270 reader.SetIsDone(true);
273 case eInputReaderInterrupt:
274 cmd_object_expr->m_expr_lines.clear();
275 reader.SetIsDone (true);
278 StreamSP async_strm_sp (reader.GetDebugger().GetAsyncOutputStream());
281 async_strm_sp->PutCString("Expression evaluation cancelled.\n");
282 async_strm_sp->Flush();
287 case eInputReaderEndOfFile:
288 reader.SetIsDone (true);
291 case eInputReaderDone:
292 if (cmd_object_expr->m_expr_lines.size() > 0)
294 StreamSP output_stream = reader.GetDebugger().GetAsyncOutputStream();
295 StreamSP error_stream = reader.GetDebugger().GetAsyncErrorStream();
296 cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(),
299 output_stream->Flush();
300 error_stream->Flush();
309 CommandObjectExpression::EvaluateExpression
312 Stream *output_stream,
313 Stream *error_stream,
314 CommandReturnObject *result
317 // Don't use m_exe_ctx as this might be called asynchronously
318 // after the command object DoExecute has finished when doing
319 // multi-line expression that use an input reader...
320 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
322 Target *target = exe_ctx.GetTargetPtr();
325 target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
329 lldb::ValueObjectSP result_valobj_sp;
331 ExecutionResults exe_results;
333 bool keep_in_memory = true;
335 EvaluateExpressionOptions options;
336 options.SetCoerceToId(m_varobj_options.use_objc)
337 .SetUnwindOnError(m_command_options.unwind_on_error)
338 .SetIgnoreBreakpoints (m_command_options.ignore_breakpoints)
339 .SetKeepInMemory(keep_in_memory)
340 .SetUseDynamic(m_varobj_options.use_dynamic)
341 .SetRunOthers(m_command_options.try_all_threads)
342 .SetTimeoutUsec(m_command_options.timeout);
344 exe_results = target->EvaluateExpression (expr,
345 exe_ctx.GetFramePtr(),
349 if (result_valobj_sp)
351 Format format = m_format_options.GetFormat();
353 if (result_valobj_sp->GetError().Success())
355 if (format != eFormatVoid)
357 if (format != eFormatDefault)
358 result_valobj_sp->SetFormat (format);
360 ValueObject::DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(true,format));
362 ValueObject::DumpValueObject (*(output_stream),
363 result_valobj_sp.get(), // Variable object to dump
366 result->SetStatus (eReturnStatusSuccessFinishResult);
371 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
373 if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
375 error_stream->PutCString("(void)\n");
379 result->SetStatus (eReturnStatusSuccessFinishResult);
383 const char *error_cstr = result_valobj_sp->GetError().AsCString();
384 if (error_cstr && error_cstr[0])
386 const size_t error_cstr_len = strlen (error_cstr);
387 const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
388 if (strstr(error_cstr, "error:") != error_cstr)
389 error_stream->PutCString ("error: ");
390 error_stream->Write(error_cstr, error_cstr_len);
391 if (!ends_with_newline)
396 error_stream->PutCString ("error: unknown error\n");
400 result->SetStatus (eReturnStatusFailed);
407 error_stream->Printf ("error: invalid execution context for expression\n");
415 CommandObjectExpression::DoExecute
418 CommandReturnObject &result
421 m_option_group.NotifyOptionParsingStarting();
423 const char * expr = NULL;
425 if (command[0] == '\0')
427 m_expr_lines.clear();
428 m_expr_line_count = 0;
430 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
433 Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
435 eInputReaderGranularityLine, // token size, to pass to callback function
438 true)); // echo input
441 m_interpreter.GetDebugger().PushInputReader (reader_sp);
442 result.SetStatus (eReturnStatusSuccessFinishNoResult);
446 result.AppendError (err.AsCString());
447 result.SetStatus (eReturnStatusFailed);
452 result.AppendError("out of memory");
453 result.SetStatus (eReturnStatusFailed);
455 return result.Succeeded();
458 if (command[0] == '-')
460 // We have some options and these options MUST end with --.
461 const char *end_options = NULL;
462 const char *s = command;
465 end_options = ::strstr (s, "--");
468 end_options += 2; // Get past the "--"
469 if (::isspace (end_options[0]))
472 while (::isspace (*expr))
482 Args args (command, end_options - command);
483 if (!ParseOptions (args, result))
486 Error error (m_option_group.NotifyOptionParsingFinished());
489 result.AppendError (error.AsCString());
490 result.SetStatus (eReturnStatusFailed);
499 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
502 result.SetStatus (eReturnStatusFailed);