[Lldb-commits] [lldb] 1758953 - [lldb-vscode] Fix focus thread when previous thread exits
Ted Woodward via lldb-commits
lldb-commits at lists.llvm.org
Wed Sep 15 16:09:46 PDT 2021
Author: Ted Woodward
Date: 2021-09-15T18:09:32-05:00
New Revision: 17589538aaef2b5ae27a0bfeb4346aff433aa59d
URL: https://github.com/llvm/llvm-project/commit/17589538aaef2b5ae27a0bfeb4346aff433aa59d
DIFF: https://github.com/llvm/llvm-project/commit/17589538aaef2b5ae27a0bfeb4346aff433aa59d.diff
LOG: [lldb-vscode] Fix focus thread when previous thread exits
The thread that Visual Studio Code displays on a stop is called the focus thread. When the previous focus thread exits and we stop in a new thread, lldb-vscode does not tell vscode to set the new thread as the focus thread, so it selects the first thread in the thread list.
This patch changes lldb-vscode to tell vscode that the new thread is the focus thread. It also includes a test that verifies the DAP stop message for this case contains the correct values.
Reviewed By: clayborg, wallace
Differential Revision: https://reviews.llvm.org/D109633
Added:
lldb/test/API/tools/lldb-vscode/correct-thread/Makefile
lldb/test/API/tools/lldb-vscode/correct-thread/TestVSCode_correct_thread.py
lldb/test/API/tools/lldb-vscode/correct-thread/main.c
Modified:
lldb/tools/lldb-vscode/lldb-vscode.cpp
Removed:
################################################################################
diff --git a/lldb/test/API/tools/lldb-vscode/correct-thread/Makefile b/lldb/test/API/tools/lldb-vscode/correct-thread/Makefile
new file mode 100644
index 0000000000000..121868fa8ec33
--- /dev/null
+++ b/lldb/test/API/tools/lldb-vscode/correct-thread/Makefile
@@ -0,0 +1,4 @@
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -lpthread
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-vscode/correct-thread/TestVSCode_correct_thread.py b/lldb/test/API/tools/lldb-vscode/correct-thread/TestVSCode_correct_thread.py
new file mode 100644
index 0000000000000..4b7b03745692e
--- /dev/null
+++ b/lldb/test/API/tools/lldb-vscode/correct-thread/TestVSCode_correct_thread.py
@@ -0,0 +1,47 @@
+"""
+Test lldb-vscode setBreakpoints request
+"""
+
+from __future__ import print_function
+
+import unittest2
+import vscode
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbvscode_testcase
+
+
+class TestVSCode_correct_thread(lldbvscode_testcase.VSCodeTestCaseBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfWindows
+ @skipIfRemote
+ def test_correct_thread(self):
+ '''
+ Tests that the correct thread is selected if we continue from
+ a thread that goes away and hit a breakpoint in another thread.
+ In this case, the selected thread should be the thread that
+ just hit the breakpoint, and not the first thread in the list.
+ '''
+ program = self.getBuildArtifact("a.out")
+ self.build_and_launch(program)
+ source = 'main.c'
+ breakpoint_line = line_number(source, '// break here')
+ lines = [breakpoint_line]
+ # Set breakpoint in the thread function
+ breakpoint_ids = self.set_source_breakpoints(source, lines)
+ self.assertEqual(len(breakpoint_ids), len(lines),
+ "expect correct number of breakpoints")
+ self.continue_to_breakpoints(breakpoint_ids)
+ # We're now stopped at the breakpoint in the first thread, thread #2.
+ # Continue to join the first thread and hit the breakpoint in the
+ # second thread, thread #3.
+ self.vscode.request_continue()
+ stopped_event = self.vscode.wait_for_stopped()
+ # Verify that the description is the relevant breakpoint,
+ # preserveFocusHint is False and threadCausedFocus is True
+ self.assertTrue(stopped_event[0]['body']['description'].startswith('breakpoint %s.' % breakpoint_ids[0]))
+ self.assertFalse(stopped_event[0]['body']['preserveFocusHint'])
+ self.assertTrue(stopped_event[0]['body']['threadCausedFocus'])
diff --git a/lldb/test/API/tools/lldb-vscode/correct-thread/main.c b/lldb/test/API/tools/lldb-vscode/correct-thread/main.c
new file mode 100644
index 0000000000000..157c3f994db1e
--- /dev/null
+++ b/lldb/test/API/tools/lldb-vscode/correct-thread/main.c
@@ -0,0 +1,23 @@
+#include <pthread.h>
+#include <stdio.h>
+
+int state_var;
+
+void *thread (void *in)
+{
+ state_var++; // break here
+ return NULL;
+}
+
+int main(int argc, char **argv)
+{
+ pthread_t t1, t2;
+
+ pthread_create(&t1, NULL, *thread, NULL);
+ pthread_join(t1, NULL);
+ pthread_create(&t2, NULL, *thread, NULL);
+ pthread_join(t2, NULL);
+
+ printf("state_var is %d\n", state_var);
+ return 0;
+}
diff --git a/lldb/tools/lldb-vscode/lldb-vscode.cpp b/lldb/tools/lldb-vscode/lldb-vscode.cpp
index 59d8debe6378c..5c237c00deabe 100644
--- a/lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ b/lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -232,13 +232,17 @@ void SendThreadStoppedEvent() {
// set it as the focus thread if below if needed.
lldb::tid_t first_tid_with_reason = LLDB_INVALID_THREAD_ID;
uint32_t num_threads_with_reason = 0;
+ bool focus_thread_exists = false;
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
const lldb::tid_t tid = thread.GetThreadID();
const bool has_reason = ThreadHasStopReason(thread);
// If the focus thread doesn't have a stop reason, clear the thread ID
- if (tid == g_vsc.focus_tid && !has_reason)
- g_vsc.focus_tid = LLDB_INVALID_THREAD_ID;
+ if (tid == g_vsc.focus_tid) {
+ focus_thread_exists = true;
+ if (!has_reason)
+ g_vsc.focus_tid = LLDB_INVALID_THREAD_ID;
+ }
if (has_reason) {
++num_threads_with_reason;
if (first_tid_with_reason == LLDB_INVALID_THREAD_ID)
@@ -246,10 +250,10 @@ void SendThreadStoppedEvent() {
}
}
- // We will have cleared g_vsc.focus_tid if he focus thread doesn't
- // have a stop reason, so if it was cleared, or wasn't set, then set the
- // focus thread to the first thread with a stop reason.
- if (g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
+ // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+ // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
+ // then set the focus thread to the first thread with a stop reason.
+ if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
g_vsc.focus_tid = first_tid_with_reason;
// If no threads stopped with a reason, then report the first one so
More information about the lldb-commits
mailing list