https://github.com/mchoo7 updated https://github.com/llvm/llvm-project/pull/183981
>From 5e6aa6996f885bc232b3a5b5e42a363f526ea6d4 Mon Sep 17 00:00:00 2001 From: Minsoo Choo <[email protected]> Date: Sun, 1 Mar 2026 00:06:31 -0500 Subject: [PATCH 1/2] [lldb][Process/FreeBSDKernelCore] Improve DoUpdateThreadList() Signed-off-by: Minsoo Choo <[email protected]> --- .../ProcessFreeBSDKernelCore.cpp | 55 ++++++++++++++++--- llvm/docs/ReleaseNotes.md | 1 + 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp index 577d8e0d50cf1..7369b5ffdcb66 100644 --- a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp +++ b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp @@ -167,7 +167,10 @@ bool ProcessFreeBSDKernelCore::DoUpdateThreadList(ThreadList &old_thread_list, // LLDB but we can construct a process without threads to provide minimal // memory reading support. switch (GetTarget().GetArchitecture().GetMachine()) { + case llvm::Triple::arm: case llvm::Triple::aarch64: + case llvm::Triple::ppc64le: + case llvm::Triple::riscv64: case llvm::Triple::x86: case llvm::Triple::x86_64: break; @@ -217,6 +220,13 @@ bool ProcessFreeBSDKernelCore::DoUpdateThreadList(ThreadList &old_thread_list, ReadSignedIntegerFromMemory(FindSymbol("pcb_size"), 4, -1, error); lldb::addr_t stoppcbs = FindSymbol("stoppcbs"); + // Read stopped_cpus bitmask and mp_maxid for CPU validation + lldb::addr_t stopped_cpus = FindSymbol("stopped_cpus"); + int32_t mp_maxid = + ReadSignedIntegerFromMemory(FindSymbol("mp_maxid"), 4, 0, error); + uint32_t long_size = GetAddressByteSize(); // approximation of sizeof(long) + uint32_t long_bits = long_size * 8; + // from FreeBSD sys/param.h constexpr size_t fbsd_maxcomlen = 19; @@ -225,11 +235,23 @@ bool ProcessFreeBSDKernelCore::DoUpdateThreadList(ThreadList &old_thread_list, // the end of the list, so we have to walk it backwards. First collect all // the processes in the list order. std::vector<lldb::addr_t> process_addrs; - for (lldb::addr_t proc = - ReadPointerFromMemory(FindSymbol("allproc"), error); - proc != 0 && proc != LLDB_INVALID_ADDRESS; - proc = ReadPointerFromMemory(proc + offset_p_list, error)) { - process_addrs.push_back(proc); + + lldb::addr_t zombproc_addr = FindSymbol("zombproc"); + if (zombproc_addr != LLDB_INVALID_ADDRESS) { + for (lldb::addr_t proc = ReadPointerFromMemory(zombproc_addr, error); + proc != 0 && proc != LLDB_INVALID_ADDRESS; + proc = ReadPointerFromMemory(proc + offset_p_list, error)) { + process_addrs.push_back(proc); + } + } + + lldb::addr_t allproc_addr = FindSymbol("allproc"); + if (allproc_addr != LLDB_INVALID_ADDRESS) { + for (lldb::addr_t proc = ReadPointerFromMemory(allproc_addr, error); + proc != 0 && proc != LLDB_INVALID_ADDRESS; + proc = ReadPointerFromMemory(proc + offset_p_list, error)) { + process_addrs.push_back(proc); + } } // Processes are in the linked list in descending PID order, so we must walk @@ -280,12 +302,27 @@ bool ProcessFreeBSDKernelCore::DoUpdateThreadList(ThreadList &old_thread_list, pcb_addr = dumppcb; thread_desc += " (crashed)"; } else if (oncpu != -1) { - // If we managed to read stoppcbs and pcb_size, use them to find - // the correct PCB. - if (stoppcbs != LLDB_INVALID_ADDRESS && pcbsize > 0) + // Verify the CPU is actually in the stopped set before using + // its stoppcbs entry. + bool is_stopped = false; + if (stopped_cpus != LLDB_INVALID_ADDRESS && oncpu >= 0 && + oncpu <= mp_maxid) { + uint32_t bit = oncpu % long_bits; + uint32_t word = oncpu / long_bits; + lldb::addr_t mask_addr = stopped_cpus + word * long_size; + uint64_t mask = + ReadUnsignedIntegerFromMemory(mask_addr, long_size, 0, error); + if (error.Success()) + is_stopped = (mask & (1ULL << bit)) != 0; + } + + // If we managed to read stoppcbs and pcb_size and the cpu is marked + // as stopped, use them to find the correct PCB. + if (is_stopped && stoppcbs != LLDB_INVALID_ADDRESS && pcbsize > 0) { pcb_addr = stoppcbs + oncpu * pcbsize; - else + } else { pcb_addr = LLDB_INVALID_ADDRESS; + } thread_desc += llvm::formatv(" (on CPU {0})", oncpu); } diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 2e0c5c5cb9370..4dd6bf57ee3a2 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -230,6 +230,7 @@ Changes to LLDB `plugin.process.freebsd-kernel-core.read-only` must be set to `false`. This setting is available when using `/dev/mem` or a kernel dump. However, since `kvm_write()` does not support writing to kernel dumps, writes to a kernel dump will still fail when the setting is false. +* Zombie processes are now shown in the thread list as well. ### Linux >From 61197ae761ce1fda26c8f3494144560415448204 Mon Sep 17 00:00:00 2001 From: Minsoo Choo <[email protected]> Date: Mon, 2 Mar 2026 12:24:47 -0500 Subject: [PATCH 2/2] fixup! [lldb][Process/FreeBSDKernelCore] Improve DoUpdateThreadList() Signed-off-by: Minsoo Choo <[email protected]> --- .../ProcessFreeBSDKernelCore.cpp | 47 +++++++++---------- llvm/docs/ReleaseNotes.md | 1 - 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp index 7369b5ffdcb66..67400b7ebce8b 100644 --- a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp +++ b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp @@ -222,12 +222,18 @@ bool ProcessFreeBSDKernelCore::DoUpdateThreadList(ThreadList &old_thread_list, // Read stopped_cpus bitmask and mp_maxid for CPU validation lldb::addr_t stopped_cpus = FindSymbol("stopped_cpus"); - int32_t mp_maxid = - ReadSignedIntegerFromMemory(FindSymbol("mp_maxid"), 4, 0, error); - uint32_t long_size = GetAddressByteSize(); // approximation of sizeof(long) - uint32_t long_bits = long_size * 8; - // from FreeBSD sys/param.h + // from sys/kern/subr_smp.c + uint32_t mp_maxid = + ReadUnsignedIntegerFromMemory(FindSymbol("mp_maxid"), 4, 0, error); + uint32_t long_bytes = *GetTarget() + .GetScratchTypeSystemForLanguage(eLanguageTypeC) + ->GetBasicTypeFromAST(eBasicTypeLong) + .GetByteSize(nullptr); + uint32_t long_bit = long_bytes * 8; + uint32_t long_bit = long_bytes * 8; + + // from sys/param.h constexpr size_t fbsd_maxcomlen = 19; // Iterate through a linked list of all processes. New processes are added @@ -235,23 +241,12 @@ bool ProcessFreeBSDKernelCore::DoUpdateThreadList(ThreadList &old_thread_list, // the end of the list, so we have to walk it backwards. First collect all // the processes in the list order. std::vector<lldb::addr_t> process_addrs; - - lldb::addr_t zombproc_addr = FindSymbol("zombproc"); - if (zombproc_addr != LLDB_INVALID_ADDRESS) { - for (lldb::addr_t proc = ReadPointerFromMemory(zombproc_addr, error); - proc != 0 && proc != LLDB_INVALID_ADDRESS; - proc = ReadPointerFromMemory(proc + offset_p_list, error)) { - process_addrs.push_back(proc); - } - } - - lldb::addr_t allproc_addr = FindSymbol("allproc"); - if (allproc_addr != LLDB_INVALID_ADDRESS) { + if (lldb::addr_t allproc_addr = FindSymbol("allproc"); + allproc_addr != LLDB_INVALID_ADDRESS) { for (lldb::addr_t proc = ReadPointerFromMemory(allproc_addr, error); - proc != 0 && proc != LLDB_INVALID_ADDRESS; - proc = ReadPointerFromMemory(proc + offset_p_list, error)) { + proc != 0 && proc != LLDB_INVALID_ADDRESS && error.Success(); + proc = ReadPointerFromMemory(proc + offset_p_list, error)) process_addrs.push_back(proc); - } } // Processes are in the linked list in descending PID order, so we must walk @@ -305,13 +300,13 @@ bool ProcessFreeBSDKernelCore::DoUpdateThreadList(ThreadList &old_thread_list, // Verify the CPU is actually in the stopped set before using // its stoppcbs entry. bool is_stopped = false; - if (stopped_cpus != LLDB_INVALID_ADDRESS && oncpu >= 0 && - oncpu <= mp_maxid) { - uint32_t bit = oncpu % long_bits; - uint32_t word = oncpu / long_bits; - lldb::addr_t mask_addr = stopped_cpus + word * long_size; + if (oncpu >= 0 && oncpu <= mp_maxid && + stopped_cpus != LLDB_INVALID_ADDRESS) { + uint32_t bit = oncpu % long_bit; + uint32_t word = oncpu / long_bit; + lldb::addr_t mask_addr = stopped_cpus + word * long_bytes; uint64_t mask = - ReadUnsignedIntegerFromMemory(mask_addr, long_size, 0, error); + ReadUnsignedIntegerFromMemory(mask_addr, long_bytes, 0, error); if (error.Success()) is_stopped = (mask & (1ULL << bit)) != 0; } diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 4dd6bf57ee3a2..2e0c5c5cb9370 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -230,7 +230,6 @@ Changes to LLDB `plugin.process.freebsd-kernel-core.read-only` must be set to `false`. This setting is available when using `/dev/mem` or a kernel dump. However, since `kvm_write()` does not support writing to kernel dumps, writes to a kernel dump will still fail when the setting is false. -* Zombie processes are now shown in the thread list as well. ### Linux _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
