The architectures provided to skipIf / expectedFail are regular
expressions (v. _match_decorator_property() in decorators.py
so on Darwin systems "arm64" would match the skips for "arm" (32-bit
Linux). Update these to "arm$" to prevent this, and also update
three tests (TestBuiltinFormats.py, TestCrossDSOTailCalls.py,
TestCrossObjectTailCalls.py) that were skipped for arm64 via this
behavior, and need to be skipped or they will fail.
This was moviated by the new TestDynamicValue.py test which has
an expected-fail for arm, but the test was passing on arm64 Darwin
resulting in failure for the CIs.
I thought I could call $(CPP) to preprocess the assembly
file, but the aarch64-ubuntu bot runs this as clang -E and
it issues a warning and no output file, apparently,
build/bin/clang -E -o interrupt-and-trap-funcs.s /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/functionalities/unwind/frameless-faulted/interrupt-and-trap-funcs.s
clang: warning: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/functionalities/unwind/frameless-faulted/interrupt-and-trap-funcs.s: 'assembler' input unused [-Wunused-command-line-argument]
/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang -g -O0 -c -o interrupt-and-trap-funcs.o interrupt-and-trap-funcs.s
clang: error: no such file or directory: 'interrupt-and-trap-funcs.s'
clang: error: no input files
Re-landing this patch with small tweaks to address CI bot failures
as it was run on many different configurations. I think the test
may run on aarch64 Linux systems now.
When a frameless function faults or is interrupted asynchronously, the
UnwindPlan MAY have no register location rule for the return address
register (lr on arm64); the value is simply live in the lr register when
it was interrupted, and the frame below this on the stack -- e.g.
sigtramp on a Unix system -- has the full register context, including
that register.
RegisterContextUnwind::SavedLocationForRegister, when asked to find the
caller's pc value, will first see if there is a pc register location. If
there isn't, on a Return Address Register architecture like
arm/mips/riscv, we rewrite the register request from "pc" to "RA
register", and search for a location.
On frame 0 (the live frame) and an interrupted frame, the UnwindPlan may
have no register location rule for the RA Reg, that is valid. A
frameless function that never calls another may simply keep the return
address in the live register the whole way. Our instruction emulation
unwind plans explicitly add a rule (see Pavel's May 2024 change
https://github.com/llvm/llvm-project/pull/91321 ), but an UnwindPlan
sourced from debug_frame may not.
I've got a case where this exactly happens - clang debug_frame for arm64
where there is no register location for the lr in a frameless function.
There is a fault in the middle of this frameless function and we only
get the lr value from the fault handler below this frame if lr has a
register location of `IsSame`, in line with Pavel's 2024 change.
Similar to how we see a request of the RA Reg from frame 0 after failing
to find an unwind location for the pc register, the same style of
special casing is needed when this is a function that was interrupted.
Without this change, we can find the pc of the frame that was executing
when it was interrupted, but we need $lr to find its caller, and we
don't descend down to the trap handler to get that value, truncating the
stack.
rdar://145614545
This test is failing on the LLDB Incremental bot (arm64), which is
running an older set of tools (Xcode 15.2) and OS (macOS 14.1) and
the CFI directives must not be emitted correctly by either the tools
or the OS. I will need to reproduce how this is compiling on that
older setup and see what the issue is. Reverting for now so the
bots are not blocked.
This reverts commit e897cb139ee6ef5c145fed5394c4d96baa658e6b.
Failed at compile time lldb-aarch64-ubuntu bot.
It did clang -E -o interrupt-and-trap-funcs.s interrupt-and-trap-funcs.c
and that added a bunch of standard C header typedefs to
the output .s file which then turn into compile errors
when it tries to compile the .s file as assembly. Never saw
that behavior in my testing on an ubuntu 24.04 system.
It would have been nice to have the test run on Linux as well
as Darwin, but it's not essential.
When a frameless function faults or is interrupted asynchronously, the
UnwindPlan MAY have no register location rule for the return address
register (lr on arm64); the value is simply live in the lr register when
it was interrupted, and the frame below this on the stack -- e.g.
sigtramp on a Unix system -- has the full register context, including
that register.
RegisterContextUnwind::SavedLocationForRegister, when asked to find the
caller's pc value, will first see if there is a pc register location. If
there isn't, on a Return Address Register architecture like
arm/mips/riscv, we rewrite the register request from "pc" to "RA
register", and search for a location.
On frame 0 (the live frame) and an interrupted frame, the UnwindPlan may
have no register location rule for the RA Reg, that is valid. A
frameless function that never calls another may simply keep the return
address in the live register the whole way. Our instruction emulation
unwind plans explicitly add a rule (see Pavel's May 2024 change
https://github.com/llvm/llvm-project/pull/91321 ), but an UnwindPlan
sourced from debug_frame may not.
I've got a case where this exactly happens - clang debug_frame for arm64
where there is no register location for the lr in a frameless function.
There is a fault in the middle of this frameless function and we only
get the lr value from the fault handler below this frame if lr has a
register location of `IsSame`, in line with Pavel's 2024 change.
Similar to how we see a request of the RA Reg from frame 0 after failing
to find an unwind location for the pc register, the same style of
special casing is needed when this is a function that was interrupted.
Without this change, we can find the pc of the frame that was executing
when it was interrupted, but we need $lr to find its caller, and we
don't descend down to the trap handler to get that value, truncating the
stack.
rdar://145614545
Line ending policies were changed in the parent, dccebddb3b80. To make
it easier to resolve downstream merge conflicts after line-ending
policies are adjusted this is a separate whitespace-only commit. If you
have merge conflicts as a result, you can simply `git add --renormalize
-u && git merge --continue` or `git add --renormalize -u && git rebase
--continue` - depending on your workflow.
This test is currently flaky on a local Windows amd64 build. The reason
is that it relies on the order of `process.threads` but this order is
nondeterministic:
If we print lldb's inputs and outputs while running, we can see that the
breakpoints are always being set correctly, and always being hit:
```sh
runCmd: breakpoint set -f "main.c" -l 2
output: Breakpoint 1: where = a.out`func_inner + 1 at main.c:2:9, address = 0x0000000140001001
runCmd: breakpoint set -f "main.c" -l 7
output: Breakpoint 2: where = a.out`main + 17 at main.c:7:5, address = 0x0000000140001021
runCmd: run
output: Process 52328 launched: 'C:\workspace\llvm-project\llvm\build\lldb-test-build.noindex\functionalities\unwind\zeroth_frame\TestZerothFrame.test_dwarf\a.out' (x86_64)
Process 52328 stopped
* thread #1, stop reason = breakpoint 1.1
frame #0: 0x00007ff68f6b1001 a.out`func_inner at main.c:2:9
1 void func_inner() {
-> 2 int a = 1; // Set breakpoint 1 here
^
3 }
4
5 int main() {
6 func_inner();
7 return 0; // Set breakpoint 2 here
```
However, sometimes the backtrace printed in this test shows that the
process is stopped inside NtWaitForWorkViaWorkerFactory from
`ntdll.dll`:
```sh
Backtrace at the first breakpoint:
frame #0: 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20
frame #1: 0x00007ffecc74585e ntdll.dll`RtlClearThreadWorkOnBehalfTicket + 862
frame #2: 0x00007ffecc3e257d kernel32.dll`BaseThreadInitThunk + 29
frame #3: 0x00007ffecc76af28 ntdll.dll`RtlUserThreadStart + 40
```
When this happens, the test fails with an assertion error that the
stopped thread's zeroth frame's current line number does not match the
expected line number. This is because the test is looking at the wrong
thread: `process.threads[0]`.
If we print the list of threads each time the test is run, we notice
that threads are sometimes in a different order, within
`process.threads`:
```sh
Thread 0: thread #4: tid = 0x9c38, 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20
Thread 1: thread #2: tid = 0xa950, 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20
Thread 2: thread #1: tid = 0xab18, 0x00007ff64bc81001 a.out`func_inner at main.c:2:9, stop reason = breakpoint 1.1
Thread 3: thread #3: tid = 0xc514, 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20
Thread 0: thread #3: tid = 0x018c, 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20
Thread 1: thread #1: tid = 0x85c8, 0x00007ff7130c1001 a.out`func_inner at main.c:2:9, stop reason = breakpoint 1.1
Thread 2: thread #2: tid = 0xf344, 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20
Thread 3: thread #4: tid = 0x6a50, 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20
```
Use `self.thread()` to consistently select the correct thread, instead.
Co-authored-by: kendal <kendal@thebrowser.company>
This uses [teyit](https://pypi.org/project/teyit/) to modernize asserts,
as recommended by the [unittest release
notes](https://docs.python.org/3.12/whatsnew/3.12.html#id3).
For example, `assertTrue(a == b)` is replaced with `assertEqual(a, b)`.
This produces better error messages, e.g. `error: unexpectedly found 1
and 2 to be different` instead of `error: False`.
assertEquals is a deprecated alias for assertEqual and has been removed
in Python 3.12. This wasn't an issue previously because we used a
vendored version of the unittest module. Now that we use the built-in
version this gets updated together with the Python version used to run
the test suite.
All Python files in the LLVM repository were reformatted with Black [1].
Files inside the LLDB subproject were reformatted in 2238dcc39358. This
patch updates a handful of tests that were added or modified since then
and weren't formatted with Black.
[1] https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style/68257
Running this on Amazon Ubuntu the final backtrace is:
```
(lldb) thread backtrace
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
* frame #0: 0x0000aaaaaaaa07d0 a.out`func_c at main.c:10:3
frame #1: 0x0000aaaaaaaa07c4 a.out`func_b at main.c:14:3
frame #2: 0x0000aaaaaaaa07b4 a.out`func_a at main.c:18:3
frame #3: 0x0000aaaaaaaa07a4 a.out`main(argc=<unavailable>, argv=<unavailable>) at main.c:22:3
frame #4: 0x0000fffff7b373fc libc.so.6`___lldb_unnamed_symbol2962 + 108
frame #5: 0x0000fffff7b374cc libc.so.6`__libc_start_main + 152
frame #6: 0x0000aaaaaaaa06b0 a.out`_start + 48
```
This causes the test to fail because of the extra ___lldb_unnamed_symbol2962 frame
(an inlined function?).
To fix this, strictly check all the frames in main.c then for the rest
just check we find __libc_start_main and _start in that order regardless
of other frames in between.
Reviewed By: omjavaid
Differential Revision: https://reviews.llvm.org/D154204
This is an ongoing series of commits that are reformatting our Python
code. Reformatting is done with `black` (23.1.0).
If you end up having problems merging this commit because you have made
changes to a python file, the best way to handle that is to run `git
checkout --ours <yourfile>` and then reformat it with black.
RFC: https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style
Differential revision: https://reviews.llvm.org/D151460
Eliminate boilerplate of having each test manually assign to `mydir` by calling
`compute_mydir` in lldbtest.py.
Differential Revision: https://reviews.llvm.org/D128077
It's been broken (not failing, but not testing anything either) for
quite some time now, and nobody noticed. It also (by design) tests
stepping through libc code, which makes it completely non-hermetic.
It's not worth reviving such a test.
TestAArch64UnwindPAC.py started failing on LLDB buildbot as underlying
hardware does not support PAC. This patch skips this test for targets
which do not support PAC feature.
This patch builds on D100521 and other related patches to add support
for unwinding stack on AArch64 systems with pointer authentication
feature enabled.
We override FixCodeAddress and FixDataAddress function in ABISysV_arm64
class. We now try to calculate and set code and data masks after reading
data_mask and code_mask registers exposed by AArch64 targets running Linux.
This patch utilizes core file linux-aarch64-pac.core for testing that
LLDB can successfully unwind stack frames in the presence of signed
return address after masking off ignored bits.
This patch also includes a AArch64 Linux native test case to demonstrate
successful back trace calculation in presence of pointer authentication
feature.
Differential Revision: https://reviews.llvm.org/D99944
The core file used is built for i386 so we
need the x86 backend to be able to load it.
Reviewed By: labath
Differential Revision: https://reviews.llvm.org/D100195
TestStandardUnwind uses the full absolute path to a set of C/C++ files as the test case name, which in turn is used in the name of a log file. When the source file is long, and the directory where log files are stored is also long, this causes an OSError because the log filename is too long.
Reviewed By: JDevlieghere
Differential Revision: https://reviews.llvm.org/D86752
Fix to code from https://reviews.llvm.org/D64993.
Field StackFrame::m_behaves_like_zeroth_frame was introduced in commit
[1], however that commit hasn't added a copying of the field to
UpdatePreviousFrameFromCurrentFrame, therefore the value wouldn't change
when updating frames to reflect the current situation.
The particular scenario, where this matters is following. Assume we have
function main that invokes function func1. We set breakpoint at
func1 entry and in main after the func1 call, and do not stop at
the main entry. Therefore, when debugger stops for the first time,
func1 is frame#0, while main is frame#1, thus
m_behaves_like_zeroth_frame is set to 0 for main frame. Execution is
resumed, and stops now in main, where it is now frame#0. However while
updating the frame object, m_behaves_like_zeroth_frame remains false.
This field plays an important role when calculating line information for
backtrace: for frame#0, PC is the current line, therefore line
information is retrieved for PC, however for all other frames this is
not the case - calculated PC is a return-PC, i.e. instruction after the
function call line, therefore for those frames LLDB needs to step back
by one instruction. Initial implementation did this strictly for frames
that have index != 0 (and index is updated properly in
UpdatePreviousFrameFromCurrentFrame), but m_behaves_like_zeroth_frame
added a capability for middle-of-stack frames to behave in a similar
manner. But because current code now doesn't check frame idx,
m_behaves_like_zeroth_frame must be set to true for frames with 0 index,
not only for frame that behave like one. In the described test case,
after stopping in main, LLDB would still consider frame#0 as
non-zeroth, and would subtract instruction from the PC, and would report
previous like as current line.
The error doesn't manifest itself in LLDB interpreter though - it can be
reproduced through LLDB-MI and when using SB API, but not when we
interpreter command "continue" is executed. Honestly, I didn't fully
understand why it works in interpreter, I did found that bug "fixes"
itself if I enable DEBUG_STACK_FRAMES in StackFrameList.cpp, because
that calls StackFrame::Dump and that calls
GetSymbolContext(eSymbolContextEverything), which fills the context of
frame on the first breakpoint, therefore it doesn't have to be
recalculated (improperly) on a second frame. However, on first
breakpoint symbol context is calculated for the "call" line, not the
next one, therefore it should be recalculated anyway on a second
breakpoint, and it is done correctly, even though
m_behaves_like_zeroth_frame is still incorrect, as long as
GetSymbolContext(eSymbolContextEverything) has been called.
[1] 31e6dbe1c6a6 Fix PC adjustment in StackFrame::GetSymbolContext
Differential Revision: https://reviews.llvm.org/D75975
Patch by Anton Kolesov <Anton.Kolesov@synopsys.com>
Some tests set settings and don't clean them up, this leads to side effects in other tests.
The patch removes a global debugger instance with a per-test debugger to avoid such effects.
From what I see, lldb.DBG was needed to determine the platform before a test is run,
lldb.selected_platform is used for this purpose now. Though, this required adding a new function
to the SBPlatform interface.
Differential Revision: https://reviews.llvm.org/D74903
Summary:
Around a third of our test sources have LLVM license headers. This patch removes those headers from all test
sources and also fixes any tests that depended on the length of the license header.
The reasons for this are:
* A few tests verify line numbers and will start failing if the number of lines in the LLVM license header changes. Once I landed my patch for valid SourceLocations in debug info we will probably have even more tests that verify line numbers.
* No other LLVM project is putting license headers in its test files to my knowledge.
* They make the test sources much more verbose than they have to be. Several tests have longer license headers than the actual test source.
For the record, the following tests had their line numbers changed to pass with the removal of the license header:
lldb-api :: functionalities/breakpoint/breakpoint_by_line_and_column/TestBreakpointByLineAndColumn.py
lldb-shell :: Reproducer/TestGDBRemoteRepro.test
lldb-shell :: Reproducer/TestMultipleTargets.test
lldb-shell :: Reproducer/TestReuseDirectory.test
lldb-shell :: ExecControl/StopHook/stop-hook-threads.test
lldb-shell :: ExecControl/StopHook/stop-hook.test
lldb-api :: lang/objc/exceptions/TestObjCExceptions.py
Reviewers: #lldb, espindola, JDevlieghere
Reviewed By: #lldb, JDevlieghere
Subscribers: emaste, aprantl, arphaman, JDevlieghere, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D74839
Summary: Moves lldbsuite tests to lldb/test/API.
This is a largely mechanical change, moved with the following steps:
```
rm lldb/test/API/testcases
mkdir -p lldb/test/API/{test_runner/test,tools/lldb-{server,vscode}}
mv lldb/packages/Python/lldbsuite/test/test_runner/test lldb/test/API/test_runner
for d in $(find lldb/packages/Python/lldbsuite/test/* -maxdepth 0 -type d | egrep -v "make|plugins|test_runner|tools"); do mv $d lldb/test/API; done
for d in $(find lldb/packages/Python/lldbsuite/test/tools/lldb-vscode -maxdepth 1 -mindepth 1 | grep -v ".py"); do mv $d lldb/test/API/tools/lldb-vscode; done
for d in $(find lldb/packages/Python/lldbsuite/test/tools/lldb-server -maxdepth 1 -mindepth 1 | egrep -v "gdbremote_testcase.py|lldbgdbserverutils.py|socket_packet_pump.py"); do mv $d lldb/test/API/tools/lldb-server; done
```
lldb/packages/Python/lldbsuite/__init__.py and lldb/test/API/lit.cfg.py were also updated with the new directory structure.
Reviewers: labath, JDevlieghere
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D71151