[Lldb-commits] [lldb] [lldb][test] check if CoreDumping info is supported (PR #160333)
github-actions[bot] wrote:
:warning: C/C++ code formatter, clang-format found issues in your code.
:warning:
You can test this locally with the following command:
``bash
git-clang-format --diff origin/main HEAD --extensions cpp --
lldb/unittests/Host/posix/HostTest.cpp
``
:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:
View the diff from clang-format here.
``diff
diff --git a/lldb/unittests/Host/posix/HostTest.cpp
b/lldb/unittests/Host/posix/HostTest.cpp
index 7bb44c99b..1c3f7799f 100644
--- a/lldb/unittests/Host/posix/HostTest.cpp
+++ b/lldb/unittests/Host/posix/HostTest.cpp
@@ -120,7 +120,7 @@ TEST_F(HostTest, GetProcessInfoSetsPriority) {
ASSERT_TRUE(Info.IsZombie().has_value());
ASSERT_FALSE(Info.IsZombie().value());
- // CoreDumping was added in kernel version 4.15
+ // CoreDumping was added in kernel version 4.15
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
ASSERT_TRUE(Info.IsCoreDumping().has_value());
ASSERT_FALSE(Info.IsCoreDumping().value());
``
https://github.com/llvm/llvm-project/pull/160333
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Parse qSupported MultiMemRead tag in GDB Remote Client (PR #163249)
https://github.com/DavidSpickett approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/163249 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [gdbremote] Document MultiMemRead packet in protocol extensions (PR #162675)
@@ -735,6 +735,56 @@ This is a performance optimization, which speeds up debugging by avoiding multiple round-trips for retrieving thread information. The information from this packet can be retrieved using a combination of `qThreadStopInfo` and `m` packets. +### MultiMemRead + +Read memory from multiple memory ranges. + +This packet has one argument: + +* `ranges`: a list of pairs of numbers, formatted in base-16. Each pair is +separated by a `,`, as is each number in each pair. The first number of the +pair denotes the base address of the memory read, the second denotes the number +of bytes to be read. The list must end with a `;`. + +The reply packet starts with a comma-separated list of numbers formatted in +base-16, denoting how many bytes were read from each range, in the same order +as the request packet. The list is followed by a `;`, followed by a sequence of +bytes containing binary encoded data for all memory that was read. The length +of this sequence must be equal to the sum of the numbers provided at the start +of the reply. The order of the binary data is the same as the order of the +ranges in the request packet. + +If an entire range is not readable, the stub may perform a partial read of a +prefix of the range. + +If the stub is unable to read any bytes from a particular range, it must return +a length of "zero" for that range in the reply packet; no bytes for this memory +range are included in the sequence of bytes that follows. + +A stub that supports this packet must include `MultiMemRead+` in the reply to +`qSupported`. + +``` +send packet: $MultiMemRead:ranges:100a00,4,200200,a0,40,4; +read packet: $4,0,2; +``` + +In the example above, the first read produced `abcd1000`, the read of `a0` +bytes from address `200200` failed to read any bytes, and the third read +produced two bytes – `eeff` – out of the four requested. + +``` +send packet: $MultiMemRead:ranges:100a00,0; +read packet: $0; +``` + +In the example above, a read of zero bytes was requested. A zero-length request +provides an alternative way of testing whether the stub supports +`MultiMemRead`. DavidSpickett wrote: Given our qSupported discussion, does it actually give a way to check for support? Due to the `M` prefix issue. Also we say "must" include the qSupported tag. So perhaps we just don't mention this slightly risky alternative. https://github.com/llvm/llvm-project/pull/162675 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [gdbremote] Document MultiMemRead packet in protocol extensions (PR #162675)
@@ -735,6 +735,56 @@ This is a performance optimization, which speeds up debugging by avoiding multiple round-trips for retrieving thread information. The information from this packet can be retrieved using a combination of `qThreadStopInfo` and `m` packets. +### MultiMemRead + +Read memory from multiple memory ranges. + +This packet has one argument: + +* `ranges`: a list of pairs of numbers, formatted in base-16. Each pair is +separated by a `,`, as is each number in each pair. The first number of the +pair denotes the base address of the memory read, the second denotes the number +of bytes to be read. The list must end with a `;`. + +The reply packet starts with a comma-separated list of numbers formatted in +base-16, denoting how many bytes were read from each range, in the same order +as the request packet. The list is followed by a `;`, followed by a sequence of +bytes containing binary encoded data for all memory that was read. The length +of this sequence must be equal to the sum of the numbers provided at the start +of the reply. The order of the binary data is the same as the order of the +ranges in the request packet. + +If an entire range is not readable, the stub may perform a partial read of a +prefix of the range. DavidSpickett wrote: But good to note anyway so that someone doesn't use this packet for a kind of "narrow down to the readable memory" strategy, by assuming partial reads tells them how close they are to the edge of a mapping. Also if we require stubs to always support partial reads, then they need to be slicing the reads into smaller and smaller chunks. Which I don't think we're trying to do with this packet. https://github.com/llvm/llvm-project/pull/162675 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [gdbremote] Document MultiMemRead packet in protocol extensions (PR #162675)
@@ -735,6 +735,56 @@ This is a performance optimization, which speeds up debugging by avoiding multiple round-trips for retrieving thread information. The information from this packet can be retrieved using a combination of `qThreadStopInfo` and `m` packets. +### MultiMemRead + +Read memory from multiple memory ranges. + +This packet has one argument: + +* `ranges`: a list of pairs of numbers, formatted in base-16. Each pair is +separated by a `,`, as is each number in each pair. The first number of the +pair denotes the base address of the memory read, the second denotes the number +of bytes to be read. The list must end with a `;`. + +The reply packet starts with a comma-separated list of numbers formatted in +base-16, denoting how many bytes were read from each range, in the same order +as the request packet. The list is followed by a `;`, followed by a sequence of +bytes containing binary encoded data for all memory that was read. The length +of this sequence must be equal to the sum of the numbers provided at the start +of the reply. The order of the binary data is the same as the order of the +ranges in the request packet. + +If an entire range is not readable, the stub may perform a partial read of a +prefix of the range. + +If the stub is unable to read any bytes from a particular range, it must return DavidSpickett wrote: This is a bit ambiguous because "unable to read any" could mean they all failed or just one. You need a way to say "if by applying the rules above, the stub has read 0 bytes from the range...". https://github.com/llvm/llvm-project/pull/162675 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] c9b07f3 - [LLDB, FreeBSD, x86] Fix empty register set when trying to get size of register (#162890)
Author: aokblast
Date: 2025-10-15T09:55:00+01:00
New Revision: c9b07f34d46237ea547f379f979e7d0106e5a910
URL:
https://github.com/llvm/llvm-project/commit/c9b07f34d46237ea547f379f979e7d0106e5a910
DIFF:
https://github.com/llvm/llvm-project/commit/c9b07f34d46237ea547f379f979e7d0106e5a910.diff
LOG: [LLDB, FreeBSD, x86] Fix empty register set when trying to get size of
register (#162890)
The register set information is stored as a singleton in
GetRegisterInfo_i386. However, other functions later access this
information assuming it is stored in GetSharedRegisterInfoVector. To
resolve this inconsistency, we remove the original construction logic
and instead initialize the singleton using llvm::call_once within the
appropriate function (GetSharedRegisterInfoVector_i386).
Added:
Modified:
lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
Removed:
diff --git
a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
index e0f3971c6e272..c361b2abb726b 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
@@ -9,6 +9,7 @@
#include "RegisterContextFreeBSD_x86_64.h"
#include "RegisterContextFreeBSD_i386.h"
#include "RegisterContextPOSIX_x86.h"
+#include "llvm/Support/Threading.h"
#include
using namespace lldb_private;
@@ -69,40 +70,34 @@ struct UserArea {
#include "RegisterInfos_x86_64.h"
#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
-static std::vector &GetSharedRegisterInfoVector() {
- static std::vector register_infos;
- return register_infos;
-}
-
-static const RegisterInfo *
-GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) {
- static std::vector g_register_infos(
- GetSharedRegisterInfoVector());
-
- // Allocate RegisterInfo only once
- if (g_register_infos.empty()) {
-// Copy the register information from base class
-std::unique_ptr reg_interface(
-new RegisterContextFreeBSD_i386(arch));
-const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
-g_register_infos.insert(g_register_infos.end(), &base_info[0],
-&base_info[k_num_registers_i386]);
+static std::vector &
+GetSharedRegisterInfoVector_i386(const lldb_private::ArchSpec &arch) {
+ static std::vector g_register_infos;
+ static llvm::once_flag g_initialized;
+ llvm::call_once(g_initialized, [&]() {
+if (g_register_infos.empty()) {
+ // Copy the register information from base class
+ std::unique_ptr reg_interface(
+ new RegisterContextFreeBSD_i386(arch));
+ const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
+ g_register_infos.insert(g_register_infos.end(), &base_info[0],
+ &base_info[k_num_registers_i386]);
// Include RegisterInfos_x86_64 to update the g_register_infos structure
// with x86_64 offsets.
#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
#include "RegisterInfos_x86_64.h"
#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
- }
-
- return &g_register_infos[0];
+}
+ });
+ return g_register_infos;
}
static const RegisterInfo *
PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
switch (target_arch.GetMachine()) {
case llvm::Triple::x86:
-return GetRegisterInfo_i386(target_arch);
+return &GetSharedRegisterInfoVector_i386(target_arch)[0];
case llvm::Triple::x86_64:
return g_register_infos_x86_64;
default:
@@ -116,9 +111,10 @@ PrivateGetRegisterCount(const lldb_private::ArchSpec
&target_arch) {
switch (target_arch.GetMachine()) {
case llvm::Triple::x86:
// This vector should have already been filled.
-assert(!GetSharedRegisterInfoVector().empty() &&
+assert(!GetSharedRegisterInfoVector_i386(target_arch).empty() &&
"i386 register info vector not filled.");
-return static_cast(GetSharedRegisterInfoVector().size());
+return static_cast(
+GetSharedRegisterInfoVector_i386(target_arch).size());
case llvm::Triple::x86_64:
return static_cast(sizeof(g_register_infos_x86_64) /
sizeof(g_register_infos_x86_64[0]));
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][test] Fix TestEmptyFuncThreadStepOut.py (PR #161788)
@@ -15,10 +15,23 @@ class FinishFromEmptyFunctionTestCase(TestBase):
def test_finish_from_empty_function(self):
"""Test that when stopped at a breakpoint in an empty function, finish
leaves it correctly."""
self.build()
-exe = self.getBuildArtifact("a.out")
-target, process, thread, _ = lldbutil.run_to_name_breakpoint(
-self, "done", exe_name=exe
+target, _, thread, _ = lldbutil.run_to_source_breakpoint(
+self, "// Set breakpoint here", lldb.SBFileSpec("main.c")
)
+# Find the last instruction address of 'done()' and set a breakpoint
there.
+error = lldb.SBError()
+ret_bp_addr = lldb.SBAddress()
+while True:
+thread.StepInstruction(False, error)
+self.assertTrue(error.Success())
+frame = thread.GetSelectedFrame()
+if "done" in frame.GetFunctionName():
+ret_bp_addr = frame.GetPCAddress()
+elif ret_bp_addr.IsValid():
+break
DavidSpickett wrote:
Comment here:
Current PC here is the epilogue of "done", so we know the previous PC must be
the last instruction.
Also is there not a static way to find this information by looking up the
function? Maybe that way includes prologue and epilogue so you can't use that?
https://github.com/llvm/llvm-project/pull/161788
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Remove timings from TestDAP_attach (PR #163452)
JDevlieghere wrote: > I love it when I see @skips getting removed Ha, let's see if it sticks, but I'm optimistic that there's no reason these test should time out anymore. If they do it's a real issue with `lldb-dap` and not the test. https://github.com/llvm/llvm-project/pull/163452 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][NativePDB] Use typedef compiler type for typedef types (PR #156250)
Nerixyz wrote: If I see it correctly, then this check is for sorting functions. Do you have a full backtrace? https://github.com/llvm/llvm-project/pull/156250 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [lldb] [Clang] Introduce OverflowBehaviorType for fine-grained overflow control (PR #148914)
ojhunt wrote: > @JustinStitt were looking over things, and I stumbled over something here... > > > Thanks. So IIUC, the rule is: > > > > 1. If the type of either operand of an arithmetic operator is `__ob_trap`, > > the operator traps on overflow, and the result type is `__ob_trap`. > > This is correct and what I was expecting. > > > 2. If either the operand type or the destination type of an integer > > conversion is `__ob_trap`, the conversion traps on overflow. > > This one, however, I think it not what we want, but I may be missing > something. > > ``` > int __ob_trap src = bigger_than_255; > ... > char dest = src; > ``` > I don't think that's correct, it's equivalent to saying ``` int64 __ob_trap src = bigger_than_2_to_32; ... int dest = src; ``` Should not trap, and similarly ``` void f(int); int64 __ob_trap src = bigger_than_2_to_32; f(src); ``` Would also not trap. It also raises questions about what happens with ``` int __ob_wrap src = bigger_than_2_to_32; ... char dest = src; ``` If ob_trap is ignored, ob_wrap should similarly be ignored, and thus we have UB overflow again. > I don't think we want a trap on the `dest` assignment, since it isn't > `__ob_trap`. It doesn't care about the truncation. This is a "sided" > operation, unlike the arithmetic. I disagree - the type has stated "overflow must have defined behavior', and in this case that behavior is to trap. This change implicitly subsumes that behavior, silencing the overflow trap, and rendering the overflow UB once more. Code of the form ``` type value = some_obt_qualified_value ``` Is not saying "overflow of `some_obt_qualified_value` does not matter", it is saying "overflow from operations on `value` does not matter". >From a consistency point of view it also means that ``` narrower_type narrower = 0; wider_type __ob_trap wider = wider_type(numeric_limits::max()) + 1; while (..) narrower += wider; ``` Will no longer have defined overflow behavior, and in the trapping configuration will not trap on the overflow. For the char case specifically, no overflow will ever trap as arithmetic on any type narrower than int is promoted to int so ```cpp char __obt_* src = ...; char dst = src + 257; /* no overflow on the arithmetic, so we end up with an `int __obt` -> char that has ignored/UB overflow */ ``` > This is in preparation for looking at having instrumentation added for > explicit casts, like: > > ``` > int b = bigger_than_255; > ... > int c = (u8 __ob_trap)b; // this should trap > ``` I'm not sure what you're saying here - this works as specified currently and it does not require implicit casts to be treated differently? https://github.com/llvm/llvm-project/pull/148914 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [gdbremote] Document MultiMemRead packet in protocol extensions (PR #162675)
felipepiovezan wrote: Addressed review comments https://github.com/llvm/llvm-project/pull/162675 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [clang-tools-extra] [compiler-rt] [libc] [libcxx] [lld] [lldb] [llvm] [mlir] [openmp] [polly] Python-related cleanups (PR #163566)
DavidSpickett wrote: I'm not clear on the specific purpose here: > Ensure that the nested native CMake build uses the same Python interpreter as > the outer build. > > Unify python shebangs so that they use python3 everywhere, instead of a mix > of python and python3. Is the first implemented by doing the second? Or are you doing 2 things here? (with so many files I might have missed something) We might be ok with a mass replace of python -> python3 generally, but if you know which specific files fix your use case, I'd prefer to see those in their own PR. So we have a better attribution of problems fixed (or created, as it may be) by each change. Or you can reframe this as "llvm requires python of at least 3, plenty of scripts use python3 already, let's make it consistent". Which is a good pitch that doesn't need the context of your use case. If there is a mass conversion of python shebangs earlier in the git history, you can cite that as precedent. We probably did for some subset of scripts back when we moved to requiring >= 3. Sometimes we will accept changes like this as is, sometimes they need to be broken up. Depends on the sub-projects' attitude to the changes. It can also take a lot of time to get every single part approved. FWIW if you broke out the LLDB changes I'd accept them as is. https://github.com/llvm/llvm-project/pull/163566 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [clang-tools-extra] [compiler-rt] [libc] [libcxx] [lld] [lldb] [llvm] [mlir] [openmp] [polly] Python-related cleanups (PR #163566)
DavidSpickett wrote: And this broke the Python formatter, as in, it failed to parse the code. Probably one of the infrequently changed projects like Polly has some strange code in it. Point is - we know this isn't changing actual Python code so ignore it. https://github.com/llvm/llvm-project/pull/163566 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [gdbremote] Document MultiMemRead packet in protocol extensions (PR #162675)
@@ -735,6 +735,56 @@ This is a performance optimization, which speeds up debugging by avoiding multiple round-trips for retrieving thread information. The information from this packet can be retrieved using a combination of `qThreadStopInfo` and `m` packets. +### MultiMemRead + +Read memory from multiple memory ranges. + +This packet has one argument: + +* `ranges`: a list of pairs of numbers, formatted in base-16. Each pair is +separated by a `,`, as is each number in each pair. The first number of the +pair denotes the base address of the memory read, the second denotes the number +of bytes to be read. The list must end with a `;`. + +The reply packet starts with a comma-separated list of numbers formatted in +base-16, denoting how many bytes were read from each range, in the same order +as the request packet. The list is followed by a `;`, followed by a sequence of +bytes containing binary encoded data for all memory that was read. The length +of this sequence must be equal to the sum of the numbers provided at the start felipepiovezan wrote: Uhhh, actually you raise a good point. There are a handful of bytes that need to be escaped because of the binary encoding of data (*). So let's rephrase this as: > The length of the binary encoded data, after being decoded as required by the > GDB remote protocol, is equal to... (*) > The binary data representation uses 7d (ASCII ‘}’) as an escape character. > Any escaped byte is transmitted as the escape character followed by the > original character XORed with 0x20. For example, the byte 0x7d would be > transmitted as the two bytes 0x7d 0x5d. The bytes 0x23 (ASCII ‘#’), 0x24 > (ASCII ‘$’), and 0x7d (ASCII ‘}’) must always be escaped. Responses sent by > the stub must also escape 0x2a (ASCII ‘*’), so that it is not interpreted as > the start of a run-length encoded sequence (described next). https://github.com/llvm/llvm-project/pull/162675 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [gdbremote] Document MultiMemRead packet in protocol extensions (PR #162675)
@@ -735,6 +735,56 @@ This is a performance optimization, which speeds up debugging by avoiding multiple round-trips for retrieving thread information. The information from this packet can be retrieved using a combination of `qThreadStopInfo` and `m` packets. +### MultiMemRead + +Read memory from multiple memory ranges. + +This packet has one argument: + +* `ranges`: a list of pairs of numbers, formatted in base-16. Each pair is +separated by a `,`, as is each number in each pair. The first number of the +pair denotes the base address of the memory read, the second denotes the number +of bytes to be read. The list must end with a `;`. + +The reply packet starts with a comma-separated list of numbers formatted in +base-16, denoting how many bytes were read from each range, in the same order +as the request packet. The list is followed by a `;`, followed by a sequence of +bytes containing binary encoded data for all memory that was read. The length +of this sequence must be equal to the sum of the numbers provided at the start +of the reply. The order of the binary data is the same as the order of the +ranges in the request packet. + +If an entire range is not readable, the stub may perform a partial read of a +prefix of the range. felipepiovezan wrote: I didn't know about the Windows limitation! Will update the text as suggested https://github.com/llvm/llvm-project/pull/162675 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [clang-tools-extra] [compiler-rt] [libc] [libcxx] [lld] [lldb] [llvm] [mlir] [openmp] [polly] Python-related cleanups (PR #163566)
rossburton wrote: The PYTHON_EXECUTABLE and the shebang cleanups are entirely unrelated except by theme, I can split them it that would make things easier. https://github.com/llvm/llvm-project/pull/163566 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] e91786a - [gdbremote] Document MultiMemRead packet in protocol extensions (#162675)
Author: Felipe de Azevedo Piovezan Date: 2025-10-15T08:02:39-07:00 New Revision: e91786a84967e006b21f2eb0eb59a56b2f925eac URL: https://github.com/llvm/llvm-project/commit/e91786a84967e006b21f2eb0eb59a56b2f925eac DIFF: https://github.com/llvm/llvm-project/commit/e91786a84967e006b21f2eb0eb59a56b2f925eac.diff LOG: [gdbremote] Document MultiMemRead packet in protocol extensions (#162675) This adds a specification for the new packet discussed in the RFC [1]. [1]: https://discourse.llvm.org/t/rfc-a-new-vectorized-memory-read-packet/88441/12 Added: Modified: lldb/docs/resources/lldbgdbremote.md Removed: diff --git a/lldb/docs/resources/lldbgdbremote.md b/lldb/docs/resources/lldbgdbremote.md index 93fb0c9b5502f..f0c5e6b04d54c 100644 --- a/lldb/docs/resources/lldbgdbremote.md +++ b/lldb/docs/resources/lldbgdbremote.md @@ -738,6 +738,57 @@ This is a performance optimization, which speeds up debugging by avoiding multiple round-trips for retrieving thread information. The information from this packet can be retrieved using a combination of `qThreadStopInfo` and `m` packets. +### MultiMemRead + +Read memory from multiple memory ranges. + +This packet has one argument: + +* `ranges`: a list of pairs of numbers, formatted in base-16. Each pair is +separated by a `,`, as is each number in each pair. The first number of the +pair denotes the base address of the memory read, the second denotes the number +of bytes to be read. The list must end with a `;`. + +The reply packet starts with a comma-separated list of numbers formatted in +base-16, denoting how many bytes were read from each range, in the same order +as the request packet. The list is followed by a `;`, followed by a sequence of +bytes containing binary encoded data for all memory that was read. The length +of the binary encodeed data, after being decoded as required by the GDB remote +protocol, must be equal to the sum of the numbers provided at the start of the +reply. The order of the binary data is the same as the order of the ranges in +the request packet. + +If some part of a range is not readable, the stub may perform a partial read of +a prefix of the range. In other words, partial reads will only ever be from the +start of the range, never the middle or end. Support for partial reads depends +on the debug stub. + +If, by applying the rules above, the stub has read zero bytes from a range, it +must return a length of zero for that range in the reply packet; no bytes for +this memory range are included in the sequence of bytes that follows. + +A stub that supports this packet must include `MultiMemRead+` in the reply to +`qSupported`. + +``` +send packet: $MultiMemRead:ranges:100a00,4,200200,a0,40,4; +read packet: $4,0,2; +``` + +In the example above, the first read produced `abcd1000`, the read of `a0` +bytes from address `200200` failed to read any bytes, and the third read +produced two bytes – `eeff` – out of the four requested. + +``` +send packet: $MultiMemRead:ranges:100a00,0; +read packet: $0; +``` + +In the example above, a read of zero bytes was requested. + +**Priority to Implement:** Only required for performance, the debugger will +fall back to doing separate read requests if this packet is unavailable. + ## QEnvironment:NAME=VALUE Setup the environment up for a new child process that will soon be ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [clang-tools-extra] [lldb] [clang] NFC: rename TagType::getOriginalDecl back to getDecl (PR #163271)
https://github.com/rupprecht approved this pull request. Thanks :) https://github.com/llvm/llvm-project/pull/163271 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Allow empty memory reference in disassemble arguments (PR #162517)
https://github.com/DrSergei updated
https://github.com/llvm/llvm-project/pull/162517
>From 3d548533d38277eb2ba59c810f7634909bb7adbd Mon Sep 17 00:00:00 2001
From: Druzhkov Sergei
Date: Wed, 8 Oct 2025 11:38:55 +0300
Subject: [PATCH 1/2] [lldb-dap] Allow empty memory reference in disassemble
arguments
---
.../disassemble/TestDAP_disassemble.py| 22 +++
.../Handler/DisassembleRequestHandler.cpp | 5 +
lldb/tools/lldb-dap/JSONUtils.cpp | 7 +-
lldb/tools/lldb-dap/JSONUtils.h | 5 -
.../lldb-dap/Protocol/ProtocolRequests.cpp| 2 +-
5 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py
b/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py
index 0562f20335a23..6c41c86ff9ae5 100644
--- a/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py
+++ b/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py
@@ -91,3 +91,25 @@ def test_disassemble_backwards(self):
# clear breakpoints
self.set_source_breakpoints(source, [])
self.continue_to_exit()
+
+def test_disassemble_empty_memory_reference(self):
+"""
+Tests the 'disassemble' request with empty memory reference.
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.c"
+bp_line_no = line_number(source, "// breakpoint 1")
+self.set_source_breakpoints(source, [bp_line_no])
+self.continue_to_next_stop()
+
+instructions = self.dap_server.request_disassemble(
+memoryReference="", instructionOffset=0, instructionCount=50
+)
+self.assertEqual(len(instructions), 50)
+for instruction in instructions:
+self.assertEqual(instruction["presentationHint"], "invalid")
+
+# clear breakpoints
+self.set_source_breakpoints(source, [])
+self.continue_to_exit()
diff --git a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
index 9542f091b055e..6d2eb74a9634c 100644
--- a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
@@ -182,6 +182,11 @@ static DisassembledInstruction
ConvertSBInstructionToDisassembledInstruction(
/// `supportsDisassembleRequest` is true.
llvm::Expected
DisassembleRequestHandler::Run(const DisassembleArguments &args) const {
+ if (args.memoryReference == LLDB_INVALID_ADDRESS) {
+std::vector invalid_instructions(
+args.instructionCount, GetInvalidInstruction());
+return DisassembleResponseBody{std::move(invalid_instructions)};
+ }
const lldb::addr_t addr_ptr = args.memoryReference + args.offset;
lldb::SBAddress addr(addr_ptr, dap.target);
if (!addr.IsValid())
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 4f26599a49bac..c00e39c86b92a 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -122,7 +122,7 @@ DecodeMemoryReference(llvm::StringRef memoryReference) {
bool DecodeMemoryReference(const llvm::json::Value &v, llvm::StringLiteral key,
lldb::addr_t &out, llvm::json::Path path,
- bool required) {
+ bool required, bool allow_empty) {
const llvm::json::Object *v_obj = v.getAsObject();
if (!v_obj) {
path.report("expected object");
@@ -145,6 +145,11 @@ bool DecodeMemoryReference(const llvm::json::Value &v,
llvm::StringLiteral key,
return false;
}
+ if (allow_empty && mem_ref_str->empty()) {
+out = LLDB_INVALID_ADDRESS;
+return true;
+ }
+
const std::optional addr_opt =
DecodeMemoryReference(*mem_ref_str);
if (!addr_opt) {
diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index e9094f67b94ec..b8187fe988350 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -156,11 +156,14 @@ DecodeMemoryReference(llvm::StringRef memoryReference);
///Indicates if the key is required to be present, otherwise report an
error
///if the key is missing.
///
+/// \param[in] allow_empty
+///Interpret empty string as a valid value, don't report an error.
+///
/// \return
///Returns \b true if the address was decoded successfully.
bool DecodeMemoryReference(const llvm::json::Value &v, llvm::StringLiteral key,
lldb::addr_t &out, llvm::json::Path path,
- bool required);
+ bool required, bool allow_empty = false);
/// Extract an array of strings for the specified key from an object.
///
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
index b455112cd37d9..fc046d18825ec 100644
--- a/lldb/tools/lldb-
[Lldb-commits] [lldb] [lldb] Enable locate module callback for main executable (PR #160199)
@@ -1303,12 +1306,16 @@
PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) {
lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths(
const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
-const FileSpecList *module_search_paths_ptr,
llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) {
const FileSpec &platform_file = module_spec.GetFileSpec();
- // See if the file is present in any of the module_search_paths_ptr
+ TargetSP target_sp = module_spec.GetTargetSP();
+ FileSpecList module_search_paths;
+ if (target_sp) {
GeorgeHuyubo wrote:
apply elsewhere
https://github.com/llvm/llvm-project/pull/160199
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Correct bridgeOS -> BridgeOS spelling (PR #163479)
https://github.com/JDevlieghere edited https://github.com/llvm/llvm-project/pull/163479 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix a potential use-after-free in StopInfoBreakpoint. (PR #163471)
https://github.com/jimingham edited https://github.com/llvm/llvm-project/pull/163471 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][NativePDB] Create simple types from function arguments and return types (PR #163621)
llvmbot wrote:
@llvm/pr-subscribers-lldb
Author: nerix (Nerixyz)
Changes
When creating all types in a compilation unit, simple types (~> primitive
and pointer types) that were only used in function arguments or return types
weren't created as LLDB `Type`s.
With this PR, they're created when creating the function/method types.
This makes it possible to run the `SymbolFile/PDB/typedefs.test` with both
plugins.
---
Full diff: https://github.com/llvm/llvm-project/pull/163621.diff
4 Files Affected:
- (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
(+25)
- (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
(+2)
- (modified) lldb/test/Shell/SymbolFile/NativePDB/simple-types.cpp (+5-7)
- (modified) lldb/test/Shell/SymbolFile/PDB/typedefs.test (+12-11)
``diff
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index ecd3188b3d564..e76b7a3cf274a 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -754,6 +754,10 @@ TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId
type_id,
TypeSP SymbolFileNativePDB::CreateFunctionType(PdbTypeSymId type_id,
const MemberFunctionRecord &mfr,
CompilerType ct) {
+ if (mfr.ReturnType.isSimple())
+GetOrCreateType(mfr.ReturnType);
+ CreateSimpleArgumentListTypes(mfr.ArgumentList);
+
Declaration decl;
return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr,
LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
@@ -763,12 +767,33 @@ TypeSP
SymbolFileNativePDB::CreateFunctionType(PdbTypeSymId type_id,
TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id,
const ProcedureRecord &pr,
CompilerType ct) {
+ if (pr.ReturnType.isSimple())
+GetOrCreateType(pr.ReturnType);
+ CreateSimpleArgumentListTypes(pr.ArgumentList);
+
Declaration decl;
return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr,
LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
ct, lldb_private::Type::ResolveState::Full);
}
+void SymbolFileNativePDB::CreateSimpleArgumentListTypes(
+llvm::codeview::TypeIndex arglist_ti) {
+ if (arglist_ti.isNoneType())
+return;
+
+ CVType arglist_cvt = m_index->tpi().getType(arglist_ti);
+ if (arglist_cvt.kind() != LF_ARGLIST)
+return; // invalid debug info
+
+ ArgListRecord alr;
+ llvm::cantFail(
+ TypeDeserializer::deserializeAs(arglist_cvt, alr));
+ for (TypeIndex id : alr.getIndices())
+if (!id.isNoneType() && id.isSimple())
+ GetOrCreateType(id);
+}
+
TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) {
if (type_id.index.isSimple())
return CreateSimpleType(type_id.index, ct);
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index a5fef354af65c..11b982e6fc67e 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -255,6 +255,8 @@ class SymbolFileNativePDB : public SymbolFileCommon {
VariableList &variables);
size_t ParseVariablesForBlock(PdbCompilandSymId block_id);
+ void CreateSimpleArgumentListTypes(llvm::codeview::TypeIndex arglist_ti);
+
llvm::Expected GetFileIndex(const CompilandIndexItem &cii,
uint32_t file_id);
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/simple-types.cpp
b/lldb/test/Shell/SymbolFile/NativePDB/simple-types.cpp
index 3781194e2e992..3664b04fd22bd 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/simple-types.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/simple-types.cpp
@@ -3,7 +3,6 @@
// Test that simple types can be found
// RUN: %build --std=c++20 --nodefaultlib --compiler=clang-cl --arch=64 -o
%t.exe -- %s
// RUN: lldb-test symbols %t.exe | FileCheck %s
-// RUN: lldb-test symbols %t.exe | FileCheck --check-prefix=FUNC-PARAMS %s
bool *PB;
bool &RB = *PB;
@@ -101,12 +100,14 @@ int main() {
// CHECK-DAG: Type{{.*}} , name = "float", size = 4, compiler_type =
0x{{[0-9a-f]+}} float
// CHECK-DAG: Type{{.*}} , name = "const float", size = 4, compiler_type =
0x{{[0-9a-f]+}} const float
+// CHECK-DAG: Type{{.*}} , name = "double", size = 8, compiler_type =
0x{{[0-9a-f]+}} double
+
// CHECK-DAG: Type{{.*}} , name = "_Complex float", size = 4, compiler_type =
0x{{[0-9a-f]+}} _Complex float
// CHECK-DAG: Type{{.*}} , name = "_Complex double", size = 8, compiler_type =
0x{{[0-9a-f]+}} _Complex double
-// CHECK-DAG
[Lldb-commits] [clang] [lldb] [Clang] Introduce OverflowBehaviorType for fine-grained overflow control (PR #148914)
kees wrote: tl;dr: I think I understand what you're saying and I think I'm convinced... We seem to be talking about different things. I'm trying to understand what you're describing. It looks like you're trying to say that values that are stored in an OBT variable carry their OB-ness permanently, such that the value cannot be stored to a non-matching OBT variable without being instrumented? I would absolutely love this approach except that I think it makes it unusable, see much further below for applying this to Linux. But just to restate what I think you're saying, given: ``` int __ob_trap src = runtime_256; u8 dest = src; ``` You're saying that the "256(stored in int, with OB trap)" value must trap when stored to "char dest" because bits will be lost. I am saying that the OB is only supposed to be checked when overflow happens for an annotated variable, i.e. when a value is stored to (or used as) an annotated variable. As in, you're saying we go through these steps: - 256 (stored in int, with OB trap) - 256(to be stored in u8, with OB trap) - overflow! 256 truncated to 1 (traps) - 1(stored in u8, no OB) (not performed, since we trapped) Rather than what I'm imagining which is: - 256 (stored in int, with OB trap) - 256(to be stored in u8, no OB) - overflow! 256 truncated to 1 (no trap) - 1(stored in u8, no OB) I'm saying that the _variable_ carries the OB, not the value. You have a later example doing effectively: ``` void takes_u32(u32 value); u64 unannoated; // 2 u32 __ob_trap trapping; // U32_MAX ... takes_u32(trapping * unannotated); ``` Which you're saying needs the "OB follows the value" logic so that we get: ``` (u64 __ob_trap)(u32 __ob_trap)trapping * (u64 __ob_trap)(u64)unannotated // U32_MAX * 2 does not overflow u64 takes_u32((u64 __ob_trap)(U32_MAX * 2) -> u32) // trap because bits lost ``` To me, this is surprising because `u32 value` isn't `__ob_trap`. The reason for doing store-only checking is because I don't think we'll be able to move a codebase to OBT if using an OBT pollutes everything it touches, specifically because current types are ambiguous about whether or not they expect overflow. I'm very worried I won't be able to port Linux to using OBTs (for example for `size_t` to be `unsigned long __ob_trap`) if assignments of non-OBT may start trapping. I think we're going to get a lot of push-back if "surprising" things start happening. https://github.com/llvm/llvm-project/pull/148914 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][PDB] Run `pointers.test` with both plugins (PR #163623)
llvmbot wrote:
@llvm/pr-subscribers-lldb
Author: nerix (Nerixyz)
Changes
The `pointers.test` was only run with the DIA plugin. I made the following
changes:
- Remove the check for the function type.
The types of the function are different in the plugins:
```
Native:
Type{0x00010084} , size = 0, compiler_type = 0x0209aff60060 int (int)
__attribute__((thiscall))
DIA:
Type{0x000a} , name = "f", decl = PointerTypeTest.cpp:8, compiler_type =
0x020bc22356c0 int (int) __attribute__((thiscall))
```
In DIA, each function gets its own type with a name and decl. In the native
plugin, only one unnamed type is created per signature. This matches DWARF.
- The check for the `struct ST` fields was split, because the order of members
and methods is swapped between the plugins. In DIA, the member is first and in
the native plugin the method is first. We still check that both are in the
struct.
- The type names for the local variables are different. The native plugin
includes \`extern "C" main'::\`2'::ST which I added as
an allowed prefix. This comes from the mangled name of the struct `ST` -
`.?AUST@?1??main@@9@`.
- The location of local variables is different. DIA creates one static location
(e.g. `DW_OP_breg6 ESI-52`) whereas the native plugin limits the location to
the block (e.g. `[0x0040100d, 0x00401038): DW_OP_breg6 ESI-52`). This gets
printed on a second line and the `location` starts with `0x:`
- DIA adds a decl for each parameter (and local variable). However, this
information is not contained in the PDB. I'm not sure how DIA calculates this.
It's often wrong and assumes variables are declared earlier. For example, in
this test
([PointerTypeTest.cpp](https://github.com/llvm/llvm-project/blob/2b135b931338a57c38d9c4a34ffdd59877ba82d6/lldb/test/Shell/SymbolFile/PDB/Inputs/PointerTypeTest.cpp)),
it assumes that all local variables of `main` are created on line 4. The
native plugin doesn't include this, so I made the check optional.
---
Full diff: https://github.com/llvm/llvm-project/pull/163623.diff
1 Files Affected:
- (modified) lldb/test/Shell/SymbolFile/PDB/pointers.test (+24-18)
``diff
diff --git a/lldb/test/Shell/SymbolFile/PDB/pointers.test
b/lldb/test/Shell/SymbolFile/PDB/pointers.test
index 29fe171ca97a3..2563ea96d1c9b 100644
--- a/lldb/test/Shell/SymbolFile/PDB/pointers.test
+++ b/lldb/test/Shell/SymbolFile/PDB/pointers.test
@@ -2,38 +2,44 @@ REQUIRES: target-windows, msvc
RUN: mkdir -p %t.dir
RUN: %build --compiler=clang-cl --mode=compile --arch=32 --nodefaultlib
--output=%t.dir/PointerTypeTest.cpp.obj %S/Inputs/PointerTypeTest.cpp
RUN: %build --compiler=msvc --mode=link --arch=32 --nodefaultlib
--output=%t.dir/PointerTypeTest.cpp.exe %t.dir/PointerTypeTest.cpp.obj
-RUN: lldb-test symbols %t.dir/PointerTypeTest.cpp.exe | FileCheck %s
-RUN: lldb-test symbols %t.dir/PointerTypeTest.cpp.exe | FileCheck
--check-prefix=MAIN-ST-F %s
-RUN: lldb-test symbols %t.dir/PointerTypeTest.cpp.exe | FileCheck
--check-prefix=MAIN-ST %s
-RUN: lldb-test symbols %t.dir/PointerTypeTest.cpp.exe | FileCheck
--check-prefix=MAIN %s
-RUN: lldb-test symbols %t.dir/PointerTypeTest.cpp.exe | FileCheck
--check-prefix=F %s
+
+RUN: env LLDB_USE_NATIVE_PDB_READER=0 lldb-test symbols
%t.dir/PointerTypeTest.cpp.exe | FileCheck %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=0 lldb-test symbols
%t.dir/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN-ST-INT %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=0 lldb-test symbols
%t.dir/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN-ST-FN %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=0 lldb-test symbols
%t.dir/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=0 lldb-test symbols
%t.dir/PointerTypeTest.cpp.exe | FileCheck --check-prefix=F %s
+
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols
%t.dir/PointerTypeTest.cpp.exe | FileCheck %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols
%t.dir/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN-ST-INT %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols
%t.dir/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN-ST-FN %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols
%t.dir/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols
%t.dir/PointerTypeTest.cpp.exe | FileCheck --check-prefix=F %s
CHECK: Module [[MOD:.*]]
CHECK: {{^[0-9A-F]+}}: CompileUnit{{[{]0x[0-9a-f]+[}]}}, language = "c++",
file = '{{.*}}\PointerTypeTest.cpp'
-MAIN-ST-F: name = "f"
-MAIN-ST-F-SAME: decl = PointerTypeTest.cpp:8
-MAIN-ST-F-SAME: compiler_type = {{.*}} int (int)
+MAIN-ST-INT-LABEL: name = "ST", size = 4, decl = PointerTypeTest.cpp:6,
compiler_type = {{.*}} struct ST {
+MAIN-ST-INT: int a;
+MAIN-ST-INT-LABEL:}
-MAIN-ST: name = "ST", size = 4, decl = PointerTypeTest.cpp:6, compiler_type =
{{.*}} struct ST {
-MAIN-S
[Lldb-commits] [clang] [lldb] [Clang] Introduce OverflowBehaviorType for fine-grained overflow control (PR #148914)
kees wrote: > You would only get a trap when you get a narrowing conversion, maybe that > should only be the case for _implicit_ conversions? e.g > `(int)some_obt_qualified_64bit_type` - I'm not sure I like that as to me it > feels like the idiomatic casting behaviour would silently truncate, > presumably unexpectedly, e.g the default developer response to an implicit > narrowing warning is just to add `(dest_type)expr` which would silently drop > high bits even though that would seem unexpected? Right this gets to my concern about casts: I don't want a way to return to ambiguous values. > It seems not unreasonable to maybe have something like `__obt_ignore` > qualifier in casts to make it easier to perform a narrowing cast that drops > instrumentation/overflow checks as a usability improvement that makes it > explicit that you do not care about overflow. I want to have overflow behavior be explicit, so I think if we wanted to "strip" an `__ob_trap`, it should get an `__ob_wrap` cast: `(dest_type __ob_wrap)expr` ? > @kees @JustinStitt Are you folk going to be at the US devmeeting? Maybe it > will be easier to go over in person? If not it might be easier to set up a > telcon or something? Yeah, @JustinStitt will be there for sure; I can probably fly down or we can do a video chat. Email me at [email protected] and let's take this offline to coordinate? https://github.com/llvm/llvm-project/pull/148914 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] a1f233a - [lldb] Fix bot failure due to new qSupported packet reply (#163643)
Author: Felipe de Azevedo Piovezan Date: 2025-10-15T14:40:38-07:00 New Revision: a1f233ae07124783b18d9e11351a3e4f7ace05ca URL: https://github.com/llvm/llvm-project/commit/a1f233ae07124783b18d9e11351a3e4f7ace05ca DIFF: https://github.com/llvm/llvm-project/commit/a1f233ae07124783b18d9e11351a3e4f7ace05ca.diff LOG: [lldb] Fix bot failure due to new qSupported packet reply (#163643) When [1] landed, gdbremote server tests had to be updated to understand the new packet field. [1]: https://github.com/llvm/llvm-project/pull/163249 Added: Modified: lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py Removed: diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py index aea6b9fe36b2c..5ba642bbedf74 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py @@ -931,6 +931,7 @@ def add_qSupported_packets(self, client_features=[]): "QNonStop", "SupportedWatchpointTypes", "SupportedCompressions", +"MultiMemRead", ] def parse_qSupported_response(self, context): ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix bot failure due to new qSupported packet reply (PR #163643)
https://github.com/felipepiovezan closed https://github.com/llvm/llvm-project/pull/163643 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] Add multi-session support with shared debugger instances (PR #163653)
https://github.com/qxy11 created
https://github.com/llvm/llvm-project/pull/163653
## Summary:
This change introduces a DAPSessionManager to enable multiple DAP sessions to
share debugger instances when needed, for things like child process debugging
and some scripting hooks that create dynamically new targets.
Changes include:
- Add DAPSessionManager singleton to track and coordinate all active DAP
sessions
- Support attaching to an existing target via its globally unique target ID
(targetId parameter)
- Share debugger instances across sessions when new targets are created
dynamically
- Refactor event thread management to allow sharing event threads between
sessions
- Add eBroadcastBitNewTargetCreated event to notify when new targets are created
- Extract session names from target creation events
- Defer debugger initialization from 'initialize' request to 'launch'/'attach'
requests. The only time the debugger is used currently in between its creation
in `InitializeRequestHandler` and the `Launch` or `Attach` requests is during
the `TelemetryDispatcher` destruction call at the end of the
`DAP::HandleObject` call, so this is safe.
This enables scenarios when new targets are created dynamically so that the
debug adapter can automatically start a new debug session for the spawned
target while sharing the debugger instance.
## Tests:
The refactoring maintains backward compatibility. All existing DAP test cases
pass.
Also added a few basic unit tests for DAPSessionManager
```
>> ninja DAPTests
>> ./tools/lldb/unittests/DAP/DAPTests
>>./bin/llvm-lit -v ../llvm-project/lldb/test/API/tools/lldb-dap/
```
>From 5b94fa5412e8a56ee1ea1fe7e1cd8d9efddcaffb Mon Sep 17 00:00:00 2001
From: qxy11
Date: Wed, 15 Oct 2025 15:47:23 -0700
Subject: [PATCH] [lldb-dap] Add multi-session support with shared debugger
instances
Summary:
This change introduces a DAPSessionManager to enable multiple concurrent
lldb-dap sessions and allow them to share debugger instances when needed.
Key changes:
- Add DAPSessionManager singleton to track and coordinate all active DAP
sessions
- Support attaching to an existing target via unique target ID (targetId
parameter)
- Share debugger instances across sessions when spawning new targets (e.g., GPU
debugging)
- Refactor event thread management to allow sharing event threads between
sessions
- Add eBroadcastBitNewTargetCreated event to notify when new targets are spawned
- Extract session names from target creation events for better identification
- Defer debugger initialization from 'initialize' request to 'launch'/'attach'
requests
This enables scenarios where a native process spawns a new target (like a child
process)
and the debug adapter can automatically start a new debug session for the
spawned
target while sharing the parent's debugger instance.
Tests:
The refactoring maintains backward compatibility. All existing test cases pass.
---
lldb/include/lldb/API/SBTarget.h | 3 +
lldb/include/lldb/Target/Target.h | 9 +
.../test/tools/lldb-dap/dap_server.py | 3 +
lldb/source/API/SBTarget.cpp | 8 +
lldb/source/Target/Target.cpp | 34 ++-
.../tools/lldb-dap/attach/TestDAP_attach.py | 13 +
lldb/tools/lldb-dap/CMakeLists.txt| 1 +
lldb/tools/lldb-dap/DAP.cpp | 231 ++
lldb/tools/lldb-dap/DAP.h | 25 +-
lldb/tools/lldb-dap/DAPSessionManager.cpp | 168 +
lldb/tools/lldb-dap/DAPSessionManager.h | 119 +
.../lldb-dap/Handler/AttachRequestHandler.cpp | 26 +-
.../Handler/InitializeRequestHandler.cpp | 58 +
.../lldb-dap/Handler/LaunchRequestHandler.cpp | 4 +
.../lldb-dap/Protocol/ProtocolRequests.cpp| 3 +-
.../lldb-dap/Protocol/ProtocolRequests.h | 3 +
lldb/tools/lldb-dap/package.json | 4 +
lldb/tools/lldb-dap/tool/lldb-dap.cpp | 53 ++--
lldb/unittests/DAP/CMakeLists.txt | 1 +
lldb/unittests/DAP/DAPSessionManagerTest.cpp | 177 ++
.../gn/secondary/lldb/tools/lldb-dap/BUILD.gn | 1 +
21 files changed, 802 insertions(+), 142 deletions(-)
create mode 100644 lldb/tools/lldb-dap/DAPSessionManager.cpp
create mode 100644 lldb/tools/lldb-dap/DAPSessionManager.h
create mode 100644 lldb/unittests/DAP/DAPSessionManagerTest.cpp
diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index 173fd05b54a13..1d251763a826a 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -44,6 +44,7 @@ class LLDB_API SBTarget {
eBroadcastBitWatchpointChanged = (1 << 3),
eBroadcastBitSymbolsLoaded = (1 << 4),
eBroadcastBitSymbolsChanged = (1 << 5),
+eBroadcastBitNewTargetCreated = (1 << 6),
};
// Constructors
@@ -69,6 +70,8 @@ class LLDB_API SBTarget {
static lldb::SBModule GetModuleAtIndexFromEvent(const uint32_t idx,
[Lldb-commits] [lldb] [lldb] Introduce ScriptedFrameProvider for real threads (PR #161870)
@@ -1400,6 +1407,9 @@ class Thread : public std::enable_shared_from_this, /// The Thread backed by this thread, if any. lldb::ThreadWP m_backed_thread; + /// The Scripted Frame Provider, if any. + lldb::ScriptedFrameProviderSP m_frame_provider_sp; JDevlieghere wrote: Would it be more ergonomic to have one StackFrameProvider per target, rather than one per thread? Conceptually, it's probably nice to be closer to the thread level, but I wonder if that doesn't complicate instantiation, as threads can come and go on each stop. https://github.com/llvm/llvm-project/pull/161870 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Unify the timeouts for the DAP tests (PR #163292)
@@ -155,15 +152,13 @@ def assertCapabilityIsNotSet(self, key: str, msg: Optional[str] = None) -> None: if key in self.dap_server.capabilities: self.assertEqual(self.dap_server.capabilities[key], False, msg) -def verify_breakpoint_hit( -self, breakpoint_ids: List[Union[int, str]], timeout: float = DEFAULT_TIMEOUT -): +def verify_breakpoint_hit(self, breakpoint_ids: List[Union[int, str]]): JDevlieghere wrote: +1, this has long bothered me as well. https://github.com/llvm/llvm-project/pull/163292 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Test gardening, enabling tests and improving doc comments. (PR #140777)
https://github.com/ashgti updated
https://github.com/llvm/llvm-project/pull/140777
>From 048b67a1ac5f54f0cbae728b67cf8b6cbbe9ce63 Mon Sep 17 00:00:00 2001
From: John Harrison
Date: Wed, 15 Oct 2025 09:12:13 -0700
Subject: [PATCH] [lldb-dap] Experimenting with async in DAP tests.
This is not fully tested yet, but the basic approach is to remove the
background thread that can cause races in the tests.
Instead, I am using an asyncio event loop to read packets, and the tests can
await on the loop to process packets as needed.
With further refactoring we should be able to push the async operations further
up the stack into the test cases themselves.
---
lldb/packages/Python/lldbsuite/test/dotest.py | 3 +-
.../test/tools/lldb-dap/dap_server.py | 900 +-
.../test/tools/lldb-dap/lldbdap_testcase.py | 124 +--
.../TestDAP_breakpointAssembly.py | 2 +-
.../tools/lldb-dap/console/TestDAP_console.py | 4 +-
lldb/test/API/tools/lldb-dap/io/TestDAP_io.py | 50 +-
.../tools/lldb-dap/launch/TestDAP_launch.py | 43 +-
.../tools/lldb-dap/server/TestDAP_server.py | 41 +-
8 files changed, 574 insertions(+), 593 deletions(-)
diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py
b/lldb/packages/Python/lldbsuite/test/dotest.py
index 63f7df4de1894..8d9e3c6c16054 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -300,7 +300,8 @@ def parseOptionsAndInitTestdirs():
configuration.libcxx_include_target_dir =
args.libcxx_include_target_dir
configuration.libcxx_library_dir = args.libcxx_library_dir
-configuration.cmake_build_type = args.cmake_build_type.lower()
+if args.cmake_build_type:
+configuration.cmake_build_type = args.cmake_build_type.lower()
if args.channels:
lldbtest_config.channels = args.channels
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 8eb64b4ab8b2b..39c17fc957357 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -1,28 +1,30 @@
#!/usr/bin/env python
+import asyncio
import binascii
+import enum
import json
import optparse
import os
-import pprint
+
+# import pprint
+import signal
import socket
import string
import subprocess
-import signal
import sys
-import threading
-import time
+from warnings import warn
from typing import (
Any,
+cast,
Optional,
Dict,
-cast,
List,
Callable,
IO,
Union,
-BinaryIO,
TextIO,
+Tuple,
TypedDict,
Literal,
)
@@ -44,7 +46,7 @@ class Request(TypedDict, total=False):
arguments: Any
-class Response(TypedDict):
+class Response(TypedDict, total=False):
type: Literal["response"]
seq: int
request_seq: int
@@ -62,29 +64,27 @@ class Source(TypedDict, total=False):
path: str
sourceReference: int
-@staticmethod
-def build(
-*,
-name: Optional[str] = None,
-path: Optional[str] = None,
-source_reference: Optional[int] = None,
-) -> "Source":
-"""Builds a source from the given name, path or source_reference."""
-if not name and not path and not source_reference:
-raise ValueError(
-"Source.build requires either name, path, or source_reference"
-)
-s = Source()
-if name:
-s["name"] = name
-if path:
-if not name:
-s["name"] = os.path.basename(path)
-s["path"] = path
-if source_reference is not None:
-s["sourceReference"] = source_reference
-return s
+def source(
+*,
+name: Optional[str] = None,
+path: Optional[str] = None,
+source_reference: Optional[int] = None,
+) -> "Source":
+"""Builds a source from the given name, path or source_reference."""
+if not name and not path and not source_reference:
+raise ValueError("Source.build requires either name, path, or
source_reference")
+
+s: Source = {}
+if name:
+s["name"] = name
+if path:
+if not name:
+s["name"] = os.path.basename(path)
+s["path"] = path
+if source_reference is not None:
+s["sourceReference"] = source_reference
+return s
class Breakpoint(TypedDict, total=False):
@@ -92,9 +92,9 @@ class Breakpoint(TypedDict, total=False):
verified: bool
source: Source
-@staticmethod
-def is_verified(src: "Breakpoint") -> bool:
-return src.get("verified", False)
+
+def is_verified(src: "Breakpoint") -> bool:
+return src.get("verified", False)
def dump_memory(base_addr, data, num_per_line, outfile):
@@ -167,70 +167,131 @@ def packet_type_is(packet, packet_type):
return "type" in packet and packet["type"] == packe
[Lldb-commits] [lldb] [lldb-dap] Unify the timeouts for the DAP tests (PR #163292)
https://github.com/JDevlieghere closed https://github.com/llvm/llvm-project/pull/163292 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [clang-tools-extra] [flang] [lldb] [llvm] [clang] Move options from clangDriver into new clangOptions library (NFC) (PR #163659)
https://github.com/naveen-seth edited https://github.com/llvm/llvm-project/pull/163659 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [clang-tools-extra] [flang] [lldb] [llvm] [clang] Move options from clangDriver into new clangOptions library (NFC) (PR #163659)
@@ -10,8 +10,8 @@ // //===--===// -#ifndef LLVM_CLANG_DRIVER_OPTIONUTILS_H -#define LLVM_CLANG_DRIVER_OPTIONUTILS_H +#ifndef LLVM_CLANG_OPTIONUTILS_H +#define LLVM_CLANG_OPTIONUTILS_H naveen-seth wrote: Thank you for quick the review! Fixed. https://github.com/llvm/llvm-project/pull/163659 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [clang-tools-extra] [flang] [lldb] [llvm] [clang] Move options from clangDriver into new clangOptions library (NFC) (PR #163659)
https://github.com/naveen-seth edited https://github.com/llvm/llvm-project/pull/163659 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [clang-tools-extra] [flang] [lldb] [llvm] [clang] Move options from clangDriver into new clangOptions library (NFC) (PR #163659)
https://github.com/naveen-seth edited https://github.com/llvm/llvm-project/pull/163659 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] d0d001d - [lldb] Support shared cache relative objc method types (#163663)
Author: Jonas Devlieghere
Date: 2025-10-15T19:52:35-07:00
New Revision: d0d001df99fdd4bf8b727b79c88951d3194e38f6
URL:
https://github.com/llvm/llvm-project/commit/d0d001df99fdd4bf8b727b79c88951d3194e38f6
DIFF:
https://github.com/llvm/llvm-project/commit/d0d001df99fdd4bf8b727b79c88951d3194e38f6.diff
LOG: [lldb] Support shared cache relative objc method types (#163663)
Support the types and name field in the relative method list to be
relative to a buffer in the shared cache, not relative to the field in
the method list itself.
A new magic bit, 0x2000, is attached to method lists where the types
are encoded in this way. This is covered by the existing tests when
running against a shared cache that uses this encoding.
rdar://147545351
Added:
Modified:
lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
Removed:
diff --git
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index 6d8f41aef1ffc..460c503b25c73 100644
---
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -260,6 +260,7 @@ bool ClassDescriptorV2::method_list_t::Read(Process
*process,
uint32_t entsize = extractor.GetU32_unchecked(&cursor);
m_is_small = (entsize & 0x8000) != 0;
m_has_direct_selector = (entsize & 0x4000) != 0;
+ m_has_relative_types = (entsize & 0x2000) != 0;
m_entsize = entsize & 0xfffc;
m_count = extractor.GetU32_unchecked(&cursor);
m_first_ptr = addr + cursor;
@@ -269,8 +270,9 @@ bool ClassDescriptorV2::method_list_t::Read(Process
*process,
llvm::SmallVector
ClassDescriptorV2::ReadMethods(llvm::ArrayRef addresses,
- lldb::addr_t relative_selector_base_addr,
- bool is_small, bool has_direct_sel) const {
+ lldb::addr_t relative_string_base_addr,
+ bool is_small, bool has_direct_sel,
+ bool has_relative_types) const {
lldb_private::Process *process = m_runtime.GetProcess();
if (!process)
return {};
@@ -297,8 +299,8 @@ ClassDescriptorV2::ReadMethods(llvm::ArrayRef
addresses,
process->GetByteOrder(),
process->GetAddressByteSize());
methods.push_back(method_t());
-methods.back().Read(extractor, process, addr, relative_selector_base_addr,
-is_small, has_direct_sel);
+methods.back().Read(extractor, process, addr, relative_string_base_addr,
+is_small, has_direct_sel, has_relative_types);
}
return methods;
@@ -306,8 +308,9 @@ ClassDescriptorV2::ReadMethods(llvm::ArrayRef
addresses,
bool ClassDescriptorV2::method_t::Read(DataExtractor &extractor,
Process *process, lldb::addr_t addr,
- lldb::addr_t
relative_selector_base_addr,
- bool is_small, bool has_direct_sel) {
+ lldb::addr_t relative_string_base_addr,
+ bool is_small, bool has_direct_sel,
+ bool has_relative_types) {
lldb::offset_t cursor = 0;
if (is_small) {
@@ -323,10 +326,13 @@ bool ClassDescriptorV2::method_t::Read(DataExtractor
&extractor,
m_name_ptr = process->ReadPointerFromMemory(m_name_ptr, error);
if (error.Fail())
return false;
-} else if (relative_selector_base_addr != LLDB_INVALID_ADDRESS) {
- m_name_ptr = relative_selector_base_addr + nameref_offset;
+} else if (relative_string_base_addr != LLDB_INVALID_ADDRESS) {
+ m_name_ptr = relative_string_base_addr + nameref_offset;
}
-m_types_ptr = addr + 4 + types_offset;
+if (has_relative_types)
+ m_types_ptr = relative_string_base_addr + types_offset;
+else
+ m_types_ptr = addr + 4 + types_offset;
m_imp_ptr = addr + 8 + imp_offset;
} else {
m_name_ptr = extractor.GetAddress_unchecked(&cursor);
@@ -481,7 +487,8 @@ bool ClassDescriptorV2::ProcessMethodList(
llvm::SmallVector methods =
ReadMethods(addresses, m_runtime.GetRelativeSelectorBaseAddr(),
- method_list.m_is_small, method_list.m_has_direct_selector);
+ method_list.m_is_small, method_list.m_has_direct_selector,
+ method_list.m_has_relative_types);
for (const auto &method : methods)
if (instance_method_func(method.m_name.c_str(), method.m_types.c_str()))
di
