Skip to content

[lldb] Fix lock inversion between statusline mutex and output mutex #135956

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 17, 2025

Conversation

JDevlieghere
Copy link
Member

@JDevlieghere JDevlieghere commented Apr 16, 2025

Fix a deadlock between the statusline mutex (in Debugger) and the output
file mutex (in LockedStreamFile). The deadlock occurs when the main
thread is calling the statusline callback while holding the output mutex
in Editline, while the default event thread is trying to update the
statusline.

Extend the uncritical section so we can redraw the statusline there.
The loop in Editline::GetCharacter should be unnecessary. It would only
loop if we had a successful read with length zero, which shouldn't be
possible or when we can't convert a partial UTF-8 character, in which
case we bail out.

rdar://149251156

@llvmbot
Copy link
Member

llvmbot commented Apr 16, 2025

@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)

Changes

Fix a deadlock between the statusline mutex (in Debugger) and the output file mutex (in LockedStreamFile). The deadlock occurs when the main thread is calling the statusline callback while holding the output mutex in Editline, while the default event thread is trying to update the stausline.

rdar://149251156


Full diff: https://github.com/llvm/llvm-project/pull/135956.diff

1 Files Affected:

  • (modified) lldb/source/Host/common/Editline.cpp (+4-1)
diff --git a/lldb/source/Host/common/Editline.cpp b/lldb/source/Host/common/Editline.cpp
index 29abaf7c65f28..6900da9909eb8 100644
--- a/lldb/source/Host/common/Editline.cpp
+++ b/lldb/source/Host/common/Editline.cpp
@@ -567,8 +567,11 @@ int Editline::GetCharacter(EditLineGetCharType *c) {
     m_needs_prompt_repaint = false;
   }
 
-  if (m_redraw_callback)
+  if (m_redraw_callback) {
+    m_locked_output.reset();
     m_redraw_callback();
+    m_locked_output.emplace(m_output_stream_sp->Lock());
+  }
 
   if (m_multiline_enabled) {
     // Detect when the number of rows used for this input line changes due to

Fix a deadlock between the statusline mutex (in Debugger) and the output
file mutex (in LockedStreamFile). The deadlock occurs when the main
thread is calling the statusline callback while holding the output mutex
in Editline, while the default event thread is trying to update the
statusline.

Extend the uncritical section so we can redraw the statusline there.
The loop in Editline::GetCharacter should be unnecessary. It would only
loop if we had a successful read with length zero, which shouldn't be
possible or when we can't convert a partial UTF-8 character, in which
case we bail out.
@JDevlieghere JDevlieghere changed the title [lldb] Fix deadlock between statusline and output mutex [lldb] Fix lock inversion between statusline mutex and output mutex Apr 16, 2025
Copy link
Collaborator

@jasonmolenda jasonmolenda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks!

@JDevlieghere JDevlieghere merged commit 8311620 into llvm:main Apr 17, 2025
10 checks passed
@JDevlieghere JDevlieghere deleted the statusline-deadlock branch April 17, 2025 15:57
JDevlieghere added a commit to swiftlang/llvm-project that referenced this pull request Apr 22, 2025
…lvm#135956)

Fix a deadlock between the statusline mutex (in Debugger) and the output
file mutex (in LockedStreamFile). The deadlock occurs when the main
thread is calling the statusline callback while holding the output mutex
in Editline, while the default event thread is trying to update the
statusline.

Extend the uncritical section so we can redraw the statusline there.
The loop in Editline::GetCharacter should be unnecessary. It would only
loop if we had a successful read with length zero, which shouldn't be
possible or when we can't convert a partial UTF-8 character, in which
case we bail out.

rdar://149251156
(cherry picked from commit 8311620)
JDevlieghere added a commit to swiftlang/llvm-project that referenced this pull request Apr 23, 2025
…-5f99e0d4b9ea-83116209331a

[🍒 swift/release/6.2] [lldb] Fix lock inversion between statusline mutex and output mutex (llvm#135956)
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…lvm#135956)

Fix a deadlock between the statusline mutex (in Debugger) and the output
file mutex (in LockedStreamFile). The deadlock occurs when the main
thread is calling the statusline callback while holding the output mutex
in Editline, while the default event thread is trying to update the
statusline.

Extend the uncritical section so we can redraw the statusline there.
The loop in Editline::GetCharacter should be unnecessary. It would only
loop if we had a successful read with length zero, which shouldn't be
possible or when we can't convert a partial UTF-8 character, in which
case we bail out.

rdar://149251156
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…lvm#135956)

Fix a deadlock between the statusline mutex (in Debugger) and the output
file mutex (in LockedStreamFile). The deadlock occurs when the main
thread is calling the statusline callback while holding the output mutex
in Editline, while the default event thread is trying to update the
statusline.

Extend the uncritical section so we can redraw the statusline there.
The loop in Editline::GetCharacter should be unnecessary. It would only
loop if we had a successful read with length zero, which shouldn't be
possible or when we can't convert a partial UTF-8 character, in which
case we bail out.

rdar://149251156
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants