The test for this is artificial as I'm not aware of any upstream targets
that use DW_CFA_val_offset
RegisterContextUnwind::ReadFrameAddress now reports how it's attempting
to obtain the CFA unless all success/failure cases emit logs that
clearly identify the method it was attempting. Previously several of the
existing failure paths emit no message or a message that's
indistinguishable from those on other paths.
AddressFunctionScope was always returning the first address range of the
function (assuming it was the only one). This doesn't work for
RegisterContextUnwind (it's only caller), when the function doesn't
start at the lowest address because it throws off the 'how many bytes
"into" a function I am' computation. This patch replaces the result with
a call to (recently introduced)
SymbolContext::GetFunctionOrSymbolAddress.
This patch uses the previously build infrastructure to parse multiple
FDE entries into a single unwind plan. There is one catch though: we
parse only one FDE entry per unwind range. This is not fully correct
because lldb coalesces adjecant address ranges, which means that
something that originally looked like two separate address ranges (and
two FDE entries) may get merged into one because if the linker decides
to put the two ranges next to each other. In this case, we will ignore
the second FDE entry.
It would be more correct to try to parse another entry when the one we
found turns out to be short, but I'm not doing this (yet), because:
- this is how we've done things so far (although, monolithic functions
are unlikely to have more than one FDE entry)
- in cases where we don't have debug info or (full) symbol tables, we
can end up with "symbols" which appear to span many megabytes
(potentially, the whole module). If we tried to fill short FDE entries,
we could end up parsing the entire eh_frame section in a single go. In a
way, this would be more correct, but it would also probably be very
slow.
I haven't quite decided what to do about this case yet, though it's not
particularly likely to happen in the "production" cases as typically the
functions are split into two parts (hot/cold) instead of one part per
basic block.
This is mainly useful for discontinuous functions because individual
parts of the function will have separate FDE entries, which can begin
many megabytes from the start of the function. However, I'm separating
it out, because it turns out we already have a test case for the
situation where the FDE does not begin exactly at the function boundary.
The test works mostly by accident because the FDE starts only one byte
after the beginning of the function so it doesn't really matter whether
one looks up the unwind row using the function or fde offset. In this
patch, I beef up the test to catch this problem more reliably.
To make this work I've also needed to change a couple of places which
that an unwind plan always has a row at offset zero.
The main change here is that we're now able to correctly look up plans
for these functions. Previously, due to caching, we could end up with
one entry covering most of the address space (because part of the
function was at the beginning and one at the end). Now, we can correctly
recognise that the part in between does not belong to that function, and
we can create a different FuncUnwinders instance for it. It doesn't help
the discontinuous function much (its plan will still be garbled), but
we can at least properly unwind out of the simple functions in between.
Fixing the unwind plans for discontinuous functions requires handling
each unwind source specially, and this setup allows us to make the
transition incrementally.
This test checks the thread backtrace for entries of intermediate frames
that aren't aligned to 16 bytes. In order to do that, it sets a single
breakpoint and makes sure we stop there. It seems sufficient, however,
to check that we hit the breakpoint itself and not which particular
site.
This reverts commit a89e01634fe2e6ce0b967ead24280b6693b523dc.
This is being reverted because it broke the test:
Unwind/trap_frame_sym_ctx.test
/Users/ec2-user/jenkins/workspace/llvm.org/lldb-cmake/llvm-project/lldb/test/Shell/Unwind/trap_frame_sym_ctx.test:21:10: error: CHECK: expected string not found in input
CHECK: frame #2: {{.*}}`main
Currently, our unwinder assumes that the functions are continuous (or at
least, that there are no functions which are "in the middle" of other
functions). Neither of these assumptions is true for functions optimized
by tools like propeller and (probably) bolt.
While there are many things that go wrong for these functions, the
biggest damage is caused by the unwind plan caching code, which
currently takes the maximalist extent of the function and assumes that
the unwind plan we get for that is going to be valid for all code inside
that range. If a part of the function has been moved into a "cold"
section, then the range of the function can be many megabytes, meaning
that any function within that range will probably fail to unwind.
We end up with this maximalist range because the unwinder asks for the
Function object for its range. This is only one of the strategies for
determining the range, but it is the first one -- and also the most
incorrect one. The second choice would is asking the eh_frame section
for the range of the function, and this one returns something reasonable
here (the address range of the current function fragment) -- which it
does because each fragment gets its own eh_frame entry (it has to,
because they have to be continuous).
With this in mind, this patch moves the eh_frame (and debug_frame) to
the front of the queue. I think that preferring this range makes sense
because eh_frame is one of the unwind plans that we return, and some
others (augmented eh_frame) are based on it. In theory this could break
some functions, where the debug info and eh_frame disagree on the extent
of the function (and eh_frame is the one who's wrong), but I don't know
of any such scenarios.
…unction (#91321)"
This reapplies fd1bd53ba5a06f344698a55578f6a5d79c457e30, which was
reverted due to a test failure on aarch64/windows. The failure was
caused by a combination of several factors:
- clang targeting aarch64-windows (unlike msvc, and unlike clang
targeting other aarch64 platforms) defaults to -fomit-frame-pointers
- lldb's code for looking up register values for `<same>` unwind rules
is recursive
- the test binary creates a very long chain of fp-less function frames
(it manages to fit about 22k frames before it blows its stack)
Together, these things have caused lldb to recreate the same deep
recursion when unwinding through this, and blow its own stack as well.
Since lldb frames are larger, about 4k frames like this was sufficient
to trigger the stack overflow.
This version of the patch works around this problem by increasing the
frame size of the test binary, thereby causing it to blow its stack
sooner. This doesn't fix the issue -- the same problem can occur with a
real binary -- but it's not very likely, as it requires an infinite
recursion in a simple (so it doesn't use the frame pointer) function
with a very small frame (so you can fit a lot of them on the stack).
A more principled fix would be to make lldb's lookup code non-recursive,
but I believe that's out of scope for this patch.
The original patch description follows:
A leaf function may not store the link register to stack, but we it can
still end up being a non-zero frame if it gets interrupted by a signal.
Currently, we were unable to unwind past this function because we could
not read the link register value.
To make this work, this patch:
- changes the function-entry unwind plan to include the `fp|lr = <same>`
rules. This in turn necessitated an adjustment in the generic
instruction emulation logic to ensure that `lr=[sp-X]` can override the
`<same>` rule.
- allows the `<same>` rule for pc and lr in all
`m_all_registers_available` frames (and not just frame zero).
The test verifies that we can unwind in a situation like this, and that
the backtrace matches the one we computed before getting a signal.
The stack validation heuristic is counter-productive in this case, as
the unaligned address is most likely the thing that caused the signal in
the first place.
This reverts commit fd1bd53ba5a06f344698a55578f6a5d79c457e30.
TestInterruptBacktrace was broken on AArch64/Windows as a result of this change.
See lldb-aarch64-windows buildbot here:
https://lab.llvm.org/buildbot/#/builders/219/builds/11261
This reverts commit b903badd73a2467fdd4e363231f2bf9b0704b546.
TestInterruptBacktrace was broken on AArch64/Windows as a result of this change.
see lldb-aarch64-windows buildbot here:
https://lab.llvm.org/buildbot/#/builders/219/builds/11261
Convert settings set EXC_BAD_INSTRUCTION to SIGILL so we get uniform
behavior (and can resume the inferior).
Fix a "omitting the parameter name in a function definition is a C23
extension" warning as a drive-by.
A leaf function may not store the link register to stack, but we it can
still end up being a non-zero frame if it gets interrupted by a signal.
Currently, we were unable to unwind past this function because we could
not read the link register value.
To make this work, this patch:
- changes the function-entry unwind plan to include the `fp|lr = <same>`
rules. This in turn necessitated an adjustment in the generic
instruction emulation logic to ensure that `lr=[sp-X]` can override the
`<same>` rule.
- allows the `<same>` rule for pc and lr in all
`m_all_registers_available` frames (and not just frame zero).
The test verifies that we can unwind in a situation like this, and that
the backtrace matches the one we computed before getting a signal.
Currently, lldb's unwinder ignores cfi_restore opcodes for registers
that are not set in the first row of the unwinding info. This prevents
unwinding of failed assertion in Chrome/v8 (https://github.com/v8/v8).
The attached test is an x64 copy of v8's function that failed to unwind
correctly (V8_Fatal).
This patch changes handling of cfi_restore to reset the location if
the first unwind table row does not map the restored register.
Differential Revision: https://reviews.llvm.org/D153043
This was un-XFAILed in `83cb2123be487302070562c45e6eb4955b22c2b4`
due to D144999. Since then D152540 fixed emission of eh_frame's
on Darwin, causing this test to fail again.
Differential Revision: https://reviews.llvm.org/D152806
Details:
D144999 potentially changes the debug format (from compact-unwind to dwarf).
Updated this test to no longer prefer debug-frame over eh-frame to be compatible with the new behaviour
Differential Revision: https://reviews.llvm.org/D152449
Explicitly consider the libraries reported on the initial rendezvous
breakpoint hit added. This is necessary on FreeBSD since the dynamic
loader issues only a single 'consistent' state rendezvous breakpoint hit
for all the libraries present in DT_NEEDED. It is also helpful on Linux
where it ensures that ld-linux is considered loaded as well
as the shared system libraries reported afterwards.
Reenable memory maps on FreeBSD since this fixed the issue triggered
by them.
Differential Revision: https://reviews.llvm.org/D92187
This reverts commit 09b08833f301ea375137931d26b7193101f82ceb.
This code is wrong on Linux, and causes ld-linux and linux-vdso to be
reported twice. I need to work on it more.
Explicitly consider the libraries reported on the initial eTakeSnapshot
action added, through adding them to the added soentry list
in DYLDRendezvous::SaveSOEntriesFromRemote(). This is necessary
on FreeBSD since the dynamic loader issues only a single 'consistent'
state rendezvous breakpoint hit for all the libraries present
in DT_NEEDED (while Linux issues an added-consistent event pair).
Reenable memory maps on FreeBSD since this fixed the issue triggered
by them.
Differential Revision: https://reviews.llvm.org/D92187
clang supports option -fsplit-machine-functions and this test checks if the
backtraces are sane when functions are split.
With -fsplit-machine-functions, a function with profiles can get split into 2
parts, the original function containing hot code and a cold part as determined
by the profile info and the cold cutoff threshold.. The cold part gets the
".cold" suffix to disambiguate its symbol from the hot part and can be placed
arbitrarily in the address space.
This test checks if the back-trace looks correct when the cold part is executed.
Differential Revision: https://reviews.llvm.org/D90081
The test reorders the basic blocks to be dis-contiguous in the address space and checks if the back trace contains the right symbol.
Reviewed By: labath
Differential Revision: https://reviews.llvm.org/D89179
The test fails on Darwin because a different Asynchronous UnwindPlan is
chosen:
Asynchronous (not restricted to call-sites) UnwindPlan is 'assembly
insn profiling'`
instead of what the test expects:
Asynchronous (not restricted to call-sites) UnwindPlan is 'eh_frame
CFI'
Summary:
This fixes a bug in the logic for choosing the unwind plan. Based on the
comment in UnwindAssembly-x86, the intention was that a plan which
describes the function epilogue correctly does not need to be augmented
(and it should be used directly). However, the way this was implemented
(by returning false) meant that the higher level code
(FuncUnwinders::GetEHFrameAugmentedUnwindPlan) interpreted this as a
failure to produce _any_ plan and proceeded with other fallback options.
The fallback usually chosed for "asynchronous" plans was the
"instruction emulation" plan, which tended to fall over on certain
functions with multiple epilogues (that's a separate bug).
This patch simply changes the function to return true, which signals the
caller that the unmodified plan is ready to be used.
The attached test case demonstrates the case where we would previously
fall back to the instruction emulation plan, and unwind incorrectly --
the test asserts that the "augmented" eh_frame plan is used, and that
the unwind is correct.
Reviewers: jasonmolenda, jankratochvil
Subscribers: davide, echristo, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D82378
The llvm DWARFExpression dump is nearly identical, but better -- for
example it does print a spurious space after zero-argument expressions.
Some parts of our code (variable locations) have been already switched
to llvm-based expression dumping. This switches the remainder: unwind
plans and some unit tests.
We have the option to stop running commands in batch mode when an error
occurs. When that happens we should exit the driver with a non-zero exit
code.
Differential revision: https://reviews.llvm.org/D78825
lld in 2bfee35 started emitting relocations for some intra-section jumps
between global symbols. This shifted the code around a bit, invalidating
text expectations.
Change the symbols to local to keep the previous behavior.
D71372 introduced: `Unwind/thread-step-out-ret-addr-check.test` failing on
Fedora 30 Linux x86_64.
[lldb] Add additional validation on return address in 'thread step-out'
https://reviews.llvm.org/D71372
One problem is the underscored `_nonstandard_stub` in the `.s` file but not in
the LLDB command:
(lldb) breakpoint set -n nonstandard_stub
Breakpoint 1: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
(lldb) process launch
Process 21919 exited with status = 0 (0x00000000)
Process 21919 launched: '/home/jkratoch/redhat/llvm-monorepo-clangassert/tools/lldb/test/Unwind/Output/thread-step-out-ret-addr-check.test.tmp' (x86_64)
(lldb) thread step-out
error: invalid thread
(lldb) _
Another problem is that Fedora Linux has executable stack by default and all
programs indicate non-executable stack by `PT_GNU_STACK`, after fixing the
underscore I was getting:
(lldb) thread step-out
Process 22294 exited with status = 0 (0x00000000)
(lldb) _
A different approach was tried as:
[lldb] Refactor thread-step-out-ret-addr-check test to use .data instead of stack variable
https://reviews.llvm.org/D71789
Differential revision: https://reviews.llvm.org/D71784
Previously, if the current function had a nonstandard stack layout/ABI, and had a valid
data pointer in the location where the return address is usually located, data corruption
would occur when the breakpoint was written. This could lead to an incorrectly reported
crash or silent corruption of the program's state. Now, if the above check fails, the command safely aborts.
Differential Revision: https://reviews.llvm.org/D71372
Summary:
This patch addresses an ambiguity in how our existing tests invoke the
compiler. Roughly two thirds of our current "shell" tests invoke the
compiler to build the executables for the host. However, there is also
a significant number of tests which don't build a host binary (because
they don't need to run it) and instead they hardcode a certain target.
We also have code which adds a bunch of default arguments to the %clang
substitutions. However, most of these arguments only really make sense
for the host compilation. So far, this has worked mostly ok, because the
arguments we were adding were not conflicting with the target-hardcoding
tests (though they did provoke an occasional "argument unused" warning).
However, this started to break down when we wanted to use
target-hardcoding clang-cl tests (D69031) because clang-cl has a
substantially different command line, and it was getting very confused
by some of the arguments we were adding on non-windows hosts.
This patch avoid this problem by creating separate %clang(xx,_cl)_host
substutitions, which are specifically meant to be used for compiling
host binaries. All funny host-specific options are moved there. To
ensure that the regular %clang substitutions are not used for compiling
host binaries (skipping the extra arguments) I employ a little
hac^H^H^Htrick -- I add an invalid --target argument to the %clang
substitution, which means that one has to use an explicit --target in
order for the compilation to succeed.
Reviewers: JDevlieghere, aprantl, mstorsjo, espindola
Subscribers: emaste, arichardson, MaskRay, jfb, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D69619