[Lldb-commits] [lldb] 71536fd - [lldb] Fix that running a top level expression without a process fails with a cryptic error
Raphael Isemann via lldb-commits
lldb-commits at lists.llvm.org
Thu Feb 11 08:07:34 PST 2021
Author: Raphael Isemann
Date: 2021-02-11T17:07:11+01:00
New Revision: 71536fd031084b25ffc9ad0a26c8471a68f5ad7c
URL: https://github.com/llvm/llvm-project/commit/71536fd031084b25ffc9ad0a26c8471a68f5ad7c
DIFF: https://github.com/llvm/llvm-project/commit/71536fd031084b25ffc9ad0a26c8471a68f5ad7c.diff
LOG: [lldb] Fix that running a top level expression without a process fails with a cryptic error
Right now when running `expr --top-level -- void foo() {}`, LLDB just prints a cryptic
`error: Couldn't find $__lldb_expr() in the module` error. The reason for that is
that if we don't have a running process, we try to set our execution policy to always use the
IR interpreter (ExecutionPolicyNever) which works even without a process. However
that code didn't consider the special ExecutionPolicyTopLevel which we use for
top-level expressions. By changing the execution policy to ExecutionPolicyNever,
LLDB thinks we're actually trying to interpret a normal expression inside our
`$__lldb_expr` function and then fails when looking for it.
This just adds an exception for top-level expressions to that code and a bunch of tests.
Reviewed By: shafik
Differential Revision: https://reviews.llvm.org/D91723
Added:
Modified:
lldb/source/Expression/UserExpression.cpp
lldb/test/API/commands/expression/static-initializers/TestStaticInitializers.py
lldb/test/API/commands/expression/top-level/TestTopLevelExprs.py
lldb/test/API/lang/cpp/elaborated-types/TestElaboratedTypes.py
Removed:
################################################################################
diff --git a/lldb/source/Expression/UserExpression.cpp b/lldb/source/Expression/UserExpression.cpp
index c6a288a30b17..25931b1232b4 100644
--- a/lldb/source/Expression/UserExpression.cpp
+++ b/lldb/source/Expression/UserExpression.cpp
@@ -187,7 +187,12 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx,
}
}
- if (process == nullptr || !process->CanJIT())
+ // Explicitly force the IR interpreter to evaluate the expression when the
+ // there is no process that supports running the expression for us. Don't
+ // change the execution policy if we have the special top-level policy that
+ // doesn't contain any expression and there is nothing to interpret.
+ if (execution_policy != eExecutionPolicyTopLevel &&
+ (process == nullptr || !process->CanJIT()))
execution_policy = eExecutionPolicyNever;
// We need to set the expression execution thread here, turns out parse can
diff --git a/lldb/test/API/commands/expression/static-initializers/TestStaticInitializers.py b/lldb/test/API/commands/expression/static-initializers/TestStaticInitializers.py
index 6abdb226be29..60a005f10280 100644
--- a/lldb/test/API/commands/expression/static-initializers/TestStaticInitializers.py
+++ b/lldb/test/API/commands/expression/static-initializers/TestStaticInitializers.py
@@ -31,3 +31,8 @@ def test_failing_init(self):
# FIXME: This error message is not even remotely helpful.
self.expect("expr -p -- struct Foo2 { Foo2() { do_abort(); } }; Foo2 f;", error=True,
substrs=["error: couldn't run static initializer:"])
+
+ def test_without_process(self):
+ """ Test a static initializer without a running process. """
+ self.expect("expr -p -- int i = 0; struct Foo3 { Foo3() { ++i; } }; Foo3 f;", error=True,
+ substrs=["Top-level code needs to be inserted into a runnable target"])
diff --git a/lldb/test/API/commands/expression/top-level/TestTopLevelExprs.py b/lldb/test/API/commands/expression/top-level/TestTopLevelExprs.py
index 4e1a3779cfc3..92707eabec0c 100644
--- a/lldb/test/API/commands/expression/top-level/TestTopLevelExprs.py
+++ b/lldb/test/API/commands/expression/top-level/TestTopLevelExprs.py
@@ -91,3 +91,14 @@ def test_top_level_expressions(self):
self.assertEqual(
resultFromCode,
resultFromTopLevel.GetValueAsUnsigned())
+
+ def test_top_level_expression_without_target(self):
+ self.expect("expr --top-level -- void func() {}", error=True,
+ substrs=["Top-level code needs to be inserted into a runnable target"])
+
+ # FIXME: This doesn't actually generate any code, so LLDB should probably
+ # allow these expressions.
+ self.expect("expr --top-level -- template<typename T> struct StructT { T m; };", error=True,
+ substrs=["Top-level code needs to be inserted into a runnable target"])
+ self.expect("expr --top-level -- struct Struct { int i; };", error=True,
+ substrs=["Top-level code needs to be inserted into a runnable target"])
diff --git a/lldb/test/API/lang/cpp/elaborated-types/TestElaboratedTypes.py b/lldb/test/API/lang/cpp/elaborated-types/TestElaboratedTypes.py
index 395ba30b5454..97670ec263e5 100644
--- a/lldb/test/API/lang/cpp/elaborated-types/TestElaboratedTypes.py
+++ b/lldb/test/API/lang/cpp/elaborated-types/TestElaboratedTypes.py
@@ -34,7 +34,7 @@ def test(self):
# Declare a template that can actually be instantiated.
# FIXME: The error message here is incorrect.
self.expect("expr --top-level -- template<typename T> struct $V {};",
- error=True, substrs=["Couldn't find $__lldb_expr() in the module"])
+ error=True, substrs=["Top-level code needs to be inserted into a runnable target"])
result = self.expect_expr("$V<::Struct> s; s",
result_type="$V< ::Struct>")
self.assertEqual(result.GetTypeName(), "$V<Struct>")
More information about the lldb-commits
mailing list