Files
clang-p2996/lldb/test/API/commands/expression/static-initializers/TestStaticInitializers.py
Adrian Prantl d33fa70ddd [lldb] Inline expression evaluator error visualization (#106470)
This patch is a reworking of Pete Lawrence's (@PortalPete) proposal
for better expression evaluator error messages:
https://github.com/llvm/llvm-project/pull/80938

Before:

```
$ lldb -o "expr a+b"
(lldb) expr a+b
error: <user expression 0>:1:1: use of undeclared identifier 'a'
a+b
^
error: <user expression 0>:1:3: use of undeclared identifier 'b'
a+b
  ^
```

After:

```
(lldb) expr a+b
            ^ ^
            │ ╰─ error: use of undeclared identifier 'b'
            ╰─ error: use of undeclared identifier 'a'
```

This eliminates the confusing `<user expression 0>:1:3` source
location and avoids echoing the expression to the console again, which
results in a cleaner presentation that makes it easier to grasp what's
going on. You can't see it here, bug the word "error" is now also in
color, if so desired.

Depends on https://github.com/llvm/llvm-project/pull/106442.
2024-09-27 18:09:52 -07:00

48 lines
1.6 KiB
Python

import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class StaticInitializers(TestBase):
@expectedFailureAll(
archs="aarch64",
oslist=["freebsd"],
bugnumber="llvm.org/pr44053",
)
def test(self):
"""Test a static initializer."""
self.build()
lldbutil.run_to_source_breakpoint(
self, "// break here", lldb.SBFileSpec("main.cpp", False)
)
# We use counter to observe if the initializer was called.
self.expect_expr("counter", result_type="int", result_value="0")
self.expect("expr -p -- struct Foo { Foo() { inc_counter(); } }; Foo f;")
self.expect_expr("counter", result_type="int", result_value="1")
def test_failing_init(self):
"""Test a static initializer that fails to execute."""
self.build()
lldbutil.run_to_source_breakpoint(
self, "// break here", lldb.SBFileSpec("main.cpp", False)
)
# FIXME: This error message is not even remotely helpful.
self.expect(
"expr -p -- struct Foo2 { Foo2() { do_abort(); } }; Foo2 f;",
error=True,
substrs=["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"],
)