[Lldb-commits] [PATCH] D114861: Don't consider frames with different PCs as a loop
Tatyana Krasnukha via Phabricator via lldb-commits
lldb-commits at lists.llvm.org
Wed Dec 1 03:49:57 PST 2021
tatyana-krasnukha created this revision.
tatyana-krasnukha added reviewers: labath, jasonmolenda.
tatyana-krasnukha added a project: LLDB.
Herald added a subscriber: JDevlieghere.
tatyana-krasnukha requested review of this revision.
Herald added a subscriber: lldb-commits.
A compiler can produce FDE records with no CFA offset if it doesn't save anything on stack for a frame. This is what the MetaWare compiler does for some functions - it doesn't update CFA since it saves return address to a register.
In this case LLDB fails to unwind the stack complaining about a loop. This patch checks also the return addresses of the frames, there is no loop if they differ.
This is also consistent with how UnwindLLDB::GetOneMoreFrame identifies infinite loops.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D114861
Files:
lldb/source/Target/RegisterContextUnwind.cpp
Index: lldb/source/Target/RegisterContextUnwind.cpp
===================================================================
--- lldb/source/Target/RegisterContextUnwind.cpp
+++ lldb/source/Target/RegisterContextUnwind.cpp
@@ -690,28 +690,29 @@
// -- or even more devious, we can actually oscillate between two CFA values.
// Detect that here and break out to avoid a possible infinite loop in lldb
// trying to unwind the stack. To detect when we have the same CFA value
- // multiple times, we compare the
- // CFA of the current
- // frame with the 2nd next frame because in some specail case (e.g. signal
- // hanlders, hand written assembly without ABI compliance) we can have 2
- // frames with the same
- // CFA (in theory we
- // can have arbitrary number of frames with the same CFA, but more then 2 is
- // very very unlikely)
+ // multiple times, we compare the CFA of the current frame with the 2nd next
+ // frame because in some specail case (e.g. signal hanlders, hand written
+ // assembly without ABI compiance) we can have 2 frames with the same CFA (in
+ // theory we can have arbitrary number of frames with the same CFA, but more
+ // then 2 is very very unlikely).
RegisterContextUnwind::SharedPtr next_frame = GetNextFrame();
- if (next_frame) {
- RegisterContextUnwind::SharedPtr next_next_frame =
- next_frame->GetNextFrame();
- addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS;
- if (next_next_frame && next_next_frame->GetCFA(next_next_frame_cfa)) {
- if (next_next_frame_cfa == m_cfa) {
- // We have a loop in the stack unwind
- return true;
- }
- }
- }
- return false;
+ if (!next_frame)
+ return false;
+
+ RegisterContextUnwind::SharedPtr next_next_frame = next_frame->GetNextFrame();
+ if (!next_next_frame)
+ return false;
+
+ // Since the return address value can be restored not only from the stack but
+ // also from a register, don't consider frames with the same CFAs and different
+ // PCs as a loop.
+ if (m_current_pc.IsValid() && (m_current_pc != next_next_frame->GetPC()))
+ return false;
+
+ addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS;
+ return next_next_frame->GetCFA(next_next_frame_cfa) &&
+ next_next_frame_cfa == m_cfa;
}
bool RegisterContextUnwind::IsFrameZero() const { return m_frame_number == 0; }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D114861.390594.patch
Type: text/x-patch
Size: 2358 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20211201/623ff52b/attachment-0001.bin>
More information about the lldb-commits
mailing list