[Lldb-commits] [lldb] When running OS Plugins from dSYM's, make sure start state is correct (PR #146441)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Jul 11 09:34:33 PDT 2025
https://github.com/jimingham updated https://github.com/llvm/llvm-project/pull/146441
>From 8a8e86d72e9d130f513d91fbf75d7631077bf930 Mon Sep 17 00:00:00 2001
From: Jim Ingham <jingham at apple.com>
Date: Thu, 12 Jun 2025 11:16:36 -0700
Subject: [PATCH 1/4] When running OS Plugins from dSYM's, make sure the OS
plugin callbacks see the correct process state.
---
lldb/include/lldb/Host/HostThread.h | 6 +
lldb/include/lldb/Target/Process.h | 2 +
lldb/source/Target/Process.cpp | 29 ++--
lldb/source/Target/StackFrameList.cpp | 2 +-
.../python_os_plugin/operating_system.py | 4 +
.../os_plugin_in_dsym/Makefile | 4 +
.../os_plugin_in_dsym/TestOSIndSYM.py | 145 ++++++++++++++++++
.../python_os_plugin/os_plugin_in_dsym/main.c | 10 ++
.../os_plugin_in_dsym/operating_system.py | 78 ++++++++++
9 files changed, 269 insertions(+), 11 deletions(-)
create mode 100644 lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/Makefile
create mode 100644 lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/TestOSIndSYM.py
create mode 100644 lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/main.c
create mode 100644 lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/operating_system.py
diff --git a/lldb/include/lldb/Host/HostThread.h b/lldb/include/lldb/Host/HostThread.h
index d3477e115e2d8..d8b3610210aac 100644
--- a/lldb/include/lldb/Host/HostThread.h
+++ b/lldb/include/lldb/Host/HostThread.h
@@ -10,6 +10,7 @@
#define LLDB_HOST_HOSTTHREAD_H
#include "lldb/Host/HostNativeThreadForward.h"
+#include "lldb/Host/HostNativeThreadBase.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-types.h"
@@ -42,6 +43,11 @@ class HostThread {
lldb::thread_result_t GetResult() const;
bool EqualsThread(lldb::thread_t thread) const;
+
+ bool HasThread() const {
+ if (!m_native_thread)
+ return false;
+ return m_native_thread->GetSystemHandle() != LLDB_INVALID_HOST_THREAD ; }
private:
std::shared_ptr<HostNativeThreadBase> m_native_thread;
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index a8892e9c43225..1329abba9b17b 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -2546,6 +2546,8 @@ void PruneThreadPlans();
ProcessRunLock &GetRunLock();
bool CurrentThreadIsPrivateStateThread();
+
+ bool CurrentThreadPosesAsPrivateStateThread();
virtual Status SendEventData(const char *data) {
return Status::FromErrorString(
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index bba1230c79920..9cdef7ef524fc 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -1271,7 +1271,7 @@ uint32_t Process::AssignIndexIDToThread(uint64_t thread_id) {
}
StateType Process::GetState() {
- if (CurrentThreadIsPrivateStateThread())
+ if (CurrentThreadPosesAsPrivateStateThread())
return m_private_state.GetValue();
else
return m_public_state.GetValue();
@@ -3144,16 +3144,17 @@ void Process::CompleteAttach() {
}
}
- if (!m_os_up) {
- LoadOperatingSystemPlugin(false);
- if (m_os_up) {
- // Somebody might have gotten threads before now, but we need to force the
- // update after we've loaded the OperatingSystem plugin or it won't get a
- // chance to process the threads.
- m_thread_list.Clear();
- UpdateThreadListIfNeeded();
- }
+ if (!m_os_up)
+ LoadOperatingSystemPlugin(false);
+
+ if (m_os_up) {
+ // Somebody might have gotten threads before now, but we need to force the
+ // update after we've loaded the OperatingSystem plugin or it won't get a
+ // chance to process the threads.
+ m_thread_list.Clear();
+ UpdateThreadListIfNeeded();
}
+
// Figure out which one is the executable, and set that in our target:
ModuleSP new_executable_module_sp;
for (ModuleSP module_sp : GetTarget().GetImages().Modules()) {
@@ -5856,6 +5857,14 @@ bool Process::CurrentThreadIsPrivateStateThread()
return m_private_state_thread.EqualsThread(Host::GetCurrentThread());
}
+bool Process::CurrentThreadPosesAsPrivateStateThread()
+{
+ // If we haven't started up the private state thread yet, then whatever thread
+ // is fetching this event should be temporarily the private state thread.
+ if (!m_private_state_thread.HasThread())
+ return true;
+ return m_private_state_thread.EqualsThread(Host::GetCurrentThread());
+}
void Process::Flush() {
m_thread_list.Flush();
diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp
index 9c6208e9e0a65..16cd2548c2784 100644
--- a/lldb/source/Target/StackFrameList.cpp
+++ b/lldb/source/Target/StackFrameList.cpp
@@ -723,7 +723,7 @@ void StackFrameList::SelectMostRelevantFrame() {
// Don't call into the frame recognizers on the private state thread as
// they can cause code to run in the target, and that can cause deadlocks
// when fetching stop events for the expression.
- if (m_thread.GetProcess()->CurrentThreadIsPrivateStateThread())
+ if (m_thread.GetProcess()->CurrentThreadPosesAsPrivateStateThread())
return;
Log *log = GetLog(LLDBLog::Thread);
diff --git a/lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py b/lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py
index f4404d78492f9..de9900cae4b75 100644
--- a/lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py
+++ b/lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py
@@ -24,6 +24,10 @@ def create_thread(self, tid, context):
return None
def get_thread_info(self):
+ if self.process.state != lldb.eStateStopped:
+ print("Error: get_thread_info called with state not stopped")
+ return []
+
if not self.threads:
self.threads = [
{
diff --git a/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/Makefile b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/Makefile
new file mode 100644
index 0000000000000..93618844a7a4d
--- /dev/null
+++ b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/Makefile
@@ -0,0 +1,4 @@
+C_SOURCES := main.c
+ENABLE_THREADS := YES
+
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/TestOSIndSYM.py b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/TestOSIndSYM.py
new file mode 100644
index 0000000000000..06524fb70566a
--- /dev/null
+++ b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/TestOSIndSYM.py
@@ -0,0 +1,145 @@
+"""
+Test that an OS plugin in a dSYM sees the right process state
+when run from a dSYM on attach
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+from lldbgdbserverutils import get_debugserver_exe
+
+import os
+import lldb
+import time
+import socket
+import shutil
+
+class TestOSPluginIndSYM(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ # The port used by debugserver.
+ PORT = 54638
+
+ # The number of attempts.
+ ATTEMPTS = 10
+
+ # Time given to the binary to launch and to debugserver to attach to it for
+ # every attempt. We'll wait a maximum of 10 times 2 seconds while the
+ # inferior will wait 10 times 10 seconds.
+ TIMEOUT = 2
+
+ def no_debugserver(self):
+ if get_debugserver_exe() is None:
+ return "no debugserver"
+ return None
+
+ def port_not_available(self):
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ if s.connect_ex(("127.0.0.1", self.PORT)) == 0:
+ return "{} not available".format(self.PORT)
+ return None
+
+ @skipUnlessDarwin
+ def test_python_os_plugin(self):
+ self.do_test_python_os_plugin(False)
+
+ @skipTestIfFn(no_debugserver)
+ @skipTestIfFn(port_not_available)
+ def test_python_os_plugin_remote(self):
+ self.do_test_python_os_plugin(True)
+
+ def do_test_python_os_plugin(self, remote):
+ """Test that the environment for os plugins in dSYM's is correct"""
+ executable = self.build_dsym("my_binary")
+
+ # Make sure we're set up to load the symbol file's python
+ self.runCmd("settings set target.load-script-from-symbol-file true")
+
+ target = self.dbg.CreateTarget(None)
+
+ error = lldb.SBError()
+
+ # Now run the process, and then attach. When the attach
+ # succeeds, make sure that we were in the right state when
+ # the OS plugins were run.
+ if not remote:
+ popen = self.spawnSubprocess(executable, [])
+
+ process = target.AttachToProcessWithID(lldb.SBListener(), popen.pid, error)
+ self.assertSuccess(error, "Attach succeeded")
+ else:
+ self.setup_remote_platform(executable)
+ process = target.process
+ self.assertTrue(process.IsValid(), "Got a valid process from debugserver")
+
+ # We should have figured out the target from the result of the attach:
+ self.assertTrue(target.IsValid, "Got a valid target")
+
+ # Make sure that we got the right plugin:
+ self.expect("settings show target.process.python-os-plugin-path", substrs=["operating_system.py"])
+
+ for thread in process.threads:
+ stack_depth = thread.num_frames
+ reg_threads = thread.frames[0].reg
+
+ # OKAY, that realized the threads, now see if the creation
+ # state was correct. The way we use the OS plugin, it doesn't need
+ # to create a thread, and doesn't have to call get_register_info,
+ # so we don't expect those to get called.
+ self.expect("test_report_command", substrs = ["in_init=1",
+ "in_get_thread_info=1",
+ "in_create_thread=2",
+ "in_get_register_info=2",
+ "in_get_register_data=1"])
+
+
+
+
+ def build_dsym(self, name):
+ self.build(debug_info="dsym", dictionary={"EXE": name})
+ executable = self.getBuildArtifact(name)
+ dsym_path = self.getBuildArtifact(name + ".dSYM")
+ python_dir_path = dsym_path
+ python_dir_path = os.path.join(dsym_path, "Contents", "Resources", "Python")
+ if not os.path.exists(python_dir_path):
+ os.mkdir(python_dir_path)
+ python_file_name = name + ".py"
+
+ os_plugin_dir = os.path.join(python_dir_path, "OS_Plugin")
+ if not os.path.exists(os_plugin_dir):
+ os.mkdir(os_plugin_dir)
+
+ plugin_dest_path = os.path.join(os_plugin_dir, "operating_system.py")
+ plugin_origin_path = os.path.join(self.getSourceDir(), "operating_system.py")
+ shutil.copy(plugin_origin_path, plugin_dest_path)
+
+ module_dest_path = os.path.join(python_dir_path, python_file_name)
+ with open(module_dest_path, "w") as f:
+ f.write( "def __lldb_init_module(debugger, unused):\n")
+ f.write(f" debugger.HandleCommand(\"settings set target.process.python-os-plugin-path '{plugin_dest_path}'\")\n")
+ f.close()
+
+ return executable
+
+ def setup_remote_platform(self, exe):
+ # Get debugserver to start up our process for us, and then we
+ # can use `process connect` to attach to it.
+ debugserver = get_debugserver_exe()
+ debugserver_args = ["localhost:{}".format(self.PORT), exe]
+ self.spawnSubprocess(debugserver, debugserver_args)
+
+ # Select the platform.
+ self.runCmd("platform select remote-gdb-server")
+
+ # Connect to debugserver
+ interpreter = self.dbg.GetCommandInterpreter()
+ connected = False
+ for i in range(self.ATTEMPTS):
+ result = lldb.SBCommandReturnObject()
+ interpreter.HandleCommand(f"gdb-remote localhost:{self.PORT}", result)
+ connected = result.Succeeded()
+ if connected:
+ break
+ time.sleep(self.TIMEOUT)
+
+ self.assertTrue(connected, "could not connect to debugserver")
diff --git a/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/main.c b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/main.c
new file mode 100644
index 0000000000000..ded9da5e18313
--- /dev/null
+++ b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/main.c
@@ -0,0 +1,10 @@
+#include <unistd.h>
+
+int
+main()
+{
+ while (1) {
+ sleep(1);
+ }
+ return 0;
+}
diff --git a/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/operating_system.py b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/operating_system.py
new file mode 100644
index 0000000000000..b8736f8b8a12e
--- /dev/null
+++ b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/operating_system.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+
+import lldb
+import struct
+
+# Value is:
+# 0 called - state is not stopped
+# 1 called - state is stopped
+# 2 not called
+
+stop_state = {"in_init" : 2,
+ "in_get_thread_info" : 2,
+ "in_create_thread" : 2,
+ "in_get_register_info" : 2,
+ "in_get_register_data" : 2}
+
+def ReportCommand(debugger, command, exe_ctx, result, unused):
+ global stop_state
+ for state in stop_state:
+ result.AppendMessage(f"{state}={stop_state[state]}\n")
+ result.SetStatus(lldb.eReturnStatusSuccessFinishResult)
+
+class OperatingSystemPlugIn():
+ """This class checks that all the
+ """
+
+ def __init__(self, process):
+ """Initialization needs a valid.SBProcess object.
+ global stop_state
+
+ This plug-in will get created after a live process is valid and has stopped for the
+ first time."""
+ self.process = process
+ stop_state["in_init"] = self.state_is_stopped()
+ interp = process.target.debugger.GetCommandInterpreter()
+ result = lldb.SBCommandReturnObject()
+ cmd_str = f"command script add test_report_command -o -f {__name__}.ReportCommand"
+ interp.HandleCommand(cmd_str, result)
+
+ def state_is_stopped(self):
+ if self.process.state == lldb.eStateStopped:
+ return 1
+ else:
+ return 0
+
+ def does_plugin_report_all_threads(self):
+ return True
+
+ def create_thread(self, tid, context):
+ global stop_state
+ stop_state["in_create_thread"] = self.state_is_stopped()
+
+ return None
+
+ def get_thread_info(self):
+ global stop_state
+ stop_state["in_get_thread_info"] = self.state_is_stopped()
+ idx = self.process.threads[0].idx
+ return [
+ {
+ "tid": 0x111111111,
+ "name": "one",
+ "queue": "queue1",
+ "state": "stopped",
+ "stop_reason": "breakpoint",
+ "core": idx,
+ }
+ ]
+
+ def get_register_info(self):
+ global stop_state
+ stop_state["in_get_register_info"] = self.state_is_stopped()
+ return None
+
+ def get_register_data(self, tid):
+ global stop_state
+ stop_state["in_get_register_data"] = self.state_is_stopped()
+ return None
>From 612ba79246bcf0372c13ca523db77d035b997999 Mon Sep 17 00:00:00 2001
From: Jim Ingham <jingham at apple.com>
Date: Mon, 30 Jun 2025 17:40:10 -0700
Subject: [PATCH 2/4] formatting
---
lldb/include/lldb/Host/HostThread.h | 9 +++--
lldb/include/lldb/Target/Process.h | 2 +-
lldb/source/Target/Process.cpp | 9 ++---
.../os_plugin_in_dsym/TestOSIndSYM.py | 40 +++++++++++--------
.../python_os_plugin/os_plugin_in_dsym/main.c | 4 +-
.../os_plugin_in_dsym/operating_system.py | 27 ++++++++-----
6 files changed, 51 insertions(+), 40 deletions(-)
diff --git a/lldb/include/lldb/Host/HostThread.h b/lldb/include/lldb/Host/HostThread.h
index d8b3610210aac..0f7113f6f9740 100644
--- a/lldb/include/lldb/Host/HostThread.h
+++ b/lldb/include/lldb/Host/HostThread.h
@@ -9,8 +9,8 @@
#ifndef LLDB_HOST_HOSTTHREAD_H
#define LLDB_HOST_HOSTTHREAD_H
-#include "lldb/Host/HostNativeThreadForward.h"
#include "lldb/Host/HostNativeThreadBase.h"
+#include "lldb/Host/HostNativeThreadForward.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-types.h"
@@ -43,11 +43,12 @@ class HostThread {
lldb::thread_result_t GetResult() const;
bool EqualsThread(lldb::thread_t thread) const;
-
- bool HasThread() const {
+
+ bool HasThread() const {
if (!m_native_thread)
return false;
- return m_native_thread->GetSystemHandle() != LLDB_INVALID_HOST_THREAD ; }
+ return m_native_thread->GetSystemHandle() != LLDB_INVALID_HOST_THREAD;
+ }
private:
std::shared_ptr<HostNativeThreadBase> m_native_thread;
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 1329abba9b17b..637b0774ec7db 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -2546,7 +2546,7 @@ void PruneThreadPlans();
ProcessRunLock &GetRunLock();
bool CurrentThreadIsPrivateStateThread();
-
+
bool CurrentThreadPosesAsPrivateStateThread();
virtual Status SendEventData(const char *data) {
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 9cdef7ef524fc..ae257123df631 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -3144,13 +3144,13 @@ void Process::CompleteAttach() {
}
}
- if (!m_os_up)
- LoadOperatingSystemPlugin(false);
+ if (!m_os_up)
+ LoadOperatingSystemPlugin(false);
if (m_os_up) {
// Somebody might have gotten threads before now, but we need to force the
// update after we've loaded the OperatingSystem plugin or it won't get a
- // chance to process the threads.
+ // chance to process the threads.
m_thread_list.Clear();
UpdateThreadListIfNeeded();
}
@@ -5857,8 +5857,7 @@ bool Process::CurrentThreadIsPrivateStateThread()
return m_private_state_thread.EqualsThread(Host::GetCurrentThread());
}
-bool Process::CurrentThreadPosesAsPrivateStateThread()
-{
+bool Process::CurrentThreadPosesAsPrivateStateThread() {
// If we haven't started up the private state thread yet, then whatever thread
// is fetching this event should be temporarily the private state thread.
if (!m_private_state_thread.HasThread())
diff --git a/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/TestOSIndSYM.py b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/TestOSIndSYM.py
index 06524fb70566a..f0d192be661bb 100644
--- a/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/TestOSIndSYM.py
+++ b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/TestOSIndSYM.py
@@ -14,6 +14,7 @@
import socket
import shutil
+
class TestOSPluginIndSYM(TestBase):
NO_DEBUG_INFO_TESTCASE = True
@@ -54,9 +55,9 @@ def do_test_python_os_plugin(self, remote):
# Make sure we're set up to load the symbol file's python
self.runCmd("settings set target.load-script-from-symbol-file true")
-
+
target = self.dbg.CreateTarget(None)
-
+
error = lldb.SBError()
# Now run the process, and then attach. When the attach
@@ -76,7 +77,10 @@ def do_test_python_os_plugin(self, remote):
self.assertTrue(target.IsValid, "Got a valid target")
# Make sure that we got the right plugin:
- self.expect("settings show target.process.python-os-plugin-path", substrs=["operating_system.py"])
+ self.expect(
+ "settings show target.process.python-os-plugin-path",
+ substrs=["operating_system.py"],
+ )
for thread in process.threads:
stack_depth = thread.num_frames
@@ -86,15 +90,17 @@ def do_test_python_os_plugin(self, remote):
# state was correct. The way we use the OS plugin, it doesn't need
# to create a thread, and doesn't have to call get_register_info,
# so we don't expect those to get called.
- self.expect("test_report_command", substrs = ["in_init=1",
- "in_get_thread_info=1",
- "in_create_thread=2",
- "in_get_register_info=2",
- "in_get_register_data=1"])
-
-
-
-
+ self.expect(
+ "test_report_command",
+ substrs=[
+ "in_init=1",
+ "in_get_thread_info=1",
+ "in_create_thread=2",
+ "in_get_register_info=2",
+ "in_get_register_data=1",
+ ],
+ )
+
def build_dsym(self, name):
self.build(debug_info="dsym", dictionary={"EXE": name})
executable = self.getBuildArtifact(name)
@@ -105,7 +111,7 @@ def build_dsym(self, name):
os.mkdir(python_dir_path)
python_file_name = name + ".py"
- os_plugin_dir = os.path.join(python_dir_path, "OS_Plugin")
+ os_plugin_dir = os.path.join(python_dir_path, "OS_Plugin")
if not os.path.exists(os_plugin_dir):
os.mkdir(os_plugin_dir)
@@ -115,12 +121,14 @@ def build_dsym(self, name):
module_dest_path = os.path.join(python_dir_path, python_file_name)
with open(module_dest_path, "w") as f:
- f.write( "def __lldb_init_module(debugger, unused):\n")
- f.write(f" debugger.HandleCommand(\"settings set target.process.python-os-plugin-path '{plugin_dest_path}'\")\n")
+ f.write("def __lldb_init_module(debugger, unused):\n")
+ f.write(
+ f" debugger.HandleCommand(\"settings set target.process.python-os-plugin-path '{plugin_dest_path}'\")\n"
+ )
f.close()
return executable
-
+
def setup_remote_platform(self, exe):
# Get debugserver to start up our process for us, and then we
# can use `process connect` to attach to it.
diff --git a/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/main.c b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/main.c
index ded9da5e18313..8e03f395e6110 100644
--- a/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/main.c
+++ b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/main.c
@@ -1,8 +1,6 @@
#include <unistd.h>
-int
-main()
-{
+int main() {
while (1) {
sleep(1);
}
diff --git a/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/operating_system.py b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/operating_system.py
index b8736f8b8a12e..0f9cec670b73f 100644
--- a/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/operating_system.py
+++ b/lldb/test/API/functionalities/plugins/python_os_plugin/os_plugin_in_dsym/operating_system.py
@@ -8,21 +8,24 @@
# 1 called - state is stopped
# 2 not called
-stop_state = {"in_init" : 2,
- "in_get_thread_info" : 2,
- "in_create_thread" : 2,
- "in_get_register_info" : 2,
- "in_get_register_data" : 2}
+stop_state = {
+ "in_init": 2,
+ "in_get_thread_info": 2,
+ "in_create_thread": 2,
+ "in_get_register_info": 2,
+ "in_get_register_data": 2,
+}
+
def ReportCommand(debugger, command, exe_ctx, result, unused):
global stop_state
for state in stop_state:
result.AppendMessage(f"{state}={stop_state[state]}\n")
result.SetStatus(lldb.eReturnStatusSuccessFinishResult)
-
-class OperatingSystemPlugIn():
- """This class checks that all the
- """
+
+
+class OperatingSystemPlugIn:
+ """This class checks that all the"""
def __init__(self, process):
"""Initialization needs a valid.SBProcess object.
@@ -34,7 +37,9 @@ def __init__(self, process):
stop_state["in_init"] = self.state_is_stopped()
interp = process.target.debugger.GetCommandInterpreter()
result = lldb.SBCommandReturnObject()
- cmd_str = f"command script add test_report_command -o -f {__name__}.ReportCommand"
+ cmd_str = (
+ f"command script add test_report_command -o -f {__name__}.ReportCommand"
+ )
interp.HandleCommand(cmd_str, result)
def state_is_stopped(self):
@@ -49,7 +54,7 @@ def does_plugin_report_all_threads(self):
def create_thread(self, tid, context):
global stop_state
stop_state["in_create_thread"] = self.state_is_stopped()
-
+
return None
def get_thread_info(self):
>From 15b7498751dd5f39d20bab2fa24673c1a116c22d Mon Sep 17 00:00:00 2001
From: Jim Ingham <jingham at apple.com>
Date: Thu, 10 Jul 2025 16:30:08 -0700
Subject: [PATCH 3/4] Move HostThread::HasThread implementation into
HostThread.cpp. Add a requested comment in Process.cpp
---
lldb/include/lldb/Host/HostThread.h | 7 +------
lldb/source/Host/common/HostThread.cpp | 6 ++++++
lldb/source/Target/Process.cpp | 8 +++++---
3 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/lldb/include/lldb/Host/HostThread.h b/lldb/include/lldb/Host/HostThread.h
index 0f7113f6f9740..c969492f5b20a 100644
--- a/lldb/include/lldb/Host/HostThread.h
+++ b/lldb/include/lldb/Host/HostThread.h
@@ -9,7 +9,6 @@
#ifndef LLDB_HOST_HOSTTHREAD_H
#define LLDB_HOST_HOSTTHREAD_H
-#include "lldb/Host/HostNativeThreadBase.h"
#include "lldb/Host/HostNativeThreadForward.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-types.h"
@@ -44,11 +43,7 @@ class HostThread {
bool EqualsThread(lldb::thread_t thread) const;
- bool HasThread() const {
- if (!m_native_thread)
- return false;
- return m_native_thread->GetSystemHandle() != LLDB_INVALID_HOST_THREAD;
- }
+ bool HasThread() const;
private:
std::shared_ptr<HostNativeThreadBase> m_native_thread;
diff --git a/lldb/source/Host/common/HostThread.cpp b/lldb/source/Host/common/HostThread.cpp
index eec029be1c091..8822be016b0a1 100644
--- a/lldb/source/Host/common/HostThread.cpp
+++ b/lldb/source/Host/common/HostThread.cpp
@@ -44,3 +44,9 @@ lldb::thread_result_t HostThread::GetResult() const {
bool HostThread::EqualsThread(lldb::thread_t thread) const {
return m_native_thread->EqualsThread(thread);
}
+
+bool HostThread::HasThread() const {
+ if (!m_native_thread)
+ return false;
+ return m_native_thread->GetSystemHandle() != LLDB_INVALID_HOST_THREAD;
+}
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index ae257123df631..91081c5167128 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -3144,13 +3144,15 @@ void Process::CompleteAttach() {
}
}
+ // If we don't have an operating system plugin loaded yet, see if
+ // LoadOperatingSystemPlugin can find one (and stuff it in m_os_up).
if (!m_os_up)
LoadOperatingSystemPlugin(false);
if (m_os_up) {
- // Somebody might have gotten threads before now, but we need to force the
- // update after we've loaded the OperatingSystem plugin or it won't get a
- // chance to process the threads.
+ // Somebody might have gotten threads before we loaded the OS Plugin above,
+ // so we need to force the update now or the newly loaded plugin won't get
+ // a chance to process the threads.
m_thread_list.Clear();
UpdateThreadListIfNeeded();
}
>From 8618073c82237fe6c6a357c5f5b87ac7182d33da Mon Sep 17 00:00:00 2001
From: Jim Ingham <jingham at apple.com>
Date: Fri, 11 Jul 2025 09:34:11 -0700
Subject: [PATCH 4/4] formatting
---
lldb/source/Target/Process.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 91081c5167128..2aa02fd58335e 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -3144,14 +3144,14 @@ void Process::CompleteAttach() {
}
}
- // If we don't have an operating system plugin loaded yet, see if
+ // If we don't have an operating system plugin loaded yet, see if
// LoadOperatingSystemPlugin can find one (and stuff it in m_os_up).
if (!m_os_up)
LoadOperatingSystemPlugin(false);
if (m_os_up) {
// Somebody might have gotten threads before we loaded the OS Plugin above,
- // so we need to force the update now or the newly loaded plugin won't get
+ // so we need to force the update now or the newly loaded plugin won't get
// a chance to process the threads.
m_thread_list.Clear();
UpdateThreadListIfNeeded();
More information about the lldb-commits
mailing list