<feed xmlns='http://www.w3.org/2005/Atom'>
<title>llvm-project.git/lldb/source/Symbol/UnwindTable.cpp, branch users/nico/python-2</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/'/>
<entry>
<title>[lldb] Parse DWARF CFI for discontinuous functions (#137006)</title>
<updated>2025-05-07T13:04:22+00:00</updated>
<author>
<name>Pavel Labath</name>
<email>pavel@labath.sk</email>
</author>
<published>2025-05-07T13:04:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=d865f32fe820f543f0a53bfeba08774f2c270589'/>
<id>d865f32fe820f543f0a53bfeba08774f2c270589</id>
<content type='text'>
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.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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.</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Teach FuncUnwinders about discontinuous functions (#133072)</title>
<updated>2025-03-27T11:51:20+00:00</updated>
<author>
<name>Pavel Labath</name>
<email>pavel@labath.sk</email>
</author>
<published>2025-03-27T11:51:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=17aca79d98d92510d131c4766a040b02adf6c4b8'/>
<id>17aca79d98d92510d131c4766a040b02adf6c4b8</id>
<content type='text'>
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.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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.</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Clear cached unwind plans when adding symbols (#125839)</title>
<updated>2025-02-07T11:52:21+00:00</updated>
<author>
<name>Pavel Labath</name>
<email>pavel@labath.sk</email>
</author>
<published>2025-02-07T11:52:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=83ba3740bf51347307494d013099e392c310e32b'/>
<id>83ba3740bf51347307494d013099e392c310e32b</id>
<content type='text'>
PR #86603 broke unwinding in for unwind info added via "target symbols
add". #86770 attempted to fix this, but the fix was only partial -- it
accepted new sources of unwind information, but didn't take into account
that the symbol file can alter what lldb percieves as function
boundaries.

A stripped file will not contain information about private
(non-exported) symbols, which will make the public symbols appear very
large. If lldb tries to unwind from such a function before symbols are
added, then the cached unwind plan will prevent new (correct) unwind
plans from being created.

target-symbols-add-unwind.test might have caught this, were it not for
the fact that the "image show-unwind" command does *not* use cached
unwind information (it recomputes it from scratch).

The changes in this patch come in three pieces:
- Clear cached unwind plans when adding symbols. Since the symbol
boundaries can change, we cannot trust anything we've computed
previously.
- Add a flag to "image show-unwind" to display the cached unwind
information (mainly for the use in the test, but I think it's also
generally useful).
- Rewrite the test to better and more reliably simulate the real-world
scenario: I've swapped the running process for a core (minidump) file so
it can run anywhere; used the caching version of the show-unwind
command; and swapped C for assembly to better control the placement of
symbols</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
PR #86603 broke unwinding in for unwind info added via "target symbols
add". #86770 attempted to fix this, but the fix was only partial -- it
accepted new sources of unwind information, but didn't take into account
that the symbol file can alter what lldb percieves as function
boundaries.

A stripped file will not contain information about private
(non-exported) symbols, which will make the public symbols appear very
large. If lldb tries to unwind from such a function before symbols are
added, then the cached unwind plan will prevent new (correct) unwind
plans from being created.

target-symbols-add-unwind.test might have caught this, were it not for
the fact that the "image show-unwind" command does *not* use cached
unwind information (it recomputes it from scratch).

The changes in this patch come in three pieces:
- Clear cached unwind plans when adding symbols. Since the symbol
boundaries can change, we cannot trust anything we've computed
previously.
- Add a flag to "image show-unwind" to display the cached unwind
information (mainly for the use in the test, but I think it's also
generally useful).
- Rewrite the test to better and more reliably simulate the real-world
scenario: I've swapped the running process for a core (minidump) file so
it can run anywhere; used the caching version of the show-unwind
command; and swapped C for assembly to better control the placement of
symbols</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "[lldb] Improve unwinding for discontinuous functions (#111409)"</title>
<updated>2024-10-14T22:27:05+00:00</updated>
<author>
<name>Shubham Sandeep Rastogi</name>
<email>srastogi22@apple.com</email>
</author>
<published>2024-10-14T22:25:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=d8de2391eb014fb3f750f4c38abc101edc1e2cc2'/>
<id>d8de2391eb014fb3f750f4c38abc101edc1e2cc2</id>
<content type='text'>
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
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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
</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Improve unwinding for discontinuous functions (#111409)</title>
<updated>2024-10-14T16:56:37+00:00</updated>
<author>
<name>Pavel Labath</name>
<email>pavel@labath.sk</email>
</author>
<published>2024-10-14T16:56:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=a89e01634fe2e6ce0b967ead24280b6693b523dc'/>
<id>a89e01634fe2e6ce0b967ead24280b6693b523dc</id>
<content type='text'>
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.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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.</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Change Module to have a concrete UnwindTable, update (#101130)</title>
<updated>2024-08-02T00:43:25+00:00</updated>
<author>
<name>Jason Molenda</name>
<email>jmolenda@apple.com</email>
</author>
<published>2024-08-02T00:43:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=7ad073a45b411d3752668dff61963d356c98145d'/>
<id>7ad073a45b411d3752668dff61963d356c98145d</id>
<content type='text'>
Currently a Module has a std::optional&lt;UnwindTable&gt; which is created
when the UnwindTable is requested from outside the Module. The idea is
to delay its creation until the Module has an ObjectFile initialized,
which will have been done by the time we're doing an unwind.

However, Module::GetUnwindTable wasn't doing any locking, so it was
possible for two threads to ask for the UnwindTable for the first time,
one would be created and returned while another thread would create one,
destroy the first in the process of emplacing it. It was an uncommon
crash, but it was possible.

Grabbing the Module's mutex would be one way to address it, but when
loading ELF binaries, we start creating the SymbolTable on one thread
(ObjectFileELF) grabbing the Module's mutex, and then spin up worker
threads to parse the individual DWARF compilation units, which then try
to also get the UnwindTable and deadlock if they try to get the Module's
mutex.

This changes Module to have a concrete UnwindTable as an ivar, and when
it adds an ObjectFile or SymbolFileVendor, it will call the Update
method on it, which will re-evaluate which sections exist in the
ObjectFile/SymbolFile. UnwindTable used to have an Initialize method
which set all the sections, and an Update method which would set some of
them if they weren't set. I unified these with the Initialize method
taking a `force` option to re-initialize the section pointers even if
they had been done already before.

This is addressing a rare crash report we've received, and also a
failure Adrian spotted on the -fsanitize=address CI bot last week, it's
still uncommon with ASAN but it can happen with the standard testsuite.

rdar://128876433</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Currently a Module has a std::optional&lt;UnwindTable&gt; which is created
when the UnwindTable is requested from outside the Module. The idea is
to delay its creation until the Module has an ObjectFile initialized,
which will have been done by the time we're doing an unwind.

However, Module::GetUnwindTable wasn't doing any locking, so it was
possible for two threads to ask for the UnwindTable for the first time,
one would be created and returned while another thread would create one,
destroy the first in the process of emplacing it. It was an uncommon
crash, but it was possible.

Grabbing the Module's mutex would be one way to address it, but when
loading ELF binaries, we start creating the SymbolTable on one thread
(ObjectFileELF) grabbing the Module's mutex, and then spin up worker
threads to parse the individual DWARF compilation units, which then try
to also get the UnwindTable and deadlock if they try to get the Module's
mutex.

This changes Module to have a concrete UnwindTable as an ivar, and when
it adds an ObjectFile or SymbolFileVendor, it will call the Update
method on it, which will re-evaluate which sections exist in the
ObjectFile/SymbolFile. UnwindTable used to have an Initialize method
which set all the sections, and an Update method which would set some of
them if they weren't set. I unified these with the Initialize method
taking a `force` option to re-initialize the section pointers even if
they had been done already before.

This is addressing a rare crash report we've received, and also a
failure Adrian spotted on the -fsanitize=address CI bot last week, it's
still uncommon with ASAN but it can happen with the standard testsuite.

rdar://128876433</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Revive shell test after updating UnwindTable (#86770)</title>
<updated>2024-03-27T16:25:46+00:00</updated>
<author>
<name>Jason Molenda</name>
<email>jmolenda@apple.com</email>
</author>
<published>2024-03-27T16:25:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=6a0ec8e25cba9d398cf525889c53835cf40247a3'/>
<id>6a0ec8e25cba9d398cf525889c53835cf40247a3</id>
<content type='text'>
In
     commit 2f63718f8567413a1c596bda803663eb58d6da5a
     Author: Jason Molenda &lt;jmolenda@apple.com&gt;
     Date:   Tue Mar 26 09:07:15 2024 -0700

[lldb] Don't clear a Module's UnwindTable when adding a SymbolFile
(#86603)

I stopped clearing a Module's UnwindTable when we add a SymbolFile to
avoid the memory management problems with adding a symbol file
asynchronously while the UnwindTable is being accessed on another
thread. This broke the target-symbols-add-unwind.test shell test on
Linux which removes the DWARF debub_frame section from a binary, loads
it, then loads the unstripped binary with the DWARF debug_frame section
and checks that the UnwindPlans for a function include debug_frame.

I originally decided that I was willing to sacrifice the possiblity of
additional unwind sources from a symbol file because we rely on assembly
emulation so heavily, they're rarely critical. But there are targets
where we we don't have emluation and rely on things like DWARF
debug_frame a lot more, so this probably wasn't a good choice.

This patch adds a new UnwindTable::Update method which looks for any new
sources of unwind information and adds it to the UnwindTable, and calls
that after a new SymbolFile has been added to a Module.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In
     commit 2f63718f8567413a1c596bda803663eb58d6da5a
     Author: Jason Molenda &lt;jmolenda@apple.com&gt;
     Date:   Tue Mar 26 09:07:15 2024 -0700

[lldb] Don't clear a Module's UnwindTable when adding a SymbolFile
(#86603)

I stopped clearing a Module's UnwindTable when we add a SymbolFile to
avoid the memory management problems with adding a symbol file
asynchronously while the UnwindTable is being accessed on another
thread. This broke the target-symbols-add-unwind.test shell test on
Linux which removes the DWARF debub_frame section from a binary, loads
it, then loads the unstripped binary with the DWARF debug_frame section
and checks that the UnwindPlans for a function include debug_frame.

I originally decided that I was willing to sacrifice the possiblity of
additional unwind sources from a symbol file because we rely on assembly
emulation so heavily, they're rarely critical. But there are targets
where we we don't have emluation and rely on things like DWARF
debug_frame a lot more, so this probably wasn't a good choice.

This patch adds a new UnwindTable::Update method which looks for any new
sources of unwind information and adds it to the UnwindTable, and calls
that after a new SymbolFile has been added to a Module.</pre>
</div>
</content>
</entry>
<entry>
<title>Re-land "[lldb] Expose a const iterator for SymbolContextList"</title>
<updated>2023-05-05T18:19:21+00:00</updated>
<author>
<name>Alex Langford</name>
<email>alangford@apple.com</email>
</author>
<published>2023-05-05T01:19:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=e9eaf7b430ee69e8ef145884cbc8fa3ef8bd3237'/>
<id>e9eaf7b430ee69e8ef145884cbc8fa3ef8bd3237</id>
<content type='text'>
Re-lands 04aa943be8ed5c03092e2a90112ac638360ec253 with modifications
to fix tests.
I originally reverted this because it caused a test to fail on Linux.
The problem was that I inverted a condition on accident.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Re-lands 04aa943be8ed5c03092e2a90112ac638360ec253 with modifications
to fix tests.
I originally reverted this because it caused a test to fail on Linux.
The problem was that I inverted a condition on accident.
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "[lldb] Expose a const iterator for SymbolContextList"</title>
<updated>2023-05-04T23:49:30+00:00</updated>
<author>
<name>Alex Langford</name>
<email>alangford@apple.com</email>
</author>
<published>2023-05-04T23:49:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=3d6073a9c33005abf8c6fc074e434c90b36dccb9'/>
<id>3d6073a9c33005abf8c6fc074e434c90b36dccb9</id>
<content type='text'>
This reverts commit 04aa943be8ed5c03092e2a90112ac638360ec253.

This broke the debian buildbot and I'm not sure why. Reverting so I can
investigate.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit 04aa943be8ed5c03092e2a90112ac638360ec253.

This broke the debian buildbot and I'm not sure why. Reverting so I can
investigate.
</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Expose a const iterator for SymbolContextList</title>
<updated>2023-05-04T23:36:44+00:00</updated>
<author>
<name>Alex Langford</name>
<email>alangford@apple.com</email>
</author>
<published>2023-05-04T20:26:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=04aa943be8ed5c03092e2a90112ac638360ec253'/>
<id>04aa943be8ed5c03092e2a90112ac638360ec253</id>
<content type='text'>
There are many situations where we'll iterate over a SymbolContextList
with the pattern:
```
SymbolContextList sc_list;
// Fill in sc_list here
for (auto i = 0; i &lt; sc_list.GetSize(); i++) {
  SymbolContext sc;
  sc_list.GetSymbolAtContext(i, sc);

  // Do work with sc
}
```
Adding an iterator to iterate over the instances directly means we don't
have to do bounds checking or create a copy of every element of the
SymbolContextList.

Differential Revision: https://reviews.llvm.org/D149900
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
There are many situations where we'll iterate over a SymbolContextList
with the pattern:
```
SymbolContextList sc_list;
// Fill in sc_list here
for (auto i = 0; i &lt; sc_list.GetSize(); i++) {
  SymbolContext sc;
  sc_list.GetSymbolAtContext(i, sc);

  // Do work with sc
}
```
Adding an iterator to iterate over the instances directly means we don't
have to do bounds checking or create a copy of every element of the
SymbolContextList.

Differential Revision: https://reviews.llvm.org/D149900
</pre>
</div>
</content>
</entry>
</feed>
