jingham created this revision. Herald added subscribers: lldb-commits, abidh, JDevlieghere.
When you run an expression like: (lldb) expr int $x = 10 the expression has no result. The ValueObject (and then SBValue) you get back from the expression signals that by putting an error indicating this in the Status object returned by SBValue::GetError(). Unfortunately, this error was not terribly helpful. The error number was a private constant that only UserExpression knew about, and the error string was unset. This meant you couldn't really trust the result of SBValue.GetError().Success() when you ran an expression. This commit adds an eExpressionProducedNoResult constant to the ExpressionResults enum, and used that and an appropriate string in the error object. So now you can usefully tell the difference between an expression that produces no result and one that failed. Repository: rLLDB LLDB https://reviews.llvm.org/D53309 Files: include/lldb/Expression/UserExpression.h include/lldb/lldb-enumerations.h packages/Python/lldbsuite/test/expression_command/no-result/Makefile packages/Python/lldbsuite/test/expression_command/no-result/TestNoResult.py packages/Python/lldbsuite/test/expression_command/no-result/main.c source/Commands/CommandObjectExpression.cpp source/Expression/REPL.cpp source/Expression/UserExpression.cpp source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
Index: packages/Python/lldbsuite/test/expression_command/no-result/main.c =================================================================== --- packages/Python/lldbsuite/test/expression_command/no-result/main.c +++ packages/Python/lldbsuite/test/expression_command/no-result/main.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +int +main() +{ + int test_var = 10; + printf ("Set a breakpoint here: %d.\n", test_var); + return 0; +} Index: packages/Python/lldbsuite/test/expression_command/no-result/TestNoResult.py =================================================================== --- packages/Python/lldbsuite/test/expression_command/no-result/TestNoResult.py +++ packages/Python/lldbsuite/test/expression_command/no-result/TestNoResult.py @@ -0,0 +1,45 @@ +""" +Test that an expression that returns no result returns a sensible error. +""" + +from __future__ import print_function + + +import os +import time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + + +class TestExprNoResult(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # If your test case doesn't stress debug info, the + # set this to true. That way it won't be run once for + # each debug info format. + NO_DEBUG_INFO_TESTCASE = True + + def test_no_result(self): + """Run an expression that has no result, check the error.""" + self.build() + self.main_source_file = lldb.SBFileSpec("main.c") + self.sample_test() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + def sample_test(self): + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "Set a breakpoint here", self.main_source_file) + + frame = thread.GetFrameAtIndex(0) + result = frame.EvaluateExpression("int $x = 10") + # No result expressions are considered to fail: + self.assertTrue(result.GetError().Fail(), "An expression with no result is a failure.") + # But the reason should be eExpressionProducedNoResult + self.assertEqual(result.GetError().GetError(), lldb.eExpressionProducedNoResult, + "But the right kind of failure") Index: packages/Python/lldbsuite/test/expression_command/no-result/Makefile =================================================================== --- packages/Python/lldbsuite/test/expression_command/no-result/Makefile +++ packages/Python/lldbsuite/test/expression_command/no-result/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../make + +C_SOURCES := main.c +CFLAGS_EXTRAS += -std=c99 + +include $(LEVEL)/Makefile.rules Index: source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp =================================================================== --- source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp +++ source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp @@ -1758,7 +1758,7 @@ if (!expr_result->GetError().Success()) { Status err = expr_result->GetError(); // Expression returned is void, so this is actually a success - if (err.GetError() == UserExpression::kNoResult) { + if (err.GetError() == lldb::eExpressionProducedNoResult) { if (log) log->Printf("%s - expression returned void.", __FUNCTION__); Index: source/Expression/UserExpression.cpp =================================================================== --- source/Expression/UserExpression.cpp +++ source/Expression/UserExpression.cpp @@ -151,6 +151,9 @@ ? UserExpression::eResultTypeId : UserExpression::eResultTypeAny; lldb::ExpressionResults execution_results = lldb::eExpressionSetupError; + + static const char *no_result_error = "Expression completed successfully " + "but had no result"; Target *target = exe_ctx.GetTargetPtr(); if (!target) { @@ -304,7 +307,8 @@ error.SetExpressionError(lldb::eExpressionSetupError, "expression needed to run but couldn't"); } else if (execution_policy == eExecutionPolicyTopLevel) { - error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); + error.SetExpressionError(lldb::eExpressionProducedNoResult, + no_result_error); return lldb::eExpressionCompleted; } else { if (options.InvokeCancelCallback(lldb::eExpressionEvaluationExecution)) { @@ -349,7 +353,8 @@ log->Printf("== [UserExpression::Evaluate] Execution completed " "normally with no result =="); - error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); + error.SetExpressionError(lldb::eExpressionProducedNoResult, + no_result_error); } } } Index: source/Expression/REPL.cpp =================================================================== --- source/Expression/REPL.cpp +++ source/Expression/REPL.cpp @@ -325,7 +325,7 @@ if (result_valobj_sp->GetError().Success()) { handled |= PrintOneVariable(debugger, output_sp, result_valobj_sp); } else if (result_valobj_sp->GetError().GetError() == - UserExpression::kNoResult) { + lldb::eExpressionProducedNoResult) { if (format != lldb::eFormatVoid && debugger.GetNotifyVoid()) { error_sp->PutCString("(void)\n"); handled = true; Index: source/Commands/CommandObjectExpression.cpp =================================================================== --- source/Commands/CommandObjectExpression.cpp +++ source/Commands/CommandObjectExpression.cpp @@ -487,7 +487,7 @@ } } else { if (result_valobj_sp->GetError().GetError() == - UserExpression::kNoResult) { + lldb::eExpressionProducedNoResult) { if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid()) { error_stream->PutCString("(void)\n"); Index: include/lldb/lldb-enumerations.h =================================================================== --- include/lldb/lldb-enumerations.h +++ include/lldb/lldb-enumerations.h @@ -254,7 +254,8 @@ eExpressionHitBreakpoint, eExpressionTimedOut, eExpressionResultUnavailable, - eExpressionStoppedForDebug + eExpressionStoppedForDebug, + eExpressionProducedNoResult }; enum SearchDepth { Index: include/lldb/Expression/UserExpression.h =================================================================== --- include/lldb/Expression/UserExpression.h +++ include/lldb/Expression/UserExpression.h @@ -288,10 +288,6 @@ uint32_t line_offset = 0, std::string *fixed_expression = nullptr, lldb::ModuleSP *jit_module_sp_ptr = nullptr); - static const Status::ValueType kNoResult = - 0x1001; ///< ValueObject::GetError() returns this if there is no result - /// from the expression. - const char *GetFixedText() { if (m_fixed_text.empty()) return nullptr;
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits