[Lldb-commits] [lldb] [LLDB] Add Lexer (with tests) for DIL (Data Inspection Language). (PR #123521)

2025-01-29 Thread Pavel Labath via lldb-commits

labath wrote:

I agree with everything except for the last part. The current parser already 
threats `[]` [very 
specially](https://github.com/llvm/llvm-project/blob/89ca3e72ca03efbbfb5ae9b1c71d81f2d1753521/lldb/source/Target/StackFrame.cpp#L781).
 I think it has to do that so it can treat pointers as C arrays (and then it 
just special cases synthetic objects). I think that's a (mostly *) reasonable 
setup that we could replicate in the new DIL implementation, particularly as we 
would need special handling of `[]` to implement things like `[i+1]`.

FWIW, I believe that the main source of keywords in Caroline's implementation 
is types (for casts). I think they could be handled generically (just ask the 
target whether the identifier names a type), were it not for the nasty C(++) 
habit of creating multiword types (`unsigned long long long long int`). Still, 
it feels there ought to be recognise these without making `unsigned` a 
full-fledged keyword.

(*) I was recently made aware of an unfortunate difference in behavior of 
`frame var` and `expr` for map types:
```
(lldb) v m
(std::map) m = size=3 {
  [0] = (first = -42, second = -47)
  [1] = (first = 0, second = 42)
  [2] = (first = 42, second = 47)
}
(lldb) v m[0]
(std::__1::__value_type::value_type) m[0] = (first = -42, second = 
-47)
(lldb) expr m[0]
(std::map::mapped_type) $0 = 42
```
I know that these are different languages, but this still seems like it could 
confuse some people. I don't have any specific ideas on how to fix/improve this 
though...

https://github.com/llvm/llvm-project/pull/123521
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Fix Block::GetRangeIndexContainingAddress for discontinuous functions (PR #124931)

2025-01-29 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Pavel Labath (labath)


Changes

This is a followup to #122440, which changed function-relative 
calculations to use the function entry point rather than the lowest address of 
the function (but missed this usage). Like in #116777, the logic is 
changed to use file addresses instead of section offsets (as not all parts of 
the function have to be in the same section).

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


2 Files Affected:

- (modified) lldb/source/Symbol/Block.cpp (+19-32) 
- (modified) lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s 
(+24-13) 


``diff
diff --git a/lldb/source/Symbol/Block.cpp b/lldb/source/Symbol/Block.cpp
index 139fa06d08fca5..bddb015333e09c 100644
--- a/lldb/source/Symbol/Block.cpp
+++ b/lldb/source/Symbol/Block.cpp
@@ -243,25 +243,15 @@ bool Block::GetRangeContainingAddress(const Address &addr,
   AddressRange &range) {
   Function *function = CalculateSymbolContextFunction();
   if (function) {
-const AddressRange &func_range = function->GetAddressRange();
-if (addr.GetModule() == func_range.GetBaseAddress().GetModule()) {
-  const addr_t file_addr = addr.GetFileAddress();
-  const addr_t func_file_addr =
-  func_range.GetBaseAddress().GetFileAddress();
-  if (file_addr >= func_file_addr &&
-  file_addr < func_file_addr + func_range.GetByteSize()) {
-addr_t offset = file_addr - func_file_addr;
-
-const Range *range_ptr = m_ranges.FindEntryThatContains(offset);
-
-if (range_ptr) {
-  range.GetBaseAddress() =
-  Address(func_file_addr + range_ptr->GetRangeBase(),
-  addr.GetModule()->GetSectionList());
-  range.SetByteSize(range_ptr->GetByteSize());
-  return true;
-}
-  }
+if (uint32_t idx = GetRangeIndexContainingAddress(addr);
+idx != UINT32_MAX) {
+  const Range *range_ptr = m_ranges.GetEntryAtIndex(idx);
+  assert(range_ptr);
+
+  range.GetBaseAddress() = function->GetAddress();
+  range.GetBaseAddress().Slide(range_ptr->GetRangeBase());
+  range.SetByteSize(range_ptr->GetByteSize());
+  return true;
 }
   }
   range.Clear();
@@ -278,19 +268,16 @@ bool Block::GetRangeContainingLoadAddress(lldb::addr_t 
load_addr,
 
 uint32_t Block::GetRangeIndexContainingAddress(const Address &addr) {
   Function *function = CalculateSymbolContextFunction();
-  if (function) {
-const AddressRange &func_range = function->GetAddressRange();
-if (addr.GetSection() == func_range.GetBaseAddress().GetSection()) {
-  const addr_t addr_offset = addr.GetOffset();
-  const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
-  if (addr_offset >= func_offset &&
-  addr_offset < func_offset + func_range.GetByteSize()) {
-addr_t offset = addr_offset - func_offset;
-return m_ranges.FindEntryIndexThatContains(offset);
-  }
-}
-  }
-  return UINT32_MAX;
+  if (!function)
+return UINT32_MAX;
+
+  const Address &func_addr = function->GetAddress();
+  if (addr.GetModule() != func_addr.GetModule())
+return UINT32_MAX;
+
+  const addr_t file_addr = addr.GetFileAddress();
+  const addr_t func_file_addr = func_addr.GetFileAddress();
+  return m_ranges.FindEntryIndexThatContains(file_addr - func_file_addr);
 }
 
 bool Block::GetRangeAtIndex(uint32_t range_idx, AddressRange &range) {
diff --git a/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s 
b/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s
index 2e2bc52cd3ff99..4d42c50467da06 100644
--- a/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s
+++ b/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s
@@ -6,15 +6,22 @@
 
 # CHECK: Found 1 function(s).
 # CHECK: foo: [input.o[0x0-0xe), input.o[0x14-0x1c)]
-# CHECK-NEXT: input.o[0x0]: cmpl   $0x0, %edi
-# CHECK-NEXT: input.o[0x3]: je 0x14
-# CHECK-NEXT: input.o[0x5]: jmp0x7
-# CHECK-NEXT: input.o[0x7]: callq  0xe
-# CHECK-NEXT: input.o[0xc]: jmp0x1b
+# CHECK-NEXT: input.o[0x0]: callq  0xe
+# CHECK-NEXT: input.o[0x5]: jmp0x1b
+# CHECK-NEXT: input.o[0x7]: cmpl   $0x0, %edi
+# CHECK-NEXT: input.o[0xa]: je 0x14
+# CHECK-NEXT: input.o[0xc]: jmp0x0
 # CHECK-EMPTY:
 # CHECK-NEXT: input.o[0x14]: callq  0x19
 # CHECK-NEXT: input.o[0x19]: jmp0x1b
 # CHECK-NEXT: input.o[0x1b]: retq
+# CHECK-NEXT: offset 0x00 => index 0
+# CHECK-NEXT: offset 0x0c => index 0
+# CHECK-NEXT: offset 0x0e => index 
+# CHECK-NEXT: offset 0x13 => index 
+# CHECK-NEXT: offset 0x14 => index 1
+# CHECK-NEXT: offset 0x1b => index 1
+# CHECK-NEXT: offset 0x1c => index 
 
 
 #--- script.py
@@ -28,6 +35,10 @@ def __lldb_init_module(debugger, internal_dict):
 fn = ctx.function
 print(f"{fn.name}: {fn.GetRanges()}")
 print(fn.GetInstructions(target))
+text = fn.addr.section
+ 

[Lldb-commits] [lldb] [lldb] Fix Block::GetRangeIndexContainingAddress for discontinuous functions (PR #124931)

2025-01-29 Thread Pavel Labath via lldb-commits

https://github.com/labath created 
https://github.com/llvm/llvm-project/pull/124931

This is a followup to #122440, which changed function-relative calculations to 
use the function entry point rather than the lowest address of the function 
(but missed this usage). Like in #116777, the logic is changed to use file 
addresses instead of section offsets (as not all parts of the function have to 
be in the same section).

>From 7e4fa296561789ae95980ac0c1468573e80ef0cc Mon Sep 17 00:00:00 2001
From: Pavel Labath 
Date: Wed, 29 Jan 2025 16:15:44 +0100
Subject: [PATCH] [lldb] Fix Block::GetRangeIndexContainingAddress for
 discontinuous functions

This is a followup to #122440, which changed function-relative
calculations to use the function entry point rather than the lowest
address of the function (but missed this usage). Like in #116777, the
logic is changed to use file addresses instead of section offsets (as
not all parts of the function have to be in the same section).
---
 lldb/source/Symbol/Block.cpp  | 51 +++
 .../Python/sb_function_ranges.s   | 37 +-
 2 files changed, 43 insertions(+), 45 deletions(-)

diff --git a/lldb/source/Symbol/Block.cpp b/lldb/source/Symbol/Block.cpp
index 139fa06d08fca5..bddb015333e09c 100644
--- a/lldb/source/Symbol/Block.cpp
+++ b/lldb/source/Symbol/Block.cpp
@@ -243,25 +243,15 @@ bool Block::GetRangeContainingAddress(const Address &addr,
   AddressRange &range) {
   Function *function = CalculateSymbolContextFunction();
   if (function) {
-const AddressRange &func_range = function->GetAddressRange();
-if (addr.GetModule() == func_range.GetBaseAddress().GetModule()) {
-  const addr_t file_addr = addr.GetFileAddress();
-  const addr_t func_file_addr =
-  func_range.GetBaseAddress().GetFileAddress();
-  if (file_addr >= func_file_addr &&
-  file_addr < func_file_addr + func_range.GetByteSize()) {
-addr_t offset = file_addr - func_file_addr;
-
-const Range *range_ptr = m_ranges.FindEntryThatContains(offset);
-
-if (range_ptr) {
-  range.GetBaseAddress() =
-  Address(func_file_addr + range_ptr->GetRangeBase(),
-  addr.GetModule()->GetSectionList());
-  range.SetByteSize(range_ptr->GetByteSize());
-  return true;
-}
-  }
+if (uint32_t idx = GetRangeIndexContainingAddress(addr);
+idx != UINT32_MAX) {
+  const Range *range_ptr = m_ranges.GetEntryAtIndex(idx);
+  assert(range_ptr);
+
+  range.GetBaseAddress() = function->GetAddress();
+  range.GetBaseAddress().Slide(range_ptr->GetRangeBase());
+  range.SetByteSize(range_ptr->GetByteSize());
+  return true;
 }
   }
   range.Clear();
@@ -278,19 +268,16 @@ bool Block::GetRangeContainingLoadAddress(lldb::addr_t 
load_addr,
 
 uint32_t Block::GetRangeIndexContainingAddress(const Address &addr) {
   Function *function = CalculateSymbolContextFunction();
-  if (function) {
-const AddressRange &func_range = function->GetAddressRange();
-if (addr.GetSection() == func_range.GetBaseAddress().GetSection()) {
-  const addr_t addr_offset = addr.GetOffset();
-  const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
-  if (addr_offset >= func_offset &&
-  addr_offset < func_offset + func_range.GetByteSize()) {
-addr_t offset = addr_offset - func_offset;
-return m_ranges.FindEntryIndexThatContains(offset);
-  }
-}
-  }
-  return UINT32_MAX;
+  if (!function)
+return UINT32_MAX;
+
+  const Address &func_addr = function->GetAddress();
+  if (addr.GetModule() != func_addr.GetModule())
+return UINT32_MAX;
+
+  const addr_t file_addr = addr.GetFileAddress();
+  const addr_t func_file_addr = func_addr.GetFileAddress();
+  return m_ranges.FindEntryIndexThatContains(file_addr - func_file_addr);
 }
 
 bool Block::GetRangeAtIndex(uint32_t range_idx, AddressRange &range) {
diff --git a/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s 
b/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s
index 2e2bc52cd3ff99..4d42c50467da06 100644
--- a/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s
+++ b/lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s
@@ -6,15 +6,22 @@
 
 # CHECK: Found 1 function(s).
 # CHECK: foo: [input.o[0x0-0xe), input.o[0x14-0x1c)]
-# CHECK-NEXT: input.o[0x0]: cmpl   $0x0, %edi
-# CHECK-NEXT: input.o[0x3]: je 0x14
-# CHECK-NEXT: input.o[0x5]: jmp0x7
-# CHECK-NEXT: input.o[0x7]: callq  0xe
-# CHECK-NEXT: input.o[0xc]: jmp0x1b
+# CHECK-NEXT: input.o[0x0]: callq  0xe
+# CHECK-NEXT: input.o[0x5]: jmp0x1b
+# CHECK-NEXT: input.o[0x7]: cmpl   $0x0, %edi
+# CHECK-NEXT: input.o[0xa]: je 0x14
+# CHECK-NEXT: input.o[0xc]: jmp0x0
 # CHECK-EMPTY:
 # CHECK-NEXT: input.o[0x14]: callq  0x19
 # CHECK-NEXT: input.o[0x19]: jmp0x1b
 # CHECK-NEXT: input.o[0x1b]: retq
+

[Lldb-commits] [lldb] 9ea64dd - [lldb] Make Python >= 3.8 required for LLDB 21 (#124735)

2025-01-29 Thread via lldb-commits

Author: David Spickett
Date: 2025-01-29T09:56:41Z
New Revision: 9ea64dd8781328d831d7c69a586f0c84dece1c11

URL: 
https://github.com/llvm/llvm-project/commit/9ea64dd8781328d831d7c69a586f0c84dece1c11
DIFF: 
https://github.com/llvm/llvm-project/commit/9ea64dd8781328d831d7c69a586f0c84dece1c11.diff

LOG: [lldb] Make Python >= 3.8 required for LLDB 21 (#124735)

As decided on
https://discourse.llvm.org/t/rfc-lets-document-and-enforce-a-minimum-python-version-for-lldb/82731.

LLDB 20 recommended `>= 3.8` but did not remove support for anything
earlier. Now we are in what will become LLDB 21, so I'm removing that
support and making
`>= 3.8` required.

See https://docs.python.org/3/c-api/apiabiversion.html#c.PY_VERSION_HEX
for the format of PY_VERSION_HEX.

Added: 


Modified: 
lldb/docs/resources/build.rst
lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h
lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
llvm/docs/ReleaseNotes.md

Removed: 




diff  --git a/lldb/docs/resources/build.rst b/lldb/docs/resources/build.rst
index c0d3c580d631c1..214c5f63f2c73b 100644
--- a/lldb/docs/resources/build.rst
+++ b/lldb/docs/resources/build.rst
@@ -62,7 +62,7 @@ CMake configuration error.
 
+---+--+--+
 | Libxml2   | XML  
| ``LLDB_ENABLE_LIBXML2``  |
 
+---+--+--+
-| Python| Python scripting. >= 3.0 is required, >= 3.8 is 
recommended. | ``LLDB_ENABLE_PYTHON``   |
+| Python| Python scripting. >= 3.8 is required.
| ``LLDB_ENABLE_PYTHON``   |
 
+---+--+--+
 | Lua   | Lua scripting. Lua 5.3 and 5.4 are supported.
| ``LLDB_ENABLE_LUA``  |
 
+---+--+--+

diff  --git 
a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp 
b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index a0f8cf954f8040..1340425aade438 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -73,10 +73,8 @@ Expected 
python::As(Expected &&obj) {
 static bool python_is_finalizing() {
 #if PY_VERSION_HEX >= 0x030d
   return Py_IsFinalizing();
-#elif PY_VERSION_HEX >= 0x0307
-  return _Py_IsFinalizing();
 #else
-  return _Py_Finalizing != nullptr;
+  return _Py_IsFinalizing();
 #endif
 }
 
@@ -810,7 +808,6 @@ bool PythonCallable::Check(PyObject *py_obj) {
   return PyCallable_Check(py_obj);
 }
 
-#if PY_VERSION_HEX >= 0x0303
 static const char get_arg_info_script[] = R"(
 from inspect import signature, Parameter, ismethod
 from collections import namedtuple
@@ -832,15 +829,12 @@ def main(f):
 raise Exception(f'unknown parameter kind: {kind}')
 return ArgInfo(count, varargs)
 )";
-#endif
 
 Expected PythonCallable::GetArgInfo() const {
   ArgInfo result = {};
   if (!IsValid())
 return nullDeref();
 
-#if PY_VERSION_HEX >= 0x0303
-
   // no need to synchronize access to this global, we already have the GIL
   static PythonScript get_arg_info(get_arg_info_script);
   Expected pyarginfo = get_arg_info(*this);
@@ -852,57 +846,6 @@ Expected 
PythonCallable::GetArgInfo() const {
   cantFail(As(pyarginfo.get().GetAttribute("has_varargs")));
   result.max_positional_args = has_varargs ? ArgInfo::UNBOUNDED : count;
 
-#else
-  PyObject *py_func_obj;
-  bool is_bound_method = false;
-  bool is_class = false;
-
-  if (PyType_Check(m_py_obj) || PyClass_Check(m_py_obj)) {
-auto init = GetAttribute("__init__");
-if (!init)
-  return init.takeError();
-py_func_obj = init.get().get();
-is_class = true;
-  } else {
-py_func_obj = m_py_obj;
-  }
-
-  if (PyMethod_Check(py_func_obj)) {
-py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
-PythonObject im_self = GetAttributeValue("im_self");
-if (im_self.IsValid() && !im_self.IsNone())
-  is_bound_method = true;
-  } else {
-// see if this is a callable object with an __call__ method
-if (!PyFunction_Check(py_func_obj)) {
-  PythonObject __call__ = GetAttributeValue("__call__");
-  if (__call__.IsValid()) {
-auto __callable__ = __call__.AsType();
-if (__callable__.IsValid()) {
-  py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
-  PythonObject im_self = __callable

[Lldb-commits] [lldb] [llvm] [lldb] Make Python >= 3.8 required for LLDB 21 (PR #124735)

2025-01-29 Thread David Spickett via lldb-commits

https://github.com/DavidSpickett closed 
https://github.com/llvm/llvm-project/pull/124735
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring lldb-dap port listening mode to allow multiple connections. (PR #116392)

2025-01-29 Thread Pavel Labath via lldb-commits


@@ -5028,48 +5021,128 @@ int main(int argc, char *argv[]) {
 #endif
 
   // Initialize LLDB first before we do anything.
-  lldb::SBDebugger::Initialize();
+  lldb::SBError error = lldb::SBDebugger::InitializeWithErrorHandling();
+  if (error.Fail()) {
+llvm::errs() << "Failed to initialize LLDB: " << error.GetCString() << 
"\n";
+return EXIT_FAILURE;
+  }
 
   // Terminate the debugger before the C++ destructor chain kicks in.
   auto terminate_debugger =
   llvm::make_scope_exit([] { lldb::SBDebugger::Terminate(); });
 
-  DAP dap = DAP(program_path.str(), default_repl_mode);
+  auto HandleClient = [=](int out_fd, int err_fd, StreamDescriptor input,
+  StreamDescriptor output) {
+DAP dap = DAP(program_path, log, default_repl_mode, pre_init_commands);
+dap.input.descriptor = std::move(input);
+dap.output.descriptor = std::move(output);
+RegisterRequestCallbacks(dap);
+
+if (auto Err = dap.ConfigureIO(out_fd, err_fd)) {
+  if (log)
+*log << "configureIO failed: " << llvm::toStringWithoutConsuming(Err)
+ << "\n";
+  std::cerr << "failed to configureIO: " << llvm::toString(std::move(Err))

labath wrote:

That's good but beware `os << error` does not "consume" (set the ["checked" 
bit](https://llvm.org/docs/ProgrammersManual.html#recoverable-errors)), on the 
llvm::Error object (which means it will trigger an assert in debug mode). You 
need to consume it somehow, e.g., via toString, or `logAllUnhandledErrors` (the 
latter works best when the entire "main" function is wrapped in something 
returning an error object

https://github.com/llvm/llvm-project/pull/116392
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb] Make Python >= 3.8 required for LLDB 21 (PR #124735)

2025-01-29 Thread David Spickett via lldb-commits

https://github.com/DavidSpickett edited 
https://github.com/llvm/llvm-project/pull/124735
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] db567ea - [lldb][NFC] Format part of ScriptInterpreterPython.cpp

2025-01-29 Thread David Spickett via lldb-commits

Author: David Spickett
Date: 2025-01-29T09:59:34Z
New Revision: db567eaca07133a374991153635a119d9eec066b

URL: 
https://github.com/llvm/llvm-project/commit/db567eaca07133a374991153635a119d9eec066b
DIFF: 
https://github.com/llvm/llvm-project/commit/db567eaca07133a374991153635a119d9eec066b.diff

LOG: [lldb][NFC] Format part of ScriptInterpreterPython.cpp

Was flagged in https://github.com/llvm/llvm-project/pull/124735
but done separately so it didn't get in the way of that.

Added: 


Modified: 
lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp

Removed: 




diff  --git 
a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp 
b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index e78e6068debb4f..f4efb00161f8b8 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -152,12 +152,14 @@ struct InitializePythonRAII {
 
 private:
   void InitializeThreadsPrivate() {
-// Since Python 3.7 `Py_Initialize` calls `PyEval_InitThreads` inside itself,
-// so there is no way to determine whether the embedded interpreter
-// was already initialized by some external code. `PyEval_ThreadsInitialized`
-// would always return `true` and `PyGILState_Ensure/Release` flow would be
-// executed instead of unlocking GIL with `PyEval_SaveThread`. When
-// an another thread calls `PyGILState_Ensure` it would get stuck in deadlock.
+// Since Python 3.7 `Py_Initialize` calls `PyEval_InitThreads` inside
+// itself, so there is no way to determine whether the embedded interpreter
+// was already initialized by some external code.
+// `PyEval_ThreadsInitialized` would always return `true` and
+// `PyGILState_Ensure/Release` flow would be executed instead of unlocking
+// GIL with `PyEval_SaveThread`. When an another thread calls
+// `PyGILState_Ensure` it would get stuck in deadlock.
+
 // The only case we should go further and acquire the GIL: it is unlocked.
 if (PyGILState_Check())
   return;



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring lldb-dap port listening mode to allow multiple connections. (PR #116392)

2025-01-29 Thread Pavel Labath via lldb-commits


@@ -5058,72 +5053,148 @@ int main(int argc, char *argv[]) {
   auto terminate_debugger =
   llvm::make_scope_exit([] { lldb::SBDebugger::Terminate(); });
 
-  StreamDescriptor input;
-  StreamDescriptor output;
-  std::FILE *redirectOut = nullptr;
-  std::FILE *redirectErr = nullptr;
-  if (portno != -1) {
-printf("Listening on port %i...\n", portno);
-SOCKET socket_fd = AcceptConnection(log.get(), portno);
-if (socket_fd < 0)
-  return EXIT_FAILURE;
+  std::vector pre_init_commands;
+  for (const std::string &arg :
+   input_args.getAllArgValues(OPT_pre_init_command)) {
+pre_init_commands.push_back(arg);
+  }
 
-input = StreamDescriptor::from_socket(socket_fd, true);
-output = StreamDescriptor::from_socket(socket_fd, false);
-  } else {
-#if defined(_WIN32)
-// Windows opens stdout and stdin in text mode which converts \n to 13,10
-// while the value is just 10 on Darwin/Linux. Setting the file mode to
-// binary fixes this.
-int result = _setmode(fileno(stdout), _O_BINARY);
-assert(result);
-result = _setmode(fileno(stdin), _O_BINARY);
-UNUSED_IF_ASSERT_DISABLED(result);
-assert(result);
-#endif
+  auto HandleClient =
+  [=, log = log.get()](std::string name, StreamDescriptor input,
+   StreamDescriptor output, std::FILE *redirectOut,
+   std::FILE *redirectErr) -> bool {
+DAP dap = DAP(name, program_path.str(), log, default_repl_mode,
+  std::move(input), std::move(output));
 
-int stdout_fd = DuplicateFileDescriptor(fileno(stdout));
-if (stdout_fd == -1) {
+// stdout/stderr redirection to the IDE's console
+if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) {
   llvm::logAllUnhandledErrors(
-  llvm::errorCodeToError(llvm::errnoAsErrorCode()), llvm::errs(),
-  "Failed to configure stdout redirect: ");
+  std::move(Err), llvm::errs(),
+  "Failed to configure lldb-dap IO operations: ");
   return EXIT_FAILURE;
 }
 
-redirectOut = stdout;
-redirectErr = stderr;
+RegisterRequestCallbacks(dap);
 
-input = StreamDescriptor::from_file(fileno(stdin), false);
-output = StreamDescriptor::from_file(stdout_fd, false);
-  }
+dap.pre_init_commands = pre_init_commands;
 
-  DAP dap = DAP(program_path.str(), log.get(), default_repl_mode,
-std::move(input), std::move(output));
+// used only by TestVSCode_redirection_to_console.py
+if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
+  redirection_test();
 
-  // stdout/stderr redirection to the IDE's console
-  if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) {
-llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(),
-"Failed to configure lldb-dap IO operations: 
");
-return EXIT_FAILURE;
-  }
+if (auto Err = dap.Loop()) {
+  if (log)
+*log << "Transport Error: " << llvm::toString(std::move(Err)) << "\n";
+  return false;
+}
+return true;
+  };
 
-  RegisterRequestCallbacks(dap);
+  if (!connection.empty()) {
+auto maybeProtoclAndName = parseConnection(connection);
+if (auto Err = maybeProtoclAndName.takeError()) {
+  llvm::errs() << "Invalid connection specification " << Err << "\n";
+  return EXIT_FAILURE;
+}
 
-  for (const std::string &arg :
-   input_args.getAllArgValues(OPT_pre_init_command)) {
-dap.pre_init_commands.push_back(arg);
-  }
+Socket::SocketProtocol protocol;
+std::string name;
+std::tie(protocol, name) = *maybeProtoclAndName;
 
-  // used only by TestVSCode_redirection_to_console.py
-  if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
-redirection_test();
+Status error;
+std::unique_ptr listener = Socket::Create(protocol, error);
+if (error.Fail()) {
+  llvm::errs() << "Failed to create listener for protocol "
+   << Socket::FindSchemeByProtocol(protocol)
+   << ", error: " << error.takeError() << "\n";
+  return EXIT_FAILURE;
+}
 
-  bool CleanExit = true;
-  if (auto Err = dap.Loop()) {
+error = listener->Listen(name, /* backlog */ 5);
+if (error.Fail()) {
+  llvm::errs() << "Failed to listen, error: " << error.takeError() << "\n";
+  return EXIT_FAILURE;
+}
+
+std::string address =
+llvm::join(listener->GetListeningConnectionURI(), ", ");
 if (log)
-  *log << "Transport Error: " << llvm::toString(std::move(Err)) << "\n";
-CleanExit = false;
+  *log << "started with connection listeners " << address << "\n";
+
+llvm::outs() << "Listening for: " << address << "\n";
+// Ensure listening address are flushed for calles to retrieve the resolve
+// address.
+llvm::outs().flush();
+
+MainLoop mainloop;
+mainloop.RegisterSignal(
+SIGHUP, [](auto &RL) { RL.RequestTermination(); }, error);
+
+unsigne

[Lldb-commits] [lldb] [llvm] [lldb] Make Python >= 3.8 required for LLDB 21 (PR #124735)

2025-01-29 Thread David Spickett via lldb-commits

https://github.com/DavidSpickett updated 
https://github.com/llvm/llvm-project/pull/124735

>From 08c47efd81fba63f252467bf7af48549ba4b62d5 Mon Sep 17 00:00:00 2001
From: David Spickett 
Date: Tue, 28 Jan 2025 10:58:34 +
Subject: [PATCH] [lldb] Make Python >= 3.8 required for LLDB 21

As decided on 
https://discourse.llvm.org/t/rfc-lets-document-and-enforce-a-minimum-python-version-for-lldb/82731.

LLDB 20 recommended >= 3.8 but did not remove support
for anything earlier. Now we are in what will become
LLDB 21, so I'm removing that support and making
>= 3.8 required.

See https://docs.python.org/3/c-api/apiabiversion.html#c.PY_VERSION_HEX for the 
format
of PY_VERSION_HEX.
---
 lldb/docs/resources/build.rst |  2 +-
 .../Python/PythonDataObjects.cpp  | 59 +--
 .../Python/ScriptInterpreterPython.cpp| 27 +
 .../ScriptInterpreter/Python/lldb-python.h|  4 +-
 .../Python/PythonDataObjectsTests.cpp |  6 --
 llvm/docs/ReleaseNotes.md |  3 +
 6 files changed, 8 insertions(+), 93 deletions(-)

diff --git a/lldb/docs/resources/build.rst b/lldb/docs/resources/build.rst
index c0d3c580d631c1..214c5f63f2c73b 100644
--- a/lldb/docs/resources/build.rst
+++ b/lldb/docs/resources/build.rst
@@ -62,7 +62,7 @@ CMake configuration error.
 
+---+--+--+
 | Libxml2   | XML  
| ``LLDB_ENABLE_LIBXML2``  |
 
+---+--+--+
-| Python| Python scripting. >= 3.0 is required, >= 3.8 is 
recommended. | ``LLDB_ENABLE_PYTHON``   |
+| Python| Python scripting. >= 3.8 is required.
| ``LLDB_ENABLE_PYTHON``   |
 
+---+--+--+
 | Lua   | Lua scripting. Lua 5.3 and 5.4 are supported.
| ``LLDB_ENABLE_LUA``  |
 
+---+--+--+
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp 
b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index a0f8cf954f8040..1340425aade438 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -73,10 +73,8 @@ Expected 
python::As(Expected &&obj) {
 static bool python_is_finalizing() {
 #if PY_VERSION_HEX >= 0x030d
   return Py_IsFinalizing();
-#elif PY_VERSION_HEX >= 0x0307
-  return _Py_IsFinalizing();
 #else
-  return _Py_Finalizing != nullptr;
+  return _Py_IsFinalizing();
 #endif
 }
 
@@ -810,7 +808,6 @@ bool PythonCallable::Check(PyObject *py_obj) {
   return PyCallable_Check(py_obj);
 }
 
-#if PY_VERSION_HEX >= 0x0303
 static const char get_arg_info_script[] = R"(
 from inspect import signature, Parameter, ismethod
 from collections import namedtuple
@@ -832,15 +829,12 @@ def main(f):
 raise Exception(f'unknown parameter kind: {kind}')
 return ArgInfo(count, varargs)
 )";
-#endif
 
 Expected PythonCallable::GetArgInfo() const {
   ArgInfo result = {};
   if (!IsValid())
 return nullDeref();
 
-#if PY_VERSION_HEX >= 0x0303
-
   // no need to synchronize access to this global, we already have the GIL
   static PythonScript get_arg_info(get_arg_info_script);
   Expected pyarginfo = get_arg_info(*this);
@@ -852,57 +846,6 @@ Expected 
PythonCallable::GetArgInfo() const {
   cantFail(As(pyarginfo.get().GetAttribute("has_varargs")));
   result.max_positional_args = has_varargs ? ArgInfo::UNBOUNDED : count;
 
-#else
-  PyObject *py_func_obj;
-  bool is_bound_method = false;
-  bool is_class = false;
-
-  if (PyType_Check(m_py_obj) || PyClass_Check(m_py_obj)) {
-auto init = GetAttribute("__init__");
-if (!init)
-  return init.takeError();
-py_func_obj = init.get().get();
-is_class = true;
-  } else {
-py_func_obj = m_py_obj;
-  }
-
-  if (PyMethod_Check(py_func_obj)) {
-py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
-PythonObject im_self = GetAttributeValue("im_self");
-if (im_self.IsValid() && !im_self.IsNone())
-  is_bound_method = true;
-  } else {
-// see if this is a callable object with an __call__ method
-if (!PyFunction_Check(py_func_obj)) {
-  PythonObject __call__ = GetAttributeValue("__call__");
-  if (__call__.IsValid()) {
-auto __callable__ = __call__.AsType();
-if (__callable__.IsValid()) {
-  py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
-  PythonObject im_self = __callable__.GetAttributeValue("im_self");
-  if (im_self.IsValid() && !im_self.IsNone())
-is_bound_method = true;
-}
-

[Lldb-commits] [lldb] [llvm] [lldb] Make Python >= 3.8 required for LLDB 21 (PR #124735)

2025-01-29 Thread David Spickett via lldb-commits

https://github.com/DavidSpickett edited 
https://github.com/llvm/llvm-project/pull/124735
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Remove some unused code in SymbolFileDWARF::ResolveFunction (PR #123206)

2025-01-29 Thread Pavel Labath via lldb-commits

labath wrote:

ping

https://github.com/llvm/llvm-project/pull/123206
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Use Function::GetAddress in Module::FindFunctions (PR #124938)

2025-01-29 Thread Pavel Labath via lldb-commits

https://github.com/labath created 
https://github.com/llvm/llvm-project/pull/124938

The original code resulted in a misfire in the symtab vs. debug info 
deduplication code, which caused us to return the same function twice when 
searching via a regex (for functions whose entry point is also not the lowest 
address).

>From b67f966fb8ccac4bed71701136b95f73ff0d6394 Mon Sep 17 00:00:00 2001
From: Pavel Labath 
Date: Wed, 29 Jan 2025 16:53:04 +0100
Subject: [PATCH] [lldb] Use Function::GetAddress in Module::FindFunctions

The original code resulted in a misfire in the symtab vs. debug info
deduplication code, which caused us to return the same function twice
when searching via a regex (for functions whose entry point is also not
the lowest address).
---
 lldb/source/Core/Module.cpp   |  5 ++---
 .../DWARF/x86/discontinuous-function.s| 20 +++
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 9601c834d9b8fec..33668c5d20dde41 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -919,9 +919,8 @@ void Module::FindFunctions(const RegularExpression ®ex,
   const SymbolContext &sc = sc_list[i];
   if (sc.block)
 continue;
-  file_addr_to_index[sc.function->GetAddressRange()
- .GetBaseAddress()
- .GetFileAddress()] = i;
+  file_addr_to_index[sc.function->GetAddress().GetFileAddress()] =
+  i;
 }
 
 FileAddrToIndexMap::const_iterator end = file_addr_to_index.end();
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s 
b/lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s
index 93ea9f33e762df7..197ab9aa14910e7 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s
@@ -6,17 +6,29 @@
 # The function bar has been placed "in the middle" of foo, and the function
 # entry point is deliberately not its lowest address.
 
-# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t
-# RUN: %lldb %t -o "image lookup -v -n foo" -o "expr -- &foo" -o exit | 
FileCheck %s
+# RUN: split-file %s %t
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %t/input.s -o %t/input.o
+# RUN: %lldb %t/input.o -s %t/commands -o exit | FileCheck %s
 
-# CHECK-LABEL: image lookup
+#--- commands
+
+image lookup -v -n foo
+# CHECK-LABEL: image lookup -v -n foo
+# CHECK: 1 match found in {{.*}}
+# CHECK: Summary: input.o`foo
+# CHECK: Function: id = {{.*}}, name = "foo", ranges = 
[0x-0x000e)[0x0014-0x001c)
+
+image lookup -v --regex -n '^foo$'
+# CHECK-LABEL: image lookup -v --regex -n '^foo$'
 # CHECK: 1 match found in {{.*}}
-# CHECK: Summary: {{.*}}`foo
+# CHECK: Summary: input.o`foo
 # CHECK: Function: id = {{.*}}, name = "foo", ranges = 
[0x-0x000e)[0x0014-0x001c)
 
+expr -- &foo
 # CHECK-LABEL: expr -- &foo
 # CHECK: (void (*)()) $0 = 0x0007
 
+#--- input.s
 .text
 
 foo.__part.1:

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Extended if conditions to support alias names for registers (PR #124475)

2025-01-29 Thread via lldb-commits

https://github.com/kper updated https://github.com/llvm/llvm-project/pull/124475

>From 096eb85718d70721cec1e539cfa4b05a96475c7a Mon Sep 17 00:00:00 2001
From: Kevin Per 
Date: Sun, 26 Jan 2025 17:34:17 +
Subject: [PATCH 1/6] lldb: Extended if conditions to support alias names for
 registers

---
 .../Plugins/ABI/RISCV/ABISysV_riscv.cpp   | 54 +++
 1 file changed, 54 insertions(+)

diff --git a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp 
b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
index 8412991933d277..c463bd006b3db4 100644
--- a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
+++ b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
@@ -850,8 +850,62 @@ void ABISysV_riscv::AugmentRegisterInfo(
   it.value().alt_name.SetCString("x3");
 else if (it.value().name == "fp")
   it.value().alt_name.SetCString("s0");
+else if (it.value().name == "tp")
+  it.value().alt_name.SetCString("x4");
 else if (it.value().name == "s0")
   it.value().alt_name.SetCString("x8");
+else if (it.value().name == "s1")
+  it.value().alt_name.SetCString("x9");
+else if (it.value().name == "t0")
+  it.value().alt_name.SetCString("x5");
+else if (it.value().name == "t1")
+  it.value().alt_name.SetCString("x6");
+else if (it.value().name == "t2")
+  it.value().alt_name.SetCString("x7");
+else if (it.value().name == "a0")
+  it.value().alt_name.SetCString("x10");
+else if (it.value().name == "a1")
+  it.value().alt_name.SetCString("x11");
+else if (it.value().name == "a2")
+  it.value().alt_name.SetCString("x12");
+else if (it.value().name == "a3")
+  it.value().alt_name.SetCString("x13");
+else if (it.value().name == "a4")
+  it.value().alt_name.SetCString("x14");
+else if (it.value().name == "a5")
+  it.value().alt_name.SetCString("x15");
+else if (it.value().name == "a6")
+  it.value().alt_name.SetCString("x16");
+else if (it.value().name == "a7")
+  it.value().alt_name.SetCString("x17");
+else if (it.value().name == "s2")
+  it.value().alt_name.SetCString("x18");
+else if (it.value().name == "s3")
+  it.value().alt_name.SetCString("x19");
+else if (it.value().name == "s4")
+  it.value().alt_name.SetCString("x20");
+else if (it.value().name == "s5")
+  it.value().alt_name.SetCString("x21");
+else if (it.value().name == "s6")
+  it.value().alt_name.SetCString("x22");
+else if (it.value().name == "s7")
+  it.value().alt_name.SetCString("x23");
+else if (it.value().name == "s8")
+  it.value().alt_name.SetCString("x24");
+else if (it.value().name == "s9")
+  it.value().alt_name.SetCString("x25");
+else if (it.value().name == "s10")
+  it.value().alt_name.SetCString("x26");
+else if (it.value().name == "s11")
+  it.value().alt_name.SetCString("x27");
+else if (it.value().name == "t3")
+  it.value().alt_name.SetCString("x28");
+else if (it.value().name == "t4")
+  it.value().alt_name.SetCString("x29");
+else if (it.value().name == "t5")
+  it.value().alt_name.SetCString("x30");
+else if (it.value().name == "t6")
+  it.value().alt_name.SetCString("x31");
 
 // Set generic regnum so lldb knows what the PC, etc is
 it.value().regnum_generic = GetGenericNum(it.value().name.GetStringRef());

>From ad3dfa270953a04f755773c402941fd10165a098 Mon Sep 17 00:00:00 2001
From: Kevin Per 
Date: Tue, 28 Jan 2025 15:23:54 +
Subject: [PATCH 2/6] Added RISCV reg test for the ServerTargetXML

---
 .../TestGDBServerTargetXML.py | 149 ++
 1 file changed, 149 insertions(+)

diff --git 
a/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py 
b/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
index 22f5553e40802d..c74726a88aa6ff 100644
--- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
@@ -652,6 +652,155 @@ def haltReason(self):
 )
 self.match("register read s31", ["s31 = 128"])
 
+@skipIfXmlSupportMissing
+@skipIfRemote
+@skipIfLLVMTargetMissing("RISCV")
+def test_riscv64_regs(self):
+"""Test grabbing various riscv64 registers from gdbserver."""
+
+class MyResponder(MockGDBServerResponder):
+reg_data = (
+(
+"0102030405060708"  # zero
+"0102030405060708"  # ra
+"0102030405060708"  # sp
+"0102030405060708"  # gp
+"0102030405060708"  # tp
+"0102030405060708"  # t0 
+"0102030405060708"  # t1
+"0102030405060708"  # t2
+"0102030405060708"  # fp 
+"0102030405060708"  # s1
+"0102030405060708"  # a0
+"01

[Lldb-commits] [lldb] [lldb] Remove PATH workaround for Android (PR #124682)

2025-01-29 Thread Pavel Labath via lldb-commits

https://github.com/labath approved this pull request.


https://github.com/llvm/llvm-project/pull/124682
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] 9326633 - [lldb] Remove PATH workaround for Android (#124682)

2025-01-29 Thread via lldb-commits

Author: Brad Smith
Date: 2025-01-29T03:21:45-05:00
New Revision: 9326633abd0e59fc77072488ee8cded4fe83c8a1

URL: 
https://github.com/llvm/llvm-project/commit/9326633abd0e59fc77072488ee8cded4fe83c8a1
DIFF: 
https://github.com/llvm/llvm-project/commit/9326633abd0e59fc77072488ee8cded4fe83c8a1.diff

LOG: [lldb] Remove PATH workaround for Android (#124682)

Added: 


Modified: 
lldb/source/Host/posix/ProcessLauncherPosixFork.cpp

Removed: 




diff  --git a/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp 
b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp
index 7d856954684c49..3e956290c3055a 100644
--- a/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp
+++ b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp
@@ -230,16 +230,6 @@ MakeForkActions(const ProcessLaunchInfo &info) {
   return result;
 }
 
-static Environment::Envp FixupEnvironment(Environment env) {
-#ifdef __ANDROID__
-  // If there is no PATH variable specified inside the environment then set the
-  // path to /system/bin. It is required because the default path used by
-  // execve() is wrong on android.
-  env.try_emplace("PATH", "/system/bin");
-#endif
-  return env.getEnvp();
-}
-
 ForkLaunchInfo::ForkLaunchInfo(const ProcessLaunchInfo &info)
 : separate_process_group(
   info.GetFlags().Test(eLaunchFlagLaunchInSeparateProcessGroup)),
@@ -247,8 +237,7 @@ ForkLaunchInfo::ForkLaunchInfo(const ProcessLaunchInfo 
&info)
   disable_aslr(info.GetFlags().Test(eLaunchFlagDisableASLR)),
   wd(info.GetWorkingDirectory().GetPath()),
   argv(info.GetArguments().GetConstArgumentVector()),
-  envp(FixupEnvironment(info.GetEnvironment())),
-  actions(MakeForkActions(info)) {}
+  envp(info.GetEnvironment().getEnvp()), actions(MakeForkActions(info)) {}
 
 HostProcess
 ProcessLauncherPosixFork::LaunchProcess(const ProcessLaunchInfo &launch_info,



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Remove PATH workaround for Android (PR #124682)

2025-01-29 Thread Brad Smith via lldb-commits

https://github.com/brad0 closed https://github.com/llvm/llvm-project/pull/124682
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring lldb-dap port listening mode to allow multiple connections. (PR #116392)

2025-01-29 Thread Pavel Labath via lldb-commits


@@ -5058,72 +5053,148 @@ int main(int argc, char *argv[]) {
   auto terminate_debugger =
   llvm::make_scope_exit([] { lldb::SBDebugger::Terminate(); });
 
-  StreamDescriptor input;
-  StreamDescriptor output;
-  std::FILE *redirectOut = nullptr;
-  std::FILE *redirectErr = nullptr;
-  if (portno != -1) {
-printf("Listening on port %i...\n", portno);
-SOCKET socket_fd = AcceptConnection(log.get(), portno);
-if (socket_fd < 0)
-  return EXIT_FAILURE;
+  std::vector pre_init_commands;
+  for (const std::string &arg :
+   input_args.getAllArgValues(OPT_pre_init_command)) {
+pre_init_commands.push_back(arg);
+  }
 
-input = StreamDescriptor::from_socket(socket_fd, true);
-output = StreamDescriptor::from_socket(socket_fd, false);
-  } else {
-#if defined(_WIN32)
-// Windows opens stdout and stdin in text mode which converts \n to 13,10
-// while the value is just 10 on Darwin/Linux. Setting the file mode to
-// binary fixes this.
-int result = _setmode(fileno(stdout), _O_BINARY);
-assert(result);
-result = _setmode(fileno(stdin), _O_BINARY);
-UNUSED_IF_ASSERT_DISABLED(result);
-assert(result);
-#endif
+  auto HandleClient =
+  [=, log = log.get()](std::string name, StreamDescriptor input,
+   StreamDescriptor output, std::FILE *redirectOut,
+   std::FILE *redirectErr) -> bool {
+DAP dap = DAP(name, program_path.str(), log, default_repl_mode,
+  std::move(input), std::move(output));
 
-int stdout_fd = DuplicateFileDescriptor(fileno(stdout));
-if (stdout_fd == -1) {
+// stdout/stderr redirection to the IDE's console
+if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) {
   llvm::logAllUnhandledErrors(
-  llvm::errorCodeToError(llvm::errnoAsErrorCode()), llvm::errs(),
-  "Failed to configure stdout redirect: ");
+  std::move(Err), llvm::errs(),
+  "Failed to configure lldb-dap IO operations: ");
   return EXIT_FAILURE;
 }
 
-redirectOut = stdout;
-redirectErr = stderr;
+RegisterRequestCallbacks(dap);
 
-input = StreamDescriptor::from_file(fileno(stdin), false);
-output = StreamDescriptor::from_file(stdout_fd, false);
-  }
+dap.pre_init_commands = pre_init_commands;
 
-  DAP dap = DAP(program_path.str(), log.get(), default_repl_mode,
-std::move(input), std::move(output));
+// used only by TestVSCode_redirection_to_console.py
+if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
+  redirection_test();
 
-  // stdout/stderr redirection to the IDE's console
-  if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) {
-llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(),
-"Failed to configure lldb-dap IO operations: 
");
-return EXIT_FAILURE;
-  }
+if (auto Err = dap.Loop()) {
+  if (log)
+*log << "Transport Error: " << llvm::toString(std::move(Err)) << "\n";
+  return false;
+}
+return true;
+  };
 
-  RegisterRequestCallbacks(dap);
+  if (!connection.empty()) {
+auto maybeProtoclAndName = parseConnection(connection);
+if (auto Err = maybeProtoclAndName.takeError()) {
+  llvm::errs() << "Invalid connection specification " << Err << "\n";
+  return EXIT_FAILURE;
+}
 
-  for (const std::string &arg :
-   input_args.getAllArgValues(OPT_pre_init_command)) {
-dap.pre_init_commands.push_back(arg);
-  }
+Socket::SocketProtocol protocol;
+std::string name;
+std::tie(protocol, name) = *maybeProtoclAndName;
 
-  // used only by TestVSCode_redirection_to_console.py
-  if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
-redirection_test();
+Status error;
+std::unique_ptr listener = Socket::Create(protocol, error);
+if (error.Fail()) {
+  llvm::errs() << "Failed to create listener for protocol "
+   << Socket::FindSchemeByProtocol(protocol)
+   << ", error: " << error.takeError() << "\n";
+  return EXIT_FAILURE;
+}
 
-  bool CleanExit = true;
-  if (auto Err = dap.Loop()) {
+error = listener->Listen(name, /* backlog */ 5);
+if (error.Fail()) {
+  llvm::errs() << "Failed to listen, error: " << error.takeError() << "\n";
+  return EXIT_FAILURE;
+}
+
+std::string address =
+llvm::join(listener->GetListeningConnectionURI(), ", ");
 if (log)
-  *log << "Transport Error: " << llvm::toString(std::move(Err)) << "\n";
-CleanExit = false;
+  *log << "started with connection listeners " << address << "\n";
+
+llvm::outs() << "Listening for: " << address << "\n";
+// Ensure listening address are flushed for calles to retrieve the resolve
+// address.
+llvm::outs().flush();
+
+MainLoop mainloop;
+mainloop.RegisterSignal(
+SIGHUP, [](auto &RL) { RL.RequestTermination(); }, error);
--

[Lldb-commits] [lldb] [lldb-dap] Refactoring lldb-dap port listening mode to allow multiple connections. (PR #116392)

2025-01-29 Thread Pavel Labath via lldb-commits


@@ -5058,72 +5053,148 @@ int main(int argc, char *argv[]) {
   auto terminate_debugger =
   llvm::make_scope_exit([] { lldb::SBDebugger::Terminate(); });
 
-  StreamDescriptor input;
-  StreamDescriptor output;
-  std::FILE *redirectOut = nullptr;
-  std::FILE *redirectErr = nullptr;
-  if (portno != -1) {
-printf("Listening on port %i...\n", portno);
-SOCKET socket_fd = AcceptConnection(log.get(), portno);
-if (socket_fd < 0)
-  return EXIT_FAILURE;
+  std::vector pre_init_commands;
+  for (const std::string &arg :
+   input_args.getAllArgValues(OPT_pre_init_command)) {
+pre_init_commands.push_back(arg);
+  }
 
-input = StreamDescriptor::from_socket(socket_fd, true);
-output = StreamDescriptor::from_socket(socket_fd, false);
-  } else {
-#if defined(_WIN32)
-// Windows opens stdout and stdin in text mode which converts \n to 13,10
-// while the value is just 10 on Darwin/Linux. Setting the file mode to
-// binary fixes this.
-int result = _setmode(fileno(stdout), _O_BINARY);
-assert(result);
-result = _setmode(fileno(stdin), _O_BINARY);
-UNUSED_IF_ASSERT_DISABLED(result);
-assert(result);
-#endif
+  auto HandleClient =
+  [=, log = log.get()](std::string name, StreamDescriptor input,
+   StreamDescriptor output, std::FILE *redirectOut,
+   std::FILE *redirectErr) -> bool {
+DAP dap = DAP(name, program_path.str(), log, default_repl_mode,
+  std::move(input), std::move(output));
 
-int stdout_fd = DuplicateFileDescriptor(fileno(stdout));
-if (stdout_fd == -1) {
+// stdout/stderr redirection to the IDE's console
+if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) {
   llvm::logAllUnhandledErrors(
-  llvm::errorCodeToError(llvm::errnoAsErrorCode()), llvm::errs(),
-  "Failed to configure stdout redirect: ");
+  std::move(Err), llvm::errs(),
+  "Failed to configure lldb-dap IO operations: ");
   return EXIT_FAILURE;
 }
 
-redirectOut = stdout;
-redirectErr = stderr;
+RegisterRequestCallbacks(dap);
 
-input = StreamDescriptor::from_file(fileno(stdin), false);
-output = StreamDescriptor::from_file(stdout_fd, false);
-  }
+dap.pre_init_commands = pre_init_commands;
 
-  DAP dap = DAP(program_path.str(), log.get(), default_repl_mode,
-std::move(input), std::move(output));
+// used only by TestVSCode_redirection_to_console.py
+if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
+  redirection_test();
 
-  // stdout/stderr redirection to the IDE's console
-  if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) {
-llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(),
-"Failed to configure lldb-dap IO operations: 
");
-return EXIT_FAILURE;
-  }
+if (auto Err = dap.Loop()) {
+  if (log)
+*log << "Transport Error: " << llvm::toString(std::move(Err)) << "\n";
+  return false;
+}
+return true;
+  };
 
-  RegisterRequestCallbacks(dap);
+  if (!connection.empty()) {
+auto maybeProtoclAndName = parseConnection(connection);
+if (auto Err = maybeProtoclAndName.takeError()) {
+  llvm::errs() << "Invalid connection specification " << Err << "\n";
+  return EXIT_FAILURE;
+}
 
-  for (const std::string &arg :
-   input_args.getAllArgValues(OPT_pre_init_command)) {
-dap.pre_init_commands.push_back(arg);
-  }
+Socket::SocketProtocol protocol;
+std::string name;
+std::tie(protocol, name) = *maybeProtoclAndName;
 
-  // used only by TestVSCode_redirection_to_console.py
-  if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
-redirection_test();
+Status error;
+std::unique_ptr listener = Socket::Create(protocol, error);
+if (error.Fail()) {
+  llvm::errs() << "Failed to create listener for protocol "
+   << Socket::FindSchemeByProtocol(protocol)
+   << ", error: " << error.takeError() << "\n";
+  return EXIT_FAILURE;
+}
 
-  bool CleanExit = true;
-  if (auto Err = dap.Loop()) {
+error = listener->Listen(name, /* backlog */ 5);
+if (error.Fail()) {
+  llvm::errs() << "Failed to listen, error: " << error.takeError() << "\n";
+  return EXIT_FAILURE;
+}
+
+std::string address =
+llvm::join(listener->GetListeningConnectionURI(), ", ");
 if (log)
-  *log << "Transport Error: " << llvm::toString(std::move(Err)) << "\n";
-CleanExit = false;
+  *log << "started with connection listeners " << address << "\n";
+
+llvm::outs() << "Listening for: " << address << "\n";
+// Ensure listening address are flushed for calles to retrieve the resolve
+// address.
+llvm::outs().flush();
+
+MainLoop mainloop;
+mainloop.RegisterSignal(
+SIGHUP, [](auto &RL) { RL.RequestTermination(); }, error);
+
+unsigne

[Lldb-commits] [lldb] [lldb-dap] Refactoring lldb-dap port listening mode to allow multiple connections. (PR #116392)

2025-01-29 Thread Pavel Labath via lldb-commits


@@ -5058,72 +5053,148 @@ int main(int argc, char *argv[]) {
   auto terminate_debugger =
   llvm::make_scope_exit([] { lldb::SBDebugger::Terminate(); });
 
-  StreamDescriptor input;
-  StreamDescriptor output;
-  std::FILE *redirectOut = nullptr;
-  std::FILE *redirectErr = nullptr;
-  if (portno != -1) {
-printf("Listening on port %i...\n", portno);
-SOCKET socket_fd = AcceptConnection(log.get(), portno);
-if (socket_fd < 0)
-  return EXIT_FAILURE;
+  std::vector pre_init_commands;
+  for (const std::string &arg :
+   input_args.getAllArgValues(OPT_pre_init_command)) {
+pre_init_commands.push_back(arg);
+  }
 
-input = StreamDescriptor::from_socket(socket_fd, true);
-output = StreamDescriptor::from_socket(socket_fd, false);
-  } else {
-#if defined(_WIN32)
-// Windows opens stdout and stdin in text mode which converts \n to 13,10
-// while the value is just 10 on Darwin/Linux. Setting the file mode to
-// binary fixes this.
-int result = _setmode(fileno(stdout), _O_BINARY);
-assert(result);
-result = _setmode(fileno(stdin), _O_BINARY);
-UNUSED_IF_ASSERT_DISABLED(result);
-assert(result);
-#endif
+  auto HandleClient =
+  [=, log = log.get()](std::string name, StreamDescriptor input,
+   StreamDescriptor output, std::FILE *redirectOut,
+   std::FILE *redirectErr) -> bool {
+DAP dap = DAP(name, program_path.str(), log, default_repl_mode,
+  std::move(input), std::move(output));
 
-int stdout_fd = DuplicateFileDescriptor(fileno(stdout));
-if (stdout_fd == -1) {
+// stdout/stderr redirection to the IDE's console
+if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) {
   llvm::logAllUnhandledErrors(
-  llvm::errorCodeToError(llvm::errnoAsErrorCode()), llvm::errs(),
-  "Failed to configure stdout redirect: ");
+  std::move(Err), llvm::errs(),
+  "Failed to configure lldb-dap IO operations: ");
   return EXIT_FAILURE;
 }
 
-redirectOut = stdout;
-redirectErr = stderr;
+RegisterRequestCallbacks(dap);
 
-input = StreamDescriptor::from_file(fileno(stdin), false);
-output = StreamDescriptor::from_file(stdout_fd, false);
-  }
+dap.pre_init_commands = pre_init_commands;
 
-  DAP dap = DAP(program_path.str(), log.get(), default_repl_mode,
-std::move(input), std::move(output));
+// used only by TestVSCode_redirection_to_console.py
+if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
+  redirection_test();
 
-  // stdout/stderr redirection to the IDE's console
-  if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) {
-llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(),
-"Failed to configure lldb-dap IO operations: 
");
-return EXIT_FAILURE;
-  }
+if (auto Err = dap.Loop()) {
+  if (log)
+*log << "Transport Error: " << llvm::toString(std::move(Err)) << "\n";
+  return false;
+}
+return true;
+  };
 
-  RegisterRequestCallbacks(dap);
+  if (!connection.empty()) {
+auto maybeProtoclAndName = parseConnection(connection);
+if (auto Err = maybeProtoclAndName.takeError()) {
+  llvm::errs() << "Invalid connection specification " << Err << "\n";
+  return EXIT_FAILURE;
+}
 
-  for (const std::string &arg :
-   input_args.getAllArgValues(OPT_pre_init_command)) {
-dap.pre_init_commands.push_back(arg);
-  }
+Socket::SocketProtocol protocol;
+std::string name;
+std::tie(protocol, name) = *maybeProtoclAndName;
 
-  // used only by TestVSCode_redirection_to_console.py
-  if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
-redirection_test();
+Status error;
+std::unique_ptr listener = Socket::Create(protocol, error);
+if (error.Fail()) {
+  llvm::errs() << "Failed to create listener for protocol "
+   << Socket::FindSchemeByProtocol(protocol)
+   << ", error: " << error.takeError() << "\n";
+  return EXIT_FAILURE;
+}
 
-  bool CleanExit = true;
-  if (auto Err = dap.Loop()) {
+error = listener->Listen(name, /* backlog */ 5);
+if (error.Fail()) {
+  llvm::errs() << "Failed to listen, error: " << error.takeError() << "\n";
+  return EXIT_FAILURE;
+}
+
+std::string address =
+llvm::join(listener->GetListeningConnectionURI(), ", ");
 if (log)
-  *log << "Transport Error: " << llvm::toString(std::move(Err)) << "\n";
-CleanExit = false;
+  *log << "started with connection listeners " << address << "\n";
+
+llvm::outs() << "Listening for: " << address << "\n";
+// Ensure listening address are flushed for calles to retrieve the resolve
+// address.
+llvm::outs().flush();
+
+MainLoop mainloop;
+mainloop.RegisterSignal(
+SIGHUP, [](auto &RL) { RL.RequestTermination(); }, error);
+
+unsigne

[Lldb-commits] [lldb] [lldb-dap] Refactoring lldb-dap port listening mode to allow multiple connections. (PR #116392)

2025-01-29 Thread Pavel Labath via lldb-commits


@@ -1167,21 +1168,61 @@ def __init__(
 
 if log_file:
 adaptor_env["LLDBDAP_LOG"] = log_file
+args = [executable]
+
+if connection is not None:
+args.append("--connection")
+args.append(connection)
+
 self.process = subprocess.Popen(
-[executable],
+args,
 stdin=subprocess.PIPE,
 stdout=subprocess.PIPE,
 stderr=subprocess.PIPE,
 env=adaptor_env,
 )
+
+if connection is not None:
+# If the process was also launched, parse the connection from the
+# resolved connection. For example, if the connection
+# `connection://localhost:0` was specified then the OS would pick a
+# random port for listening and lldb-dap would print the listening
+# port to stdout.
+if self.process is not None:
+# lldb-dap will print the listening address once the listener 
is
+# made to stdout. The listener is formatted like
+# `connection://host:port` or `unix-connection:///path`.
+expected_prefix = "Listening for: "
+out = self.process.stdout.readline().decode()
+if not out.startswith(expected_prefix):
+self.process.kill()
+raise ValueError(
+"lldb-dap failed to print listening address, expected 
'{}', got '{}'".format(
+expected_prefix, out
+)
+)
+
+# If the listener expanded into multiple addresses, use the 
first.
+connection = (
+
out.removeprefix(expected_prefix).rstrip("\r\n").split(",", 1)[0]
+)
+
+if connection.startswith("unix-connect://"):  # 
unix-connect:///path

labath wrote:

How about something like:
```suggestion
scheme, address = connection.split("://")
if connection == "unix-connect":  # unix-connect:///path
  # etc.
```

https://github.com/llvm/llvm-project/pull/116392
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring lldb-dap port listening mode to allow multiple connections. (PR #116392)

2025-01-29 Thread Pavel Labath via lldb-commits


@@ -4952,6 +4930,28 @@ static int DuplicateFileDescriptor(int fd) {
 #endif
 }
 
+static llvm::Expected>
+parseConnection(llvm::StringRef conn) {
+  if (conn.contains("://")) {

labath wrote:

It looks like this could use `lldb/Utility/URIParser.h`

https://github.com/llvm/llvm-project/pull/116392
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring lldb-dap port listening mode to allow multiple connections. (PR #116392)

2025-01-29 Thread Pavel Labath via lldb-commits

https://github.com/labath edited 
https://github.com/llvm/llvm-project/pull/116392
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring lldb-dap port listening mode to allow multiple connections. (PR #116392)

2025-01-29 Thread Pavel Labath via lldb-commits

https://github.com/labath commented:

I think this looks pretty good now. Just a couple of questions from my side.

https://github.com/llvm/llvm-project/pull/116392
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb][Windows] WoA HW Watchpoint support in LLDB (PR #108072)

2025-01-29 Thread Omair Javaid via lldb-commits

omjavaid wrote:

> ### Known Issues (Just for documentation):
> 1.

I have updates the PR description the "Known Issues (Just for documentation):" 
part will be skipped in the final patch description.

https://github.com/llvm/llvm-project/pull/108072
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb][Windows] WoA HW Watchpoint support in LLDB (PR #108072)

2025-01-29 Thread Omair Javaid via lldb-commits

https://github.com/omjavaid edited 
https://github.com/llvm/llvm-project/pull/108072
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb] Change lldb's breakpoint detection behavior [WIP] (PR #105594)

2025-01-29 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/105594

>From 56ca564185bdceea25162a1ce3b1e8c8fa2641e2 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Fri, 19 Jul 2024 17:26:13 -0700
Subject: [PATCH 1/8] [lldb] Change lldb's breakpoint handling behavior
 (#96260)

lldb today has two rules: When a thread stops at a BreakpointSite, we
set the thread's StopReason to be "breakpoint hit" (regardless if we've
actually hit the breakpoint, or if we've merely stopped *at* the
breakpoint instruction/point and haven't tripped it yet). And second,
when resuming a process, any thread sitting at a BreakpointSite is
silently stepped over the BreakpointSite -- because we've already
flagged the breakpoint hit when we stopped there originally.

In this patch, I change lldb to only set a thread's stop reason to
breakpoint-hit when we've actually executed the instruction/triggered
the breakpoint. When we resume, we only silently step past a
BreakpointSite that we've registered as hit. We preserve this state
across inferior function calls that the user may do while stopped, etc.

Also, when a user adds a new breakpoint at $pc while stopped, or changes
$pc to be the address of a BreakpointSite, we will silently step past
that breakpoint when the process resumes. This is purely a UX call, I
don't think there's any person who wants to set a breakpoint at $pc and
then hit it immediately on resuming.

One non-intuitive UX from this change, but I'm convinced it is
necessary: If you're stopped at a BreakpointSite that has not yet
executed, you `stepi`, you will hit the breakpoint and the pc will not
yet advance. This thread has not completed its stepi, and the thread
plan is still on the stack. If you then `continue` the thread, lldb will
now stop and say, "instruction step completed", one instruction past the
BreakpointSite. You can continue a second time to resume execution. I
discussed this with Jim, and trying to paper over this behavior will
lead to more complicated scenarios behaving non-intuitively. And mostly
it's the testsuite that was trying to instruction step past a breakpoint
and getting thrown off -- and I changed those tests to expect the new
behavior.

The bugs driving this change are all from lldb dropping the real stop
reason for a thread and setting it to breakpoint-hit when that was not
the case. Jim hit one where we have an aarch64 watchpoint that triggers
one instruction before a BreakpointSite. On this arch we are notified of
the watchpoint hit after the instruction has been unrolled -- we disable
the watchpoint, instruction step, re-enable the watchpoint and collect
the new value. But now we're on a BreakpointSite so the watchpoint-hit
stop reason is lost.

Another was reported by ZequanWu in
https://discourse.llvm.org/t/lldb-unable-to-break-at-start/78282 we
attach to/launch a process with the pc at a BreakpointSite and
misbehave. Caroline Tice mentioned it is also a problem they've had with
putting a breakpoint on _dl_debug_state.

The change to each Process plugin that does execution control is that

1. If we've stopped at a BreakpointSite that has not been executed yet,
we will call Thread::SetThreadStoppedAtUnexecutedBP(pc) to record
that.  When the thread resumes, if the pc is still at the same site, we
will continue, hit the breakpoint, and stop again.

2. When we've actually hit a breakpoint (enabled for this thread or not),
the Process plugin should call Thread::SetThreadHitBreakpointSite().
When we go to resume the thread, we will push a step-over-breakpoint
ThreadPlan before resuming.

The biggest set of changes is to StopInfoMachException where we
translate a Mach Exception into a stop reason. The Mach exception codes
differ in a few places depending on the target (unambiguously), and I
didn't want to duplicate the new code for each target so I've tested
what mach exceptions we get for each action on each target, and
reorganized StopInfoMachException::CreateStopReasonWithMachException to
document these possible values, and handle them without specializing
based on the target arch.

rdar://123942164
---
 lldb/include/lldb/Target/Thread.h |  24 ++
 .../Process/Utility/StopInfoMachException.cpp | 322 --
 .../Process/Windows/Common/ProcessWindows.cpp |  32 +-
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  93 ++---
 .../Process/scripted/ScriptedThread.cpp   |  11 +
 lldb/source/Target/StopInfo.cpp   |   2 +
 lldb/source/Target/Thread.cpp |  15 +-
 .../TestConsecutiveBreakpoints.py |  26 +-
 .../TestStepOverBreakpoint.py |   6 +-
 9 files changed, 266 insertions(+), 265 deletions(-)

diff --git a/lldb/include/lldb/Target/Thread.h 
b/lldb/include/lldb/Target/Thread.h
index 38b65b2bc58490..22d452c7b4b8a3 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ b/lldb/include/lldb/Target/Thread.h
@@ -131,6 +131,7 @@ class Thread : public std::enable_shared_from_this,
 register

[Lldb-commits] [lldb] Only include necessary files in the lldb-dap VSIX (PR #124986)

2025-01-29 Thread Matthew Bastien via lldb-commits

https://github.com/matthewbastien created 
https://github.com/llvm/llvm-project/pull/124986

The published VSIX for the LLDB DAP extension contains a bunch of unnecessary 
files:
```
❯ tar tf llvm-vs-code-extensions.lldb-dap-0.2.8.vsix

extension.vsixmanifest
[Content_Types].xml
extension/.github/workflows/auto_publish.yml
extension/.github/workflows/integrate_llvmproject.yml
extension/.gitignore
extension/.vscode/launch.json
extension/.vscode/tasks.json
extension/LICENSE.TXT
extension/out/debug-adapter-factory.js
extension/out/debug-adapter-factory.js.map
extension/out/disposable-context.js
extension/out/disposable-context.js.map
extension/out/extension.js
extension/out/extension.js.map
extension/out/types.js
extension/out/types.js.map
extension/package.json
extension/README.md
extension/src-ts/debug-adapter-factory.ts
extension/src-ts/disposable-context.ts
extension/src-ts/extension.ts
extension/src-ts/types.ts
extension/syntaxes/arm.disasm
extension/syntaxes/arm64.disasm
extension/syntaxes/disassembly.json
extension/syntaxes/x86.disasm
extension/tsconfig.json
```

All that's really needed is the package.json, license, README, syntaxes folder, 
and compiled sources. This PR adds a `.vscodeignore` file that requires files 
and directories to be explicitly added to the VSIX.

>From d98d57a5f0df75aee5196e3e4046a7f68f4dc0d6 Mon Sep 17 00:00:00 2001
From: Matthew Bastien 
Date: Wed, 29 Jan 2025 16:02:11 -0500
Subject: [PATCH] only include necessary files in the lldb-dap VSIX

---
 lldb/tools/lldb-dap/.vscodeignore | 9 +
 1 file changed, 9 insertions(+)
 create mode 100644 lldb/tools/lldb-dap/.vscodeignore

diff --git a/lldb/tools/lldb-dap/.vscodeignore 
b/lldb/tools/lldb-dap/.vscodeignore
new file mode 100644
index 00..0491ba879fc3f0
--- /dev/null
+++ b/lldb/tools/lldb-dap/.vscodeignore
@@ -0,0 +1,9 @@
+// Ignore everything by default
+**/*
+
+// Only include specific files and directories
+!LICENSE.TXT
+!package.json
+!README.md
+!out/**
+!syntaxes/**

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Only include necessary files in the lldb-dap VSIX (PR #124986)

2025-01-29 Thread via lldb-commits

github-actions[bot] wrote:



Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write 
permissions for the repository. In which case you can instead tag reviewers by 
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a 
review by "ping"ing the PR by adding a comment “Ping”. The common courtesy 
"ping" rate is once a week. Please remember that you are asking for valuable 
time from other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

https://github.com/llvm/llvm-project/pull/124986
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb][Windows] WoA HW Watchpoint support in LLDB (PR #108072)

2025-01-29 Thread Omair Javaid via lldb-commits


@@ -110,8 +110,8 @@ 
NativeRegisterContextWindows::CreateHostNativeRegisterContextWindows(
 
 NativeRegisterContextWindows_x86_64::NativeRegisterContextWindows_x86_64(
 const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
-: NativeRegisterContextWindows(native_thread,
-   CreateRegisterInfoInterface(target_arch)) {}
+: NativeRegisterContextRegisterInfo(
+  native_thread, CreateRegisterInfoInterface(target_arch)) {}

omjavaid wrote:

Yes. Correct.
NativeRegisterContextWindows_arm64 class now inherits from both 
NativeRegisterContextWindows and NativeRegisterContextDBReg_arm64 but both of 
these classes previously inherited from NativeRegisterContextRegisterInfo 
non-virtually. This caused multiple instances of 
NativeRegisterContextRegisterInfo in the hierarchy.
I have now changed NativeRegisterContextWindows definition to inherit 
NativeRegisterContextRegisterInfo virtually 
which shifts the responsibility of initializing 
NativeRegisterContextRegisterInfo to the most derived class.
Thats why this and other similar changes have been made.

https://github.com/llvm/llvm-project/pull/108072
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb] Change lldb's breakpoint detection behavior [WIP] (PR #105594)

2025-01-29 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/105594

>From 56ca564185bdceea25162a1ce3b1e8c8fa2641e2 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Fri, 19 Jul 2024 17:26:13 -0700
Subject: [PATCH 1/7] [lldb] Change lldb's breakpoint handling behavior
 (#96260)

lldb today has two rules: When a thread stops at a BreakpointSite, we
set the thread's StopReason to be "breakpoint hit" (regardless if we've
actually hit the breakpoint, or if we've merely stopped *at* the
breakpoint instruction/point and haven't tripped it yet). And second,
when resuming a process, any thread sitting at a BreakpointSite is
silently stepped over the BreakpointSite -- because we've already
flagged the breakpoint hit when we stopped there originally.

In this patch, I change lldb to only set a thread's stop reason to
breakpoint-hit when we've actually executed the instruction/triggered
the breakpoint. When we resume, we only silently step past a
BreakpointSite that we've registered as hit. We preserve this state
across inferior function calls that the user may do while stopped, etc.

Also, when a user adds a new breakpoint at $pc while stopped, or changes
$pc to be the address of a BreakpointSite, we will silently step past
that breakpoint when the process resumes. This is purely a UX call, I
don't think there's any person who wants to set a breakpoint at $pc and
then hit it immediately on resuming.

One non-intuitive UX from this change, but I'm convinced it is
necessary: If you're stopped at a BreakpointSite that has not yet
executed, you `stepi`, you will hit the breakpoint and the pc will not
yet advance. This thread has not completed its stepi, and the thread
plan is still on the stack. If you then `continue` the thread, lldb will
now stop and say, "instruction step completed", one instruction past the
BreakpointSite. You can continue a second time to resume execution. I
discussed this with Jim, and trying to paper over this behavior will
lead to more complicated scenarios behaving non-intuitively. And mostly
it's the testsuite that was trying to instruction step past a breakpoint
and getting thrown off -- and I changed those tests to expect the new
behavior.

The bugs driving this change are all from lldb dropping the real stop
reason for a thread and setting it to breakpoint-hit when that was not
the case. Jim hit one where we have an aarch64 watchpoint that triggers
one instruction before a BreakpointSite. On this arch we are notified of
the watchpoint hit after the instruction has been unrolled -- we disable
the watchpoint, instruction step, re-enable the watchpoint and collect
the new value. But now we're on a BreakpointSite so the watchpoint-hit
stop reason is lost.

Another was reported by ZequanWu in
https://discourse.llvm.org/t/lldb-unable-to-break-at-start/78282 we
attach to/launch a process with the pc at a BreakpointSite and
misbehave. Caroline Tice mentioned it is also a problem they've had with
putting a breakpoint on _dl_debug_state.

The change to each Process plugin that does execution control is that

1. If we've stopped at a BreakpointSite that has not been executed yet,
we will call Thread::SetThreadStoppedAtUnexecutedBP(pc) to record
that.  When the thread resumes, if the pc is still at the same site, we
will continue, hit the breakpoint, and stop again.

2. When we've actually hit a breakpoint (enabled for this thread or not),
the Process plugin should call Thread::SetThreadHitBreakpointSite().
When we go to resume the thread, we will push a step-over-breakpoint
ThreadPlan before resuming.

The biggest set of changes is to StopInfoMachException where we
translate a Mach Exception into a stop reason. The Mach exception codes
differ in a few places depending on the target (unambiguously), and I
didn't want to duplicate the new code for each target so I've tested
what mach exceptions we get for each action on each target, and
reorganized StopInfoMachException::CreateStopReasonWithMachException to
document these possible values, and handle them without specializing
based on the target arch.

rdar://123942164
---
 lldb/include/lldb/Target/Thread.h |  24 ++
 .../Process/Utility/StopInfoMachException.cpp | 322 --
 .../Process/Windows/Common/ProcessWindows.cpp |  32 +-
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  93 ++---
 .../Process/scripted/ScriptedThread.cpp   |  11 +
 lldb/source/Target/StopInfo.cpp   |   2 +
 lldb/source/Target/Thread.cpp |  15 +-
 .../TestConsecutiveBreakpoints.py |  26 +-
 .../TestStepOverBreakpoint.py |   6 +-
 9 files changed, 266 insertions(+), 265 deletions(-)

diff --git a/lldb/include/lldb/Target/Thread.h 
b/lldb/include/lldb/Target/Thread.h
index 38b65b2bc58490..22d452c7b4b8a3 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ b/lldb/include/lldb/Target/Thread.h
@@ -131,6 +131,7 @@ class Thread : public std::enable_shared_from_this,
 register

[Lldb-commits] [lldb] [LLDB] Add Lexer (with tests) for DIL (Data Inspection Language). (PR #123521)

2025-01-29 Thread via lldb-commits


@@ -0,0 +1,189 @@
+//===-- DILLexer.cpp 
--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// This implements the recursive descent parser for the Data Inspection
+// Language (DIL), and its helper functions, which will eventually underlie the
+// 'frame variable' command. The language that this parser recognizes is
+// described in lldb/docs/dil-expr-lang.ebnf
+//
+//===--===//
+
+#include "lldb/ValueObject/DILLexer.h"
+#include "lldb/Utility/Status.h"
+#include "llvm/ADT/StringSwitch.h"
+
+namespace lldb_private {
+
+namespace dil {
+
+llvm::StringRef Token::GetTokenName(Kind kind) {
+  switch (kind) {
+  case Kind::coloncolon:
+return "coloncolon";
+  case Kind::eof:
+return "eof";
+  case Kind::identifier:
+return "identifier";
+  case Kind::invalid:
+return "invalid";
+  case Kind::kw_namespace:
+return "namespace";
+  case Kind::l_paren:
+return "l_paren";
+  case Kind::none:
+return "none";
+  case Kind::r_paren:
+return "r_paren";
+  case Kind::unknown:
+return "unknown";
+  }
+}
+
+static bool IsLetter(char c) {
+  return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
+}
+
+static bool IsDigit(char c) { return '0' <= c && c <= '9'; }
+
+// A word starts with a letter, underscore, or dollar sign, followed by
+// letters ('a'..'z','A'..'Z'), digits ('0'..'9'), and/or  underscores.
+llvm::iterator_range DILLexer::IsWord() {
+  llvm::StringRef::iterator start = m_cur_pos;
+  bool dollar_start = false;
+
+  // Must not start with a digit.
+  if (m_cur_pos == m_expr.end() || IsDigit(*m_cur_pos))
+return llvm::make_range(m_cur_pos, m_cur_pos);
+
+  // First character *may* be a '$', for a register name or convenience
+  // variable.
+  if (*m_cur_pos == '$') {
+dollar_start = true;
+++m_cur_pos;
+  }
+
+  // Contains only letters, digits or underscores
+  for (; m_cur_pos != m_expr.end(); ++m_cur_pos) {
+char c = *m_cur_pos;
+if (!IsLetter(c) && !IsDigit(c) && c != '_')
+  break;
+  }
+
+  // If first char is '$', make sure there's at least one mare char, or it's
+  // invalid.
+  if (dollar_start && (m_cur_pos - start <= 1)) {
+m_cur_pos = start;
+return llvm::make_range(start, start); // Empty range
+  }
+
+  return llvm::make_range(start, m_cur_pos);
+}
+
+void DILLexer::UpdateLexedTokens(Token &result, Token::Kind tok_kind,
+ std::string tok_str, uint32_t tok_pos) {
+  Token new_token(tok_kind, tok_str, tok_pos);
+  result = new_token;
+  m_lexed_tokens.push_back(std::move(new_token));
+}
+
+llvm::Expected DILLexer::LexAll() {
+  bool done = false;
+  while (!done) {
+auto tok_or_err = Lex();
+if (!tok_or_err)
+  return tok_or_err.takeError();
+Token token = *tok_or_err;
+if (token.GetKind() == Token::eof) {
+  done = true;
+}
+  }
+  return true;
+}
+
+llvm::Expected DILLexer::Lex() {
+  Token result;
+
+  // Skip over whitespace (spaces).
+  while (m_cur_pos != m_expr.end() && *m_cur_pos == ' ')
+m_cur_pos++;
+
+  // Check to see if we've reached the end of our input string.
+  if (m_cur_pos == m_expr.end()) {
+UpdateLexedTokens(result, Token::eof, "", (uint32_t)m_expr.size());
+return result;
+  }
+
+  uint32_t position = m_cur_pos - m_expr.begin();
+  llvm::StringRef::iterator start = m_cur_pos;
+  llvm::iterator_range word_range = IsWord();
+  if (!word_range.empty()) {
+uint32_t length = word_range.end() - word_range.begin();
+llvm::StringRef word(m_expr.substr(position, length));
+// We will be adding more keywords here in the future...
+Token::Kind kind = llvm::StringSwitch(word)
+   .Case("namespace", Token::kw_namespace)
+   .Default(Token::identifier);
+UpdateLexedTokens(result, kind, word.str(), position);
+return result;
+  }
+
+  m_cur_pos = start;
+  llvm::StringRef remainder(m_expr.substr(position, m_expr.end() - m_cur_pos));
+  std::vector> operators = {
+  {Token::l_paren, "("},
+  {Token::r_paren, ")"},
+  {Token::coloncolon, "::"},
+  };
+  for (auto [kind, str] : operators) {
+if (remainder.consume_front(str)) {
+  m_cur_pos += strlen(str);
+  UpdateLexedTokens(result, kind, str, position);
+  return result;
+}
+  }
+
+  // Unrecognized character(s) in string; unable to lex it.
+  Status error("Unable to lex input string");
+  return error.ToError();
+}
+
+const Token &DILLexer::LookAhead(uint32_t N) {
+  if (m_tokens_idx + N + 1 < m_lexed_tokens.size())

cmtice wrote:

I think the  "infinite" stream of eof tokens at the end is ok; I will give it a 
try. :-)

https://github.com/llvm/llvm-project/pull/123521
__

[Lldb-commits] [lldb] [lldb] Remove some unused code in SymbolFileDWARF::ResolveFunction (PR #123206)

2025-01-29 Thread Pavel Labath via lldb-commits

https://github.com/labath closed 
https://github.com/llvm/llvm-project/pull/123206
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] 3cf56b5 - [lldb] Remove some unused code in SymbolFileDWARF::ResolveFunction (#123206)

2025-01-29 Thread via lldb-commits

Author: Pavel Labath
Date: 2025-01-30T08:24:40+01:00
New Revision: 3cf56b5f04cdec567cfab3975ac7b531422c1e2c

URL: 
https://github.com/llvm/llvm-project/commit/3cf56b5f04cdec567cfab3975ac7b531422c1e2c
DIFF: 
https://github.com/llvm/llvm-project/commit/3cf56b5f04cdec567cfab3975ac7b531422c1e2c.diff

LOG: [lldb] Remove some unused code in SymbolFileDWARF::ResolveFunction 
(#123206)

The purpose of this originally was to check for DWARF which refers to
garbage-collected functions (by checking whether we're able to get a
good address out of the function). The address check has been removed in
https://reviews.llvm.org/D112310, so the code computing it is not doing
anything.

Added: 


Modified: 
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Removed: 




diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index afc37f517559ee4..a96757afabddf2e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2455,18 +2455,12 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE 
&orig_die,
   }
   assert(die && die.Tag() == DW_TAG_subprogram);
   if (GetFunction(die, sc)) {
-Address addr;
 // Parse all blocks if needed
 if (inlined_die) {
   Block &function_block = sc.function->GetBlock(true);
   sc.block = function_block.FindBlockByID(inlined_die.GetID());
   if (sc.block == nullptr)
 sc.block = function_block.FindBlockByID(inlined_die.GetOffset());
-  if (sc.block == nullptr || !sc.block->GetStartAddress(addr))
-addr.Clear();
-} else {
-  sc.block = nullptr;
-  addr = sc.function->GetAddressRange().GetBaseAddress();
 }
 
 sc_list.Append(sc);



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Remove some unused code in SymbolFileDWARF::ResolveFunction (PR #123206)

2025-01-29 Thread Pavel Labath via lldb-commits

labath wrote:

I tend to ignore those because people have very different definitions  of NFC, 
but yeah, I guess this would fit most definitions.

https://github.com/llvm/llvm-project/pull/123206
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Use Function::GetAddress in Module::FindFunctions (PR #124938)

2025-01-29 Thread Pavel Labath via lldb-commits

labath wrote:

There isn't a good reason for using GetAddressRange, and removing it is what 
I'm trying to do. But rather than trying to do it all at once, I'm doing it in 
pieces as some of the changes (particularly those that need to iterate over a 
set of ranges) are not trivial. This way I can also verify that each change 
does what it's supposed to do.

I changed most of the trivial call sites when I introduced GetAddress (in 
#115836). In retrospect, this is probably trivial enough that it could have 
been a part of that, but I skipped it then because the mapping part looked 
scary.

https://github.com/llvm/llvm-project/pull/124938
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Only include necessary files in the lldb-dap VSIX (PR #124986)

2025-01-29 Thread Matthew Bastien via lldb-commits

https://github.com/matthewbastien edited 
https://github.com/llvm/llvm-project/pull/124986
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Only include necessary files in the lldb-dap VSIX (PR #124986)

2025-01-29 Thread Matthew Bastien via lldb-commits

https://github.com/matthewbastien edited 
https://github.com/llvm/llvm-project/pull/124986
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Reland "[lldb] Implement basic support for reverse-continue" (#123906)" (PR #123945)

2025-01-29 Thread Robert O'Callahan via lldb-commits

rocallahan wrote:

@DavidSpickett can you apply that change to your branch since this is your PR 
now?

@labath does this pass on x86-via-Rosetta Mac? Should we retry merging with 
this change?

Thanks!

https://github.com/llvm/llvm-project/pull/123945
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb][Windows] WoA HW Watchpoint support in LLDB (PR #108072)

2025-01-29 Thread Omair Javaid via lldb-commits

https://github.com/omjavaid updated 
https://github.com/llvm/llvm-project/pull/108072

>From 82ee1429a0fcf67aa36bf6ca7debb5518211d16c Mon Sep 17 00:00:00 2001
From: Muhammad Omair Javaid 
Date: Tue, 10 Sep 2024 18:03:29 +0500
Subject: [PATCH 1/7] WoA hardware breakpoint/watchpoint support

---
 .../Windows/Common/NativeProcessWindows.cpp   | 52 ---
 .../Common/NativeRegisterContextWindows.cpp   |  3 -
 .../Common/NativeRegisterContextWindows.h |  6 +-
 .../NativeRegisterContextWindows_WoW64.cpp|  4 +-
 .../NativeRegisterContextWindows_arm.cpp  |  4 +-
 .../NativeRegisterContextWindows_arm64.cpp| 86 ++-
 .../NativeRegisterContextWindows_arm64.h  | 32 ++-
 .../NativeRegisterContextWindows_i386.cpp |  4 +-
 .../NativeRegisterContextWindows_x86_64.cpp   |  4 +-
 .../Windows/Common/NativeThreadWindows.cpp| 32 +++
 10 files changed, 135 insertions(+), 92 deletions(-)

diff --git 
a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
index 9c330ff1186709..f38f6e32fcd90d 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
@@ -491,24 +491,47 @@ NativeProcessWindows::OnDebugException(bool first_chance,
 return ExceptionResult::MaskException;
   }
   case DWORD(STATUS_BREAKPOINT):
-  case STATUS_WX86_BREAKPOINT:
-if (FindSoftwareBreakpoint(record.GetExceptionAddress())) {
-  LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
-   record.GetExceptionAddress());
-
-  StopThread(record.GetThreadID(), StopReason::eStopReasonBreakpoint);
-
-  if (NativeThreadWindows *stop_thread =
-  GetThreadByID(record.GetThreadID())) {
-auto ®ister_context = stop_thread->GetRegisterContext();
+  case STATUS_WX86_BREAKPOINT: {
+bool breakpoint_hit = false;
+NativeThreadWindows *stop_thread = GetThreadByID(record.GetThreadID());
+
+if (stop_thread) {
+  uint32_t hw_id = LLDB_INVALID_INDEX32;
+  auto ®_ctx = stop_thread->GetRegisterContext();
+  reg_ctx.GetHardwareBreakHitIndex(hw_id, record.GetExceptionAddress());
+  if (hw_id != LLDB_INVALID_INDEX32) {
+breakpoint_hit = true;
+LLDB_LOG(log, "Hit hardware breakpoint at address {0:x}.",
+ record.GetExceptionAddress());
+  } else if (FindSoftwareBreakpoint(record.GetExceptionAddress())) {
+breakpoint_hit = true;
+LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
+ record.GetExceptionAddress());
 uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset();
 // The current PC is AFTER the BP opcode, on all architectures.
-uint64_t pc = register_context.GetPC() - breakpoint_size;
-register_context.SetPC(pc);
+uint64_t pc = reg_ctx.GetPC() - breakpoint_size;
+reg_ctx.SetPC(pc);
   }
 
-  SetState(eStateStopped, true);
-  return ExceptionResult::MaskException;
+  if (breakpoint_hit) {
+StopThread(record.GetThreadID(), StopReason::eStopReasonBreakpoint);
+SetState(eStateStopped, true);
+return ExceptionResult::MaskException;
+  } else {
+const std::vector &args = record.GetExceptionArguments();
+if (args.size() >= 2) {
+  reg_ctx.GetWatchpointHitIndex(hw_id, args[1]);
+  if (hw_id != LLDB_INVALID_INDEX32) {
+addr_t wp_pc = record.GetExceptionAddress();
+std::string desc =
+formatv("{0} {1} {2}", args[1], hw_id, wp_pc).str();
+StopThread(record.GetThreadID(), StopReason::eStopReasonWatchpoint,
+   desc);
+SetState(eStateStopped, true);
+return ExceptionResult::MaskException;
+  }
+}
+  }
 }
 
 if (!initial_stop) {
@@ -531,6 +554,7 @@ NativeProcessWindows::OnDebugException(bool first_chance,
   // Hit the initial stop. Continue the application.
   return ExceptionResult::BreakInDebugger;
 }
+  }
 
 [[fallthrough]];
   default:
diff --git 
a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp
index 9128363eaa577a..95be1183abb759 100644
--- 
a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp
+++ 
b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp
@@ -18,9 +18,6 @@
 using namespace lldb;
 using namespace lldb_private;
 
-NativeRegisterContextWindows::NativeRegisterContextWindows(
-NativeThreadProtocol &thread, RegisterInfoInterface *reg_info_interface_p)
-: NativeRegisterContextRegisterInfo(thread, reg_info_interface_p) {}
 
 lldb::thread_t NativeRegisterContextWindows::GetThreadHandle() const {
   auto wthread = static_cast(&m_thread);
diff --git 
a/lldb/source/Plugins

[Lldb-commits] [lldb] [lldb] Support CommandInterpreter print callbacks (PR #125006)

2025-01-29 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere created 
https://github.com/llvm/llvm-project/pull/125006

Xcode uses a pseudoterminal for the debugger console.

 - The upside of this apporach is that it means that it can rely on LLDB's 
IOHandlers for multiline and script input.
 - The downside of this approach is that the command output is printed to the 
PTY and you don't get a SBCommandReturnObject. Adrian added support for inline 
diagnostics (#110901) and we'd like to access those from the IDE.

This patch adds support for registering a callback in the command interpreter 
that gives access to the `(SB)CommandReturnObject` right before it will be 
printed. The callback implementation can choose whether it likes to handle 
printing the result or defer to lldb. If the callback indicated it handled the 
result, the command interpreter will skip printing the result.

We considered a few other alternatives to solve this problem:

 - The most obvious one is using `HandleCommand`, which returns a 
`SBCommandReturnObject`. The problem with this approach is the multiline input 
mentioned above. We would need a way to tell the IDE that it should expect 
multiline input, which isn't known until LLDB starts handling the command.
 - To address the multiline issue,we considered exposing (some of the) 
IOHandler machinery through the SB API. To solve this particular issue, that 
would require reimplementing a ton of logic that already exists today in the 
CommandInterpeter. Furthermore that seems like overkill compared to the 
proposed solution.

rdar://141254310


>From fdac9c0292cef848b880904cf84b2c0083065005 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere 
Date: Tue, 28 Jan 2025 15:43:31 -0800
Subject: [PATCH 1/3] [lldb] Fix CommandInterpreter formatting (NFC)

---
 .../lldb/Interpreter/CommandInterpreter.h| 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h 
b/lldb/include/lldb/Interpreter/CommandInterpreter.h
index 2bafc30cc8e23a..910c1d84303354 100644
--- a/lldb/include/lldb/Interpreter/CommandInterpreter.h
+++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h
@@ -100,8 +100,7 @@ class CommandInterpreterRunOptions {
LazyBool stop_on_error, LazyBool stop_on_crash,
LazyBool echo_commands, LazyBool echo_comments,
LazyBool print_results, LazyBool print_errors,
-   LazyBool add_to_history,
-   LazyBool handle_repeats)
+   LazyBool add_to_history, LazyBool 
handle_repeats)
   : m_stop_on_continue(stop_on_continue), m_stop_on_error(stop_on_error),
 m_stop_on_crash(stop_on_crash), m_echo_commands(echo_commands),
 m_echo_comment_commands(echo_comments), m_print_results(print_results),
@@ -248,13 +247,13 @@ class CommandInterpreter : public Broadcaster,
   enum CommandTypes {
 eCommandTypesBuiltin = 0x0001, //< native commands such as "frame"
 eCommandTypesUserDef = 0x0002, //< scripted commands
-eCommandTypesUserMW  = 0x0004, //< multiword commands (command containers)
+eCommandTypesUserMW = 0x0004,  //< multiword commands (command containers)
 eCommandTypesAliases = 0x0008, //< aliases such as "po"
-eCommandTypesHidden  = 0x0010, //< commands prefixed with an underscore
+eCommandTypesHidden = 0x0010,  //< commands prefixed with an underscore
 eCommandTypesAllThem = 0x  //< all commands
   };
 
-  // The CommandAlias and CommandInterpreter both have a hand in 
+  // The CommandAlias and CommandInterpreter both have a hand in
   // substituting for alias commands.  They work by writing special tokens
   // in the template form of the Alias command, and then detecting them when 
the
   // command is executed.  These are the special tokens:
@@ -334,9 +333,8 @@ class CommandInterpreter : public Broadcaster,
   /// dummy "contains everything MWC, so we return null here, but
   /// in this case error.Success is true.
 
-  CommandObjectMultiword *VerifyUserMultiwordCmdPath(Args &path,
- bool leaf_is_command,
- Status &result);
+  CommandObjectMultiword *
+  VerifyUserMultiwordCmdPath(Args &path, bool leaf_is_command, Status &result);
 
   CommandAlias *AddAlias(llvm::StringRef alias_name,
  lldb::CommandObjectSP &command_obj_sp,
@@ -596,7 +594,7 @@ class CommandInterpreter : public Broadcaster,
   void SetEchoCommentCommands(bool enable);
 
   bool GetRepeatPreviousCommand() const;
-  
+
   bool GetRequireCommandOverwrite() const;
 
   const CommandObject::CommandMap &GetUserCommands() const {

>From e1e8d1487194c4e21cf9724da99588796a03883d Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere 
Date: Tue, 28 Jan 2025 16:10:33 -0800
Subject: [PATCH 2/3] [lldb] Constify methods in

[Lldb-commits] [lldb] [lldb] Support CommandInterpreter print callbacks (PR #125006)

2025-01-29 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)


Changes

Xcode uses a pseudoterminal for the debugger console.

 - The upside of this apporach is that it means that it can rely on LLDB's 
IOHandlers for multiline and script input.
 - The downside of this approach is that the command output is printed to the 
PTY and you don't get a SBCommandReturnObject. Adrian added support for inline 
diagnostics (#110901) and we'd like to access those from the IDE.

This patch adds support for registering a callback in the command interpreter 
that gives access to the `(SB)CommandReturnObject` right before it will be 
printed. The callback implementation can choose whether it likes to handle 
printing the result or defer to lldb. If the callback indicated it handled the 
result, the command interpreter will skip printing the result.

We considered a few other alternatives to solve this problem:

 - The most obvious one is using `HandleCommand`, which returns a 
`SBCommandReturnObject`. The problem with this approach is the multiline input 
mentioned above. We would need a way to tell the IDE that it should expect 
multiline input, which isn't known until LLDB starts handling the command.
 - To address the multiline issue,we considered exposing (some of the) 
IOHandler machinery through the SB API. To solve this particular issue, that 
would require reimplementing a ton of logic that already exists today in the 
CommandInterpeter. Furthermore that seems like overkill compared to the 
proposed solution.

rdar://141254310


---

Patch is 25.66 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/125006.diff


17 Files Affected:

- (modified) lldb/bindings/python/python-swigsafecast.swig (+4) 
- (modified) lldb/bindings/python/python-typemaps.swig (+19) 
- (modified) lldb/bindings/python/python-wrapper.swig (+22-2) 
- (modified) lldb/include/lldb/API/SBCommandInterpreter.h (+5-3) 
- (modified) lldb/include/lldb/API/SBCommandReturnObject.h (+2) 
- (modified) lldb/include/lldb/API/SBDefines.h (+3) 
- (modified) lldb/include/lldb/Interpreter/CommandInterpreter.h (+20-9) 
- (modified) lldb/include/lldb/Interpreter/CommandReturnObject.h (+5-5) 
- (modified) lldb/include/lldb/Utility/StreamTee.h (+1-1) 
- (modified) lldb/include/lldb/lldb-enumerations.h (+9) 
- (modified) lldb/source/API/SBCommandInterpreter.cpp (+39-1) 
- (modified) lldb/source/Interpreter/CommandInterpreter.cpp (+40-20) 
- (modified) lldb/source/Interpreter/CommandReturnObject.cpp (+3-2) 
- (modified) lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h 
(+7-6) 
- (added) lldb/test/API/python_api/interpreter_callback/Makefile (+3) 
- (added) 
lldb/test/API/python_api/interpreter_callback/TestCommandInterepterPrintCallback.py
 (+66) 
- (added) lldb/test/API/python_api/interpreter_callback/main.c (+6) 


``diff
diff --git a/lldb/bindings/python/python-swigsafecast.swig 
b/lldb/bindings/python/python-swigsafecast.swig
index 429baad158ca5d..4721dfdc17e6a0 100644
--- a/lldb/bindings/python/python-swigsafecast.swig
+++ b/lldb/bindings/python/python-swigsafecast.swig
@@ -9,6 +9,10 @@ PythonObject 
SWIGBridge::ToSWIGWrapper(std::unique_ptr value_sb)
   return ToSWIGHelper(value_sb.release(), SWIGTYPE_p_lldb__SBValue);
 }
 
+PythonObject 
SWIGBridge::ToSWIGWrapper(std::unique_ptr 
result_up) {
+  return ToSWIGHelper(result_up.release(), 
SWIGTYPE_p_lldb__SBCommandReturnObject);
+}
+
 PythonObject SWIGBridge::ToSWIGWrapper(lldb::ValueObjectSP value_sp) {
   return ToSWIGWrapper(std::unique_ptr(new 
lldb::SBValue(value_sp)));
 }
diff --git a/lldb/bindings/python/python-typemaps.swig 
b/lldb/bindings/python/python-typemaps.swig
index f8c33e15c03e66..88b6cd9ef6b6e7 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -476,6 +476,25 @@ template <> bool SetNumberFromPyObject(double 
&number, PyObject *obj) {
   $1 = $1 || PyCallable_Check(reinterpret_cast($input));
 }
 
+// For lldb::SBCommandPrintCallback
+%typemap(in) (lldb::SBCommandPrintCallback callback, void *baton) {
+  if (!($input == Py_None ||
+PyCallable_Check(reinterpret_cast($input {
+PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+SWIG_fail;
+  }
+
+  // Don't lose the callback reference.
+  Py_INCREF($input);
+  $1 = LLDBSwigPythonCallPythonCommandPrintCallback;
+  $2 = $input;
+}
+
+%typemap(typecheck) (lldb::SBCommandPrintCallback callback, void *baton) {
+  $1 = $input == Py_None;
+  $1 = $1 || PyCallable_Check(reinterpret_cast($input));
+}
+
 %typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {
   if (!($input == Py_None ||
 PyCallable_Check(reinterpret_cast($input {
diff --git a/lldb/bindings/python/python-wrapper.swig 
b/lldb/bindings/python/python-wrapper.swig
index b72a462d04643b..fcabf60008b17d 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wr

[Lldb-commits] [lldb] [lldb] Support CommandInterpreter print callbacks (PR #125006)

2025-01-29 Thread Jonas Devlieghere via lldb-commits

JDevlieghere wrote:

I recommend reviewing the last commit and ignoring the two NFC commits, which I 
will land separately anyway. 

https://github.com/llvm/llvm-project/pull/125006
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring lldb-dap port listening mode to allow multiple connections. (PR #116392)

2025-01-29 Thread John Harrison via lldb-commits


@@ -5058,72 +5053,148 @@ int main(int argc, char *argv[]) {
   auto terminate_debugger =
   llvm::make_scope_exit([] { lldb::SBDebugger::Terminate(); });
 
-  StreamDescriptor input;
-  StreamDescriptor output;
-  std::FILE *redirectOut = nullptr;
-  std::FILE *redirectErr = nullptr;
-  if (portno != -1) {
-printf("Listening on port %i...\n", portno);
-SOCKET socket_fd = AcceptConnection(log.get(), portno);
-if (socket_fd < 0)
-  return EXIT_FAILURE;
+  std::vector pre_init_commands;
+  for (const std::string &arg :
+   input_args.getAllArgValues(OPT_pre_init_command)) {
+pre_init_commands.push_back(arg);
+  }
 
-input = StreamDescriptor::from_socket(socket_fd, true);
-output = StreamDescriptor::from_socket(socket_fd, false);
-  } else {
-#if defined(_WIN32)
-// Windows opens stdout and stdin in text mode which converts \n to 13,10
-// while the value is just 10 on Darwin/Linux. Setting the file mode to
-// binary fixes this.
-int result = _setmode(fileno(stdout), _O_BINARY);
-assert(result);
-result = _setmode(fileno(stdin), _O_BINARY);
-UNUSED_IF_ASSERT_DISABLED(result);
-assert(result);
-#endif
+  auto HandleClient =
+  [=, log = log.get()](std::string name, StreamDescriptor input,
+   StreamDescriptor output, std::FILE *redirectOut,
+   std::FILE *redirectErr) -> bool {
+DAP dap = DAP(name, program_path.str(), log, default_repl_mode,
+  std::move(input), std::move(output));
 
-int stdout_fd = DuplicateFileDescriptor(fileno(stdout));
-if (stdout_fd == -1) {
+// stdout/stderr redirection to the IDE's console
+if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) {
   llvm::logAllUnhandledErrors(
-  llvm::errorCodeToError(llvm::errnoAsErrorCode()), llvm::errs(),
-  "Failed to configure stdout redirect: ");
+  std::move(Err), llvm::errs(),
+  "Failed to configure lldb-dap IO operations: ");
   return EXIT_FAILURE;
 }
 
-redirectOut = stdout;
-redirectErr = stderr;
+RegisterRequestCallbacks(dap);
 
-input = StreamDescriptor::from_file(fileno(stdin), false);
-output = StreamDescriptor::from_file(stdout_fd, false);
-  }
+dap.pre_init_commands = pre_init_commands;
 
-  DAP dap = DAP(program_path.str(), log.get(), default_repl_mode,
-std::move(input), std::move(output));
+// used only by TestVSCode_redirection_to_console.py
+if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
+  redirection_test();
 
-  // stdout/stderr redirection to the IDE's console
-  if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) {
-llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(),
-"Failed to configure lldb-dap IO operations: 
");
-return EXIT_FAILURE;
-  }
+if (auto Err = dap.Loop()) {
+  if (log)
+*log << "Transport Error: " << llvm::toString(std::move(Err)) << "\n";
+  return false;
+}
+return true;
+  };
 
-  RegisterRequestCallbacks(dap);
+  if (!connection.empty()) {
+auto maybeProtoclAndName = parseConnection(connection);
+if (auto Err = maybeProtoclAndName.takeError()) {
+  llvm::errs() << "Invalid connection specification " << Err << "\n";
+  return EXIT_FAILURE;
+}
 
-  for (const std::string &arg :
-   input_args.getAllArgValues(OPT_pre_init_command)) {
-dap.pre_init_commands.push_back(arg);
-  }
+Socket::SocketProtocol protocol;
+std::string name;
+std::tie(protocol, name) = *maybeProtoclAndName;
 
-  // used only by TestVSCode_redirection_to_console.py
-  if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
-redirection_test();
+Status error;
+std::unique_ptr listener = Socket::Create(protocol, error);
+if (error.Fail()) {
+  llvm::errs() << "Failed to create listener for protocol "
+   << Socket::FindSchemeByProtocol(protocol)
+   << ", error: " << error.takeError() << "\n";
+  return EXIT_FAILURE;
+}
 
-  bool CleanExit = true;
-  if (auto Err = dap.Loop()) {
+error = listener->Listen(name, /* backlog */ 5);
+if (error.Fail()) {
+  llvm::errs() << "Failed to listen, error: " << error.takeError() << "\n";
+  return EXIT_FAILURE;
+}
+
+std::string address =
+llvm::join(listener->GetListeningConnectionURI(), ", ");
 if (log)
-  *log << "Transport Error: " << llvm::toString(std::move(Err)) << "\n";
-CleanExit = false;
+  *log << "started with connection listeners " << address << "\n";
+
+llvm::outs() << "Listening for: " << address << "\n";
+// Ensure listening address are flushed for calles to retrieve the resolve
+// address.
+llvm::outs().flush();
+
+MainLoop mainloop;
+mainloop.RegisterSignal(
+SIGHUP, [](auto &RL) { RL.RequestTermination(); }, error);
+
+unsigne

[Lldb-commits] [lldb] [lldb] Support CommandInterpreter print callbacks (PR #125006)

2025-01-29 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere updated 
https://github.com/llvm/llvm-project/pull/125006

>From fdac9c0292cef848b880904cf84b2c0083065005 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere 
Date: Tue, 28 Jan 2025 15:43:31 -0800
Subject: [PATCH 1/4] [lldb] Fix CommandInterpreter formatting (NFC)

---
 .../lldb/Interpreter/CommandInterpreter.h| 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h 
b/lldb/include/lldb/Interpreter/CommandInterpreter.h
index 2bafc30cc8e23a..910c1d84303354 100644
--- a/lldb/include/lldb/Interpreter/CommandInterpreter.h
+++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h
@@ -100,8 +100,7 @@ class CommandInterpreterRunOptions {
LazyBool stop_on_error, LazyBool stop_on_crash,
LazyBool echo_commands, LazyBool echo_comments,
LazyBool print_results, LazyBool print_errors,
-   LazyBool add_to_history,
-   LazyBool handle_repeats)
+   LazyBool add_to_history, LazyBool 
handle_repeats)
   : m_stop_on_continue(stop_on_continue), m_stop_on_error(stop_on_error),
 m_stop_on_crash(stop_on_crash), m_echo_commands(echo_commands),
 m_echo_comment_commands(echo_comments), m_print_results(print_results),
@@ -248,13 +247,13 @@ class CommandInterpreter : public Broadcaster,
   enum CommandTypes {
 eCommandTypesBuiltin = 0x0001, //< native commands such as "frame"
 eCommandTypesUserDef = 0x0002, //< scripted commands
-eCommandTypesUserMW  = 0x0004, //< multiword commands (command containers)
+eCommandTypesUserMW = 0x0004,  //< multiword commands (command containers)
 eCommandTypesAliases = 0x0008, //< aliases such as "po"
-eCommandTypesHidden  = 0x0010, //< commands prefixed with an underscore
+eCommandTypesHidden = 0x0010,  //< commands prefixed with an underscore
 eCommandTypesAllThem = 0x  //< all commands
   };
 
-  // The CommandAlias and CommandInterpreter both have a hand in 
+  // The CommandAlias and CommandInterpreter both have a hand in
   // substituting for alias commands.  They work by writing special tokens
   // in the template form of the Alias command, and then detecting them when 
the
   // command is executed.  These are the special tokens:
@@ -334,9 +333,8 @@ class CommandInterpreter : public Broadcaster,
   /// dummy "contains everything MWC, so we return null here, but
   /// in this case error.Success is true.
 
-  CommandObjectMultiword *VerifyUserMultiwordCmdPath(Args &path,
- bool leaf_is_command,
- Status &result);
+  CommandObjectMultiword *
+  VerifyUserMultiwordCmdPath(Args &path, bool leaf_is_command, Status &result);
 
   CommandAlias *AddAlias(llvm::StringRef alias_name,
  lldb::CommandObjectSP &command_obj_sp,
@@ -596,7 +594,7 @@ class CommandInterpreter : public Broadcaster,
   void SetEchoCommentCommands(bool enable);
 
   bool GetRepeatPreviousCommand() const;
-  
+
   bool GetRequireCommandOverwrite() const;
 
   const CommandObject::CommandMap &GetUserCommands() const {

>From e1e8d1487194c4e21cf9724da99588796a03883d Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere 
Date: Tue, 28 Jan 2025 16:10:33 -0800
Subject: [PATCH 2/4] [lldb] Constify methods in CommandReturnObject (NFC)

---
 lldb/include/lldb/Interpreter/CommandReturnObject.h | 10 +-
 lldb/include/lldb/Utility/StreamTee.h   |  2 +-
 lldb/source/Interpreter/CommandReturnObject.cpp |  5 +++--
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h 
b/lldb/include/lldb/Interpreter/CommandReturnObject.h
index 9fef59337016df..f96da34889a324 100644
--- a/lldb/include/lldb/Interpreter/CommandReturnObject.h
+++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h
@@ -32,9 +32,9 @@ class CommandReturnObject {
   ~CommandReturnObject() = default;
 
   /// Format any inline diagnostics with an indentation of \c indent.
-  std::string GetInlineDiagnosticString(unsigned indent);
+  std::string GetInlineDiagnosticString(unsigned indent) const;
 
-  llvm::StringRef GetOutputString() {
+  llvm::StringRef GetOutputString() const {
 lldb::StreamSP 
stream_sp(m_out_stream.GetStreamAtIndex(eStreamStringIndex));
 if (stream_sp)
   return std::static_pointer_cast(stream_sp)->GetString();
@@ -46,7 +46,7 @@ class CommandReturnObject {
   /// If \c with_diagnostics is true, all diagnostics are also
   /// rendered into the string. Otherwise the expectation is that they
   /// are fetched with \ref GetInlineDiagnosticString().
-  std::string GetErrorString(bool with_diagnostics = true);
+  std::string GetErrorString(bool with_diagnostics = true) const;
   StructuredData:

[Lldb-commits] [lldb] [lldb] Support CommandInterpreter print callbacks (PR #125006)

2025-01-29 Thread Jonas Devlieghere via lldb-commits

JDevlieghere wrote:

> If this result printing callback was also passed the command string (which it 
> has from just above where the callback is called) then this would also be an 
> easy way to do logging of command execution. That's not needed for your 
> current purpose, but would add another strong motivation for this change...

Adrian made a similar observation offline. What do you think about putting that 
in the `CommandReturnObject`? This seems generally useful and that way it's not 
tied to the callback. 

https://github.com/llvm/llvm-project/pull/125006
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Only include necessary files in the lldb-dap VSIX (PR #124986)

2025-01-29 Thread Matthew Bastien via lldb-commits

https://github.com/matthewbastien edited 
https://github.com/llvm/llvm-project/pull/124986
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Use Function::GetAddress in Module::FindFunctions (PR #124938)

2025-01-29 Thread via lldb-commits

jimingham wrote:

This looks fine, but more generally, is there any good reason to ever use 
Function::GetAddressRange?  Shouldn't that just be removed and all the 
instances replaced with either GetAddress or get the ranges and iterate over 
them looking for whatever they wanted?

https://github.com/llvm/llvm-project/pull/124938
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb][Windows] WoA HW Watchpoint support in LLDB (PR #108072)

2025-01-29 Thread Omair Javaid via lldb-commits


@@ -575,6 +575,10 @@ Changes to LLDB
  24   int main() {
   Likely cause: f->b->d accessed 0x4
   ```
+* LLDB now supports hardware watchpoints for AArch64 Windows targets. Windows
+  does not provide API to query the number of supported hardware watchpoints.
+  Therefore current implementation allows only 1 watchpoint, as tested with
+  Windows 11 on the Microsoft SQ2 and Snapdragon Elite X platforms.

omjavaid wrote:

I have run all tests individually and only those test fail now which require 
more than single hardware watchpoint resources. I am not really sure why ninja 
check-lldb fails the watchpoint test even when run single threaded but all 
tests pass when they are run via dotest.py individually. 

https://github.com/llvm/llvm-project/pull/108072
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [NFC][lldb] Document a few ivars on the value object system. (PR #124971)

2025-01-29 Thread via lldb-commits


@@ -1187,6 +1187,7 @@ class EntityResultVariable : public Materializer::Entity {
 
 private:
   CompilerType m_type;
+  /// If this result entity can (and should) track the value on inferior 
memory.

jimingham wrote:

on -> in?

https://github.com/llvm/llvm-project/pull/124971
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [NFC][lldb] Document a few ivars on the value object system. (PR #124971)

2025-01-29 Thread via lldb-commits

jimingham wrote:

Other than that tiny quibble, these are accurate and helpful comments.

https://github.com/llvm/llvm-project/pull/124971
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb][Windows] WoA HW Watchpoint support in LLDB (PR #108072)

2025-01-29 Thread Omair Javaid via lldb-commits


@@ -492,23 +492,40 @@ NativeProcessWindows::OnDebugException(bool first_chance,
   }
   case DWORD(STATUS_BREAKPOINT):
   case STATUS_WX86_BREAKPOINT:

omjavaid wrote:

yes. Heres the detail from ntstatus.h
//
// MessageId: STATUS_WX86_BREAKPOINT
//
// MessageText:
//
// Exception status code used by Win32 x86 emulation subsystem.
//
#define STATUS_WX86_BREAKPOINT   ((NTSTATUS)0x401FL)

https://github.com/llvm/llvm-project/pull/108072
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Support CommandInterpreter print callbacks (PR #125006)

2025-01-29 Thread via lldb-commits


@@ -1012,6 +1012,26 @@ static void 
LLDBSwigPythonCallPythonLogOutputCallback(const char *str,
   }
 }
 
+// For DebuggerTerminateCallback functions

jimingham wrote:

Is this comment right?

https://github.com/llvm/llvm-project/pull/125006
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Support CommandInterpreter print callbacks (PR #125006)

2025-01-29 Thread via lldb-commits


@@ -0,0 +1,66 @@
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class BreakpointAPITestCase(TestBase):
+NO_DEBUG_INFO_TESTCASE = True
+
+def run_command_interpreter_with_output_file(self, out_filename, 
input_str):
+with open(out_filename, "w") as f:
+self.dbg.SetOutputFileHandle(f, False)
+self.dbg.SetInputString(input_str)
+opts = lldb.SBCommandInterpreterRunOptions()
+self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
+
+def test_command_interpreter_print_callback(self):
+"""Make sure that if an SBBreakpoint gets deleted its IsValid returns 
false."""

jimingham wrote:

That's not what this test does, is it?

https://github.com/llvm/llvm-project/pull/125006
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Support CommandInterpreter print callbacks (PR #125006)

2025-01-29 Thread via lldb-commits

jimingham wrote:

Man there's a lot of boiler plate in hooking up to SWIG...  But this all looks 
right to me.  

I wondered whether the callback would benefit from knowing whether the result 
had been dumped immediately or not, but I can't think of a good reason for that.

If this result printing callback was also passed the command string (which it 
has from just above where the callback is called) then this would also be an 
easy way to do logging of command execution.  That's not needed for your 
current purpose, but would add another strong motivation for this change...

https://github.com/llvm/llvm-project/pull/125006
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Extended if conditions to support alias names for registers (PR #124475)

2025-01-29 Thread David Spickett via lldb-commits

DavidSpickett wrote:

> I have created two tests.

Which is great, but we need live processes too and I found those, they are in 
`lldb/test/Shell/Register/` for example 
`lldb/test/Shell/Register/aarch64-gp-read.test`. For some reason we don't check 
all registers there just parameter registers, but there's no reason you can't 
check them all for RISC-V.

It's probably simpler to set each register to `1+register_number` so x0 is 1 
and x1 is 2 and so on. Instead of loading values from memory as that example 
does.

The logic of that test is set all the registers in inline asm, then manually 
break before the inline asm block finishes, so that compiler generated code 
doesn't restore the values.

> However, it turned out that register read x8 is not working. I think, there 
> is some edge case because it has fp and s0.

It's very possible that we have never had a register with 3 names before, or we 
have support for it but the code that checks them doesn't know that.

> I am not sure whether to try to fix this in this PR or another one?

I would investigate why this error happens and if you can fix it, see what the 
changes look like. It can probably be a PR after this one, that updates the 
tests now that they work. But we'll keep this one open while you do that in 
case it makes more sense to bundle them.

If it seems like it's going to be a massive job to fix it, just let us know 
what you found and I'll take a look too. I don't want to drown you in 
unexpected work.

https://github.com/llvm/llvm-project/pull/124475
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Fix "in function" detection in "thread until" (PR #123622)

2025-01-29 Thread Pavel Labath via lldb-commits

labath wrote:

ping @jimingham 

https://github.com/llvm/llvm-project/pull/123622
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Remove some unused code in SymbolFileDWARF::ResolveFunction (PR #123206)

2025-01-29 Thread Greg Clayton via lldb-commits

https://github.com/clayborg approved this pull request.

Want to add a [NFC] to the title as well?

https://github.com/llvm/llvm-project/pull/123206
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][Docs] Expand remote testing instructions (PR #122694)

2025-01-29 Thread David Spickett via lldb-commits

DavidSpickett wrote:

ping!

https://github.com/llvm/llvm-project/pull/122694
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add support for gdb-style 'x' packet (PR #124733)

2025-01-29 Thread Pavel Labath via lldb-commits

labath wrote:

Let's continue the discussion 
[here](https://discourse.llvm.org/t/rfc-fixing-incompatibilties-of-the-x-packet-w-r-t-gdb/84288/8).
 

(It could work it's just not how gdb implemented it. Sniffing of zero-length 
reads was considered, but a qSupported feature was deemed more principled. I 
suppose one advantage of that is that it saves us one round-trip (after we no 
longer need to support/detect the lldb-x implementation))

https://github.com/llvm/llvm-project/pull/124733
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Use Function::GetAddress in Module::FindFunctions (PR #124938)

2025-01-29 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Pavel Labath (labath)


Changes

The original code resulted in a misfire in the symtab vs. debug info 
deduplication code, which caused us to return the same function twice when 
searching via a regex (for functions whose entry point is also not the lowest 
address).

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


2 Files Affected:

- (modified) lldb/source/Core/Module.cpp (+2-3) 
- (modified) lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s 
(+16-4) 


``diff
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 9601c834d9b8fe..33668c5d20dde4 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -919,9 +919,8 @@ void Module::FindFunctions(const RegularExpression ®ex,
   const SymbolContext &sc = sc_list[i];
   if (sc.block)
 continue;
-  file_addr_to_index[sc.function->GetAddressRange()
- .GetBaseAddress()
- .GetFileAddress()] = i;
+  file_addr_to_index[sc.function->GetAddress().GetFileAddress()] =
+  i;
 }
 
 FileAddrToIndexMap::const_iterator end = file_addr_to_index.end();
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s 
b/lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s
index 93ea9f33e762df..197ab9aa14910e 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s
@@ -6,17 +6,29 @@
 # The function bar has been placed "in the middle" of foo, and the function
 # entry point is deliberately not its lowest address.
 
-# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t
-# RUN: %lldb %t -o "image lookup -v -n foo" -o "expr -- &foo" -o exit | 
FileCheck %s
+# RUN: split-file %s %t
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %t/input.s -o %t/input.o
+# RUN: %lldb %t/input.o -s %t/commands -o exit | FileCheck %s
 
-# CHECK-LABEL: image lookup
+#--- commands
+
+image lookup -v -n foo
+# CHECK-LABEL: image lookup -v -n foo
+# CHECK: 1 match found in {{.*}}
+# CHECK: Summary: input.o`foo
+# CHECK: Function: id = {{.*}}, name = "foo", ranges = 
[0x-0x000e)[0x0014-0x001c)
+
+image lookup -v --regex -n '^foo$'
+# CHECK-LABEL: image lookup -v --regex -n '^foo$'
 # CHECK: 1 match found in {{.*}}
-# CHECK: Summary: {{.*}}`foo
+# CHECK: Summary: input.o`foo
 # CHECK: Function: id = {{.*}}, name = "foo", ranges = 
[0x-0x000e)[0x0014-0x001c)
 
+expr -- &foo
 # CHECK-LABEL: expr -- &foo
 # CHECK: (void (*)()) $0 = 0x0007
 
+#--- input.s
 .text
 
 foo.__part.1:

``




https://github.com/llvm/llvm-project/pull/124938
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB] Add Lexer (with tests) for DIL (Data Inspection Language). (PR #123521)

2025-01-29 Thread via lldb-commits

cmtice wrote:

If DIL is not allowed to recognize any operators except period, arrow, and 
parentheses, it seems to me that it won't be any more powerful than the current 
'frame variable' implementation, in which case what is the point of having it 
at all?  (As a matter of fact, it would be less powerful, since  'frame 
variable' also recognizes square brackets and star as valid operators and 
treats them accordingly).

At the same time, I understand the concern about wanting to be able to parse 
synthetic variable names, which can contain arbitrary operator-like symbols.  
So I have a tentative proposal:  How about insisting that  synthetic variable 
names need to be surrounded by special delimiters, such as backquote or slash?  
Or having some other way of marking them as special?

https://github.com/llvm/llvm-project/pull/123521
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB] Add Lexer (with tests) for DIL (Data Inspection Language). (PR #123521)

2025-01-29 Thread via lldb-commits

cmtice wrote:

> > If DIL is not allowed to recognize any operators except period, arrow, and 
> > parentheses, it seems to me that it won't be any more powerful than the 
> > current 'frame variable' implementation, in which case what is the point of 
> > having it at all? (As a matter of fact, it would be less powerful, since 
> > 'frame variable' also recognizes square brackets and star as valid 
> > operators and treats them accordingly).
> > At the same time, I understand the concern about wanting to be able to 
> > parse synthetic variable names, which can contain arbitrary operator-like 
> > symbols. So I have a tentative proposal: How about insisting that synthetic 
> > variable names need to be surrounded by special delimiters, such as 
> > backquote or slash? Or having some other way of marking them as special?
> 
> These are unfortunately visible to the user, and they will have to type them 
> in `frame var` to access the child. So we can't make them something ugly.

I don't want to make them ugly, but I *do* think we need to ask the user to 
distinguish them in some way. Otherwise I don't see how we can make DIL any 
more powerful than the current 'frame variable'.

https://github.com/llvm/llvm-project/pull/123521
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB] Add Lexer (with tests) for DIL (Data Inspection Language). (PR #123521)

2025-01-29 Thread via lldb-commits

jimingham wrote:

> I agree with everything except for the last part. The current parser already 
> threats `[]` [very 
> specially](https://github.com/llvm/llvm-project/blob/89ca3e72ca03efbbfb5ae9b1c71d81f2d1753521/lldb/source/Target/StackFrame.cpp#L781).
>  I think it has to do that so it can treat pointers as C arrays (and then it 
> just special cases synthetic objects). I think that's a (mostly *) reasonable 
> setup that we could replicate in the new DIL implementation, particularly as 
> we would need special handling of `[]` to implement things like `[i+1]`.
> 

We would have to change how synthetic children are made currently for array 
like things for this to work.  If I have a std:vector called `foo` and I write:

(lldb) v foo[0]

and the DIL parses that it will either ask foo for a child named `0`, which 
doesn't exist, or ask it for the 0th child which currently is not required to 
be the one called `[0]`.  I think I mentioned this back when we were first 
discussing this, but if we want to make this part work, then we have to add 
some API on the synthetic child provider like `AddVectorChild(size_t idx, 
ValueObjectSP child_sp)` and require you use that to make vector like things.  
Then we could require that the child named `[0]` HAS to be the 0th child, etc.

We still have the problem of all the synthetic child providers in the wild that 
might not do this. 

> FWIW, I believe that the main source of keywords in Caroline's implementation 
> is types (for casts). I think they could be handled generically (just ask the 
> target whether the identifier names a type), were it not for the nasty C(++) 
> habit of creating multiword types (`unsigned long long long long int`). 
> Still, it feels there ought to be recognise these without making `unsigned` a 
> full-fledged keyword.

That comes back to how soon we expect to know the language as we are parsing.  
`unsigned` is a perfectly good variable name in swift, for instance...  I don't 
think we want to limit lldb to only C-family languages.

> 
> (*) I was recently made aware of an unfortunate difference in behavior of 
> `frame var` and `expr` for map types:
> 
> ```
> (lldb) v m
> (std::map) m = size=3 {
>   [0] = (first = -42, second = -47)
>   [1] = (first = 0, second = 42)
>   [2] = (first = 42, second = 47)
> }
> (lldb) v m[0]
> (std::__1::__value_type::value_type) m[0] = (first = -42, second = 
> -47)
> (lldb) expr m[0]
> (std::map::mapped_type) $0 = 42
> ```
> 
> I know that these are different languages, but this still seems like it could 
> confuse some people. I don't have any specific ideas on how to fix/improve 
> this though...

Yes, collection classes that use arbitrary types for the keys are problematic.  
How would we show the map if the keys are structures with some non-trivial 
compare function in a way that wouldn't be awful to use?  I don't think we can 
get around people having to know that `v` path expressions are NOT expressions 
in the underlying language.

https://github.com/llvm/llvm-project/pull/123521
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Reland "[lldb] Implement basic support for reverse-continue" (#123906)" (PR #123945)

2025-01-29 Thread Pavel Labath via lldb-commits

https://github.com/labath edited 
https://github.com/llvm/llvm-project/pull/123945
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Reland "[lldb] Implement basic support for reverse-continue" (#123906)" (PR #123945)

2025-01-29 Thread Pavel Labath via lldb-commits


@@ -0,0 +1,537 @@
+import os
+import os.path
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.gdbclientutils import *
+from lldbsuite.test.lldbgdbproxy import *
+import lldbgdbserverutils
+import re
+
+
+class ThreadSnapshot:
+def __init__(self, thread_id, registers):
+self.thread_id = thread_id
+self.registers = registers
+
+
+class MemoryBlockSnapshot:
+def __init__(self, address, data):
+self.address = address
+self.data = data
+
+
+class StateSnapshot:
+def __init__(self, thread_snapshots, memory):
+self.thread_snapshots = thread_snapshots
+self.memory = memory
+self.thread_id = None
+
+
+class RegisterInfo:
+def __init__(self, lldb_index, name, bitsize, little_endian):
+self.lldb_index = lldb_index
+self.name = name
+self.bitsize = bitsize
+self.little_endian = little_endian
+
+
+BELOW_STACK_POINTER = 16384
+ABOVE_STACK_POINTER = 4096
+
+BLOCK_SIZE = 1024
+
+SOFTWARE_BREAKPOINTS = 0
+HARDWARE_BREAKPOINTS = 1
+WRITE_WATCHPOINTS = 2
+
+
+class ReverseTestBase(GDBProxyTestBase):
+"""
+Base class for tests that need reverse execution.
+
+This class uses a gdbserver proxy to add very limited reverse-
+execution capability to lldb-server/debugserver for testing
+purposes only.
+
+To use this class, run the inferior forward until some stopping point.
+Then call `start_recording()` and execute forward again until reaching
+a software breakpoint; this class records the state before each execution 
executes.
+At that point, the server will accept "bc" and "bs" packets to step
+backwards through the state.
+When executing during recording, we only allow single-step and continue 
without
+delivering a signal, and only software breakpoint stops are allowed.
+
+We assume that while recording is enabled, the only effects of instructions
+are on general-purpose registers (read/written by the 'g' and 'G' packets)
+and on memory bytes between [SP - BELOW_STACK_POINTER, SP + 
ABOVE_STACK_POINTER).
+"""
+
+NO_DEBUG_INFO_TESTCASE = True
+
+"""
+A list of StateSnapshots in time order.
+
+There is one snapshot per single-stepped instruction,
+representing the state before that instruction was
+executed. The last snapshot in the list is the
+snapshot before the last instruction was executed.
+This is an undo log; we snapshot a superset of the state that may have
+been changed by the instruction's execution.
+"""
+snapshots = None
+recording_enabled = False
+
+breakpoints = None
+
+pc_register_info = None
+sp_register_info = None
+general_purpose_register_info = None
+
+def __init__(self, *args, **kwargs):
+GDBProxyTestBase.__init__(self, *args, **kwargs)
+self.breakpoints = [set(), set(), set(), set(), set()]
+
+def respond(self, packet):
+if not packet:
+raise ValueError("Invalid empty packet")
+if packet == self.server.PACKET_INTERRUPT:
+# Don't send a response. We'll just run to completion.
+return []
+if self.is_command(packet, "qSupported", ":"):
+# Disable multiprocess support in the server and in LLDB
+# since Mac debugserver doesn't support it and we want lldb-server 
to
+# be consistent with that
+reply = self.pass_through(packet.replace(";multiprocess", ""))
+return reply.replace(";multiprocess", "") + 
";ReverseStep+;ReverseContinue+"
+if packet == "c" or packet == "s":
+packet = "vCont;" + packet
+elif (
+packet[0] == "c" or packet[0] == "s" or packet[0] == "C" or 
packet[0] == "S"
+):
+raise ValueError(
+"Old-style continuation packets with address or signal not 
supported yet"
+)
+if self.is_command(packet, "vCont", ";"):
+if self.recording_enabled:
+return self.continue_with_recording(packet)
+snapshots = []
+if packet == "bc":
+return self.reverse_continue()
+if packet == "bs":
+return self.reverse_step()
+if packet == "jThreadsInfo":
+# Suppress this because it contains thread stop reasons which we 
might
+# need to modify, and we don't want to have to implement that.
+return ""
+if packet[0] == "z" or packet[0] == "Z":

labath wrote:

```suggestion
if packet[0] == "x":
# Suppress *binary* reads as results starting with "O" can be 
mistaken for an output packet
# by the test server code
return ""
if packet[0] == "z" or packet[0] == "Z":
```

https://github.com/llvm/llvm-project/pull/123945
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm

[Lldb-commits] [lldb] Reland "[lldb] Implement basic support for reverse-continue" (#123906)" (PR #123945)

2025-01-29 Thread Pavel Labath via lldb-commits

https://github.com/labath approved this pull request.

After much deliberation, I came to the conclusion that it's best to just work 
around this problem, given that we're going to be changing how the `x` packet 
works (and removing the ambiguity) anyway.

This usage technically was not ambiguous because the output packet can only be 
sent when the target is running (so it can't be confused with an `x` response), 
but the test code was not tracking the run state of the server. I tried 
teaching it to do that, but wasn't particularly happy with the result, and 
given the `x` change, the added complication would not be necessary anyway. For 
a time I also wanted to wait until the servers start sending the new `x` 
response, but now it looks like that may still take quite some time.

TL;DR: LGTM with the inline suggestion applied

https://github.com/llvm/llvm-project/pull/123945
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [NFC][lldb] Document a few ivars on the value object system. (PR #124971)

2025-01-29 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere approved this pull request.

LGTM with one solution since you're already improving the comments. 

https://github.com/llvm/llvm-project/pull/124971
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [NFC][lldb] Document a few ivars on the value object system. (PR #124971)

2025-01-29 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere edited 
https://github.com/llvm/llvm-project/pull/124971
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [NFC][lldb] Document a few ivars on the value object system. (PR #124971)

2025-01-29 Thread Jonas Devlieghere via lldb-commits


@@ -108,7 +108,14 @@ class ExpressionVariable
   FlagType m_flags; // takes elements of Flags
 
   // these should be private

JDevlieghere wrote:

```suggestion
  /// These members should be private.
  /// @{
  [...]
  lldb::ValueObjectSP m_live_sp;
  /// @}
```

https://github.com/llvm/llvm-project/pull/124971
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [DebugInfo] Add explicit visibility macros to CodeView template functions (PR #113102)

2025-01-29 Thread Thomas Fransham via lldb-commits

https://github.com/fsfod updated 
https://github.com/llvm/llvm-project/pull/113102

>From 79408f0a5703c1174ef98130a4106c61cd593d76 Mon Sep 17 00:00:00 2001
From: Thomas Fransham 
Date: Mon, 12 Aug 2024 16:04:12 +0100
Subject: [PATCH 1/2] [DebugInfo] Add explicit visibility macros to CodeView
 template functions

These will be needed for when llvm is built as a shared library on windows with
explicit visibility macros enabled.
Change UnionRecord to class instead of a struct so we can use X macros from
CodeViewTypes.def to forward declare all record classes.

This is part of the work to enable LLVM_BUILD_LLVM_DYLIB and LLVM plugins on 
window.
---
 .../SymbolFile/NativePDB/SymbolFileNativePDB.h |  2 +-
 .../DebugInfo/CodeView/ContinuationRecordBuilder.h | 14 ++
 .../llvm/DebugInfo/CodeView/SimpleTypeSerializer.h | 13 +
 llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h  |  3 ++-
 4 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h 
b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index b0e78a243a3c24..479a8724e2adef 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -32,7 +32,7 @@ class ClassRecord;
 class EnumRecord;
 class ModifierRecord;
 class PointerRecord;
-struct UnionRecord;
+class UnionRecord;
 } // namespace codeview
 } // namespace llvm
 
diff --git a/llvm/include/llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h 
b/llvm/include/llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h
index 84cef520a2f460..8347ef870d0676 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h
@@ -50,6 +50,20 @@ class ContinuationRecordBuilder {
 
   std::vector end(TypeIndex Index);
 };
+
+// Needed by RandomAccessVisitorTest.cpp
+#define TYPE_RECORD(EnumName, EnumVal, Name)
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD(EnumName, EnumVal, Name) 
\
+  extern template LLVM_TEMPLATE_ABI void 
ContinuationRecordBuilder::writeMemberType(\
+  Name##Record &Record);
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+#undef TYPE_RECORD
+#undef TYPE_RECORD_ALIAS
+#undef MEMBER_RECORD
+#undef MEMBER_RECORD_ALIAS
+
 } // namespace codeview
 } // namespace llvm
 
diff --git a/llvm/include/llvm/DebugInfo/CodeView/SimpleTypeSerializer.h 
b/llvm/include/llvm/DebugInfo/CodeView/SimpleTypeSerializer.h
index fcc0452a6ae9a7..713798fc38d2d8 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/SimpleTypeSerializer.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/SimpleTypeSerializer.h
@@ -32,6 +32,19 @@ class SimpleTypeSerializer {
   ArrayRef serialize(const FieldListRecord &Record) = delete;
 };
 
+// Needed by RandomAccessVisitorTest.cpp
+#define TYPE_RECORD(EnumName, EnumVal, Name)   
\
+  class Name##Record;  
\
+  extern template LLVM_TEMPLATE_ABI ArrayRef 
llvm::codeview::SimpleTypeSerializer::serialize(  \
+  Name##Record &Record);
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD(EnumName, EnumVal, Name)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+#undef TYPE_RECORD
+#undef TYPE_RECORD_ALIAS
+#undef MEMBER_RECORD
+#undef MEMBER_RECORD_ALIAS
 } // end namespace codeview
 } // end namespace llvm
 
diff --git a/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h 
b/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
index 5a84fac5f59034..484e05b5adc672 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
@@ -495,7 +495,8 @@ class ClassRecord : public TagRecord {
 };
 
 // LF_UNION
-struct UnionRecord : public TagRecord {
+class UnionRecord : public TagRecord {
+public:
   UnionRecord() = default;
   explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
   UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,

>From 0d429239bfa598736c0eb7cb99c5726ba7d7ae93 Mon Sep 17 00:00:00 2001
From: Thomas Fransham 
Date: Sun, 20 Oct 2024 20:35:48 +0100
Subject: [PATCH 2/2] Fix formatting

---
 .../llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h   | 4 ++--
 llvm/include/llvm/DebugInfo/CodeView/SimpleTypeSerializer.h   | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h 
b/llvm/include/llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h
index 8347ef870d0676..3de138f37be2d2 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h

[Lldb-commits] [lldb] [lldb] Fix "in function" detection in "thread until" (PR #123622)

2025-01-29 Thread via lldb-commits


@@ -970,19 +969,21 @@ class CommandObjectThreadUntil : public 
CommandObjectParsed {
   return;
 }
 
-AddressRange fun_addr_range = sc.function->GetAddressRange();
-Address fun_start_addr = fun_addr_range.GetBaseAddress();
-line_table->FindLineEntryByAddress(fun_start_addr, function_start,
-   &index_ptr);
-
-Address fun_end_addr(fun_start_addr.GetSection(),
- fun_start_addr.GetOffset() +
- fun_addr_range.GetByteSize());
-
-bool all_in_function = true;
+uint32_t lowest_func_idx = UINT32_MAX;
+uint32_t highest_func_idx = 0;
+for (AddressRange range : sc.function->GetAddressRanges()) {
+  uint32_t idx;
+  LineEntry unused;
+  Address addr = range.GetBaseAddress();
+  if (line_table->FindLineEntryByAddress(addr, unused, &idx))
+lowest_func_idx = std::min(lowest_func_idx, idx);
+
+  addr.Slide(range.GetByteSize() - 1);

jimingham wrote:

This deserves a comment.

https://github.com/llvm/llvm-project/pull/123622
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Fix "in function" detection in "thread until" (PR #123622)

2025-01-29 Thread via lldb-commits


@@ -1007,29 +1009,29 @@ class CommandObjectThreadUntil : public 
CommandObjectParsed {
 addr_t address =
 line_entry.range.GetBaseAddress().GetLoadAddress(target);
 if (address != LLDB_INVALID_ADDRESS) {
-  if (fun_addr_range.ContainsLoadAddress(address, target))
+  AddressRange unused;
+  if (sc.function->GetRangeContainingLoadAddress(address, *target,
+ unused))
 address_list.push_back(address);
-  else
-all_in_function = false;
 }
 start_idx_ptr++;
   }
 }
 
 for (lldb::addr_t address : m_options.m_until_addrs) {
-  if (fun_addr_range.ContainsLoadAddress(address, target))
+  AddressRange unused;
+  if (sc.function->GetRangeContainingLoadAddress(address, *target,
+ unused))
 address_list.push_back(address);
-  else
-all_in_function = false;
 }
 
 if (address_list.empty()) {

jimingham wrote:

Since you only care here about `found_something` and `address_list.size > 0` 
could you short-circuit this search when you find the first address that 
matches the line?

https://github.com/llvm/llvm-project/pull/123622
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Fix "in function" detection in "thread until" (PR #123622)

2025-01-29 Thread via lldb-commits


@@ -970,19 +969,21 @@ class CommandObjectThreadUntil : public 
CommandObjectParsed {
   return;
 }
 
-AddressRange fun_addr_range = sc.function->GetAddressRange();
-Address fun_start_addr = fun_addr_range.GetBaseAddress();
-line_table->FindLineEntryByAddress(fun_start_addr, function_start,
-   &index_ptr);
-
-Address fun_end_addr(fun_start_addr.GetSection(),
- fun_start_addr.GetOffset() +
- fun_addr_range.GetByteSize());
-
-bool all_in_function = true;
+uint32_t lowest_func_idx = UINT32_MAX;
+uint32_t highest_func_idx = 0;
+for (AddressRange range : sc.function->GetAddressRanges()) {
+  uint32_t idx;
+  LineEntry unused;
+  Address addr = range.GetBaseAddress();
+  if (line_table->FindLineEntryByAddress(addr, unused, &idx))
+lowest_func_idx = std::min(lowest_func_idx, idx);
+
+  addr.Slide(range.GetByteSize() - 1);

jimingham wrote:

Magical -1's...

https://github.com/llvm/llvm-project/pull/123622
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB] Add Lexer (with tests) for DIL (Data Inspection Language). (PR #123521)

2025-01-29 Thread via lldb-commits

jimingham wrote:

> If DIL is not allowed to recognize any operators except period, arrow, and 
> parentheses, it seems to me that it won't be any more powerful than the 
> current 'frame variable' implementation, in which case what is the point of 
> having it at all? (As a matter of fact, it would be less powerful, since 
> 'frame variable' also recognizes square brackets and star as valid operators 
> and treats them accordingly).
> 
> At the same time, I understand the concern about wanting to be able to parse 
> synthetic variable names, which can contain arbitrary operator-like symbols. 
> So I have a tentative proposal: How about insisting that synthetic variable 
> names need to be surrounded by special delimiters, such as backquote or 
> slash? Or having some other way of marking them as special?

These are unfortunately visible to the user, and they will have to type them in 
`frame var` to access the child.  So we can't make them something ugly.

https://github.com/llvm/llvm-project/pull/123521
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [NFC][lldb] Document a few ivars on the value object system. (PR #124971)

2025-01-29 Thread Augusto Noronha via lldb-commits

https://github.com/augusto2112 created 
https://github.com/llvm/llvm-project/pull/124971

None

>From cd28fcaf8739a32897a09bd661cb805b3960a7c7 Mon Sep 17 00:00:00 2001
From: Augusto Noronha 
Date: Wed, 29 Jan 2025 10:53:23 -0800
Subject: [PATCH] [NFC][lldb] Document a few ivars on the value object system.

---
 lldb/include/lldb/Expression/ExpressionVariable.h  | 7 +++
 lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h | 4 
 lldb/source/Expression/Materializer.cpp| 1 +
 3 files changed, 12 insertions(+)

diff --git a/lldb/include/lldb/Expression/ExpressionVariable.h 
b/lldb/include/lldb/Expression/ExpressionVariable.h
index fc36793b3a475c..a2175dee7dca9e 100644
--- a/lldb/include/lldb/Expression/ExpressionVariable.h
+++ b/lldb/include/lldb/Expression/ExpressionVariable.h
@@ -108,7 +108,14 @@ class ExpressionVariable
   FlagType m_flags; // takes elements of Flags
 
   // these should be private
+  /// A value object whose value's data lives in host (lldb's) memory.
   lldb::ValueObjectSP m_frozen_sp;
+  /// The ValueObject counterpart to m_frozen_sp that tracks the value in
+  /// inferior memory. This object may not always exist; its presence depends 
on
+  /// whether it is logical for the value to exist in the inferior memory. For
+  /// example, when evaluating a C++ expression that generates an r-value, such
+  /// as a single function call, there is no memory address in the inferior to
+  /// track.
   lldb::ValueObjectSP m_live_sp;
 };
 
diff --git a/lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h 
b/lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h
index dbd68160acb4dc..5509886a8965da 100644
--- a/lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h
+++ b/lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h
@@ -66,6 +66,10 @@ class ValueObjectConstResultImpl {
 
 private:
   ValueObject *m_impl_backend;
+  /// The memory address in the inferior process that this ValueObject tracks.
+  /// This address is used to request additional memory when the actual data
+  /// size exceeds the initial local buffer size, such as when a dynamic type
+  /// resolution results in a type larger than its statically determined type.
   lldb::addr_t m_live_address;
   AddressType m_live_address_type;
   lldb::ValueObjectSP m_address_of_backend;
diff --git a/lldb/source/Expression/Materializer.cpp 
b/lldb/source/Expression/Materializer.cpp
index 8cd050f9fdb7ef..500b8c098f7ca8 100644
--- a/lldb/source/Expression/Materializer.cpp
+++ b/lldb/source/Expression/Materializer.cpp
@@ -1187,6 +1187,7 @@ class EntityResultVariable : public Materializer::Entity {
 
 private:
   CompilerType m_type;
+  /// If this result entity can (and should) track the value on inferior 
memory.
   bool m_is_program_reference;
   bool m_keep_in_memory;
 

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [NFC][lldb] Document a few ivars on the value object system. (PR #124971)

2025-01-29 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Augusto Noronha (augusto2112)


Changes



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


3 Files Affected:

- (modified) lldb/include/lldb/Expression/ExpressionVariable.h (+7) 
- (modified) lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h (+4) 
- (modified) lldb/source/Expression/Materializer.cpp (+1) 


``diff
diff --git a/lldb/include/lldb/Expression/ExpressionVariable.h 
b/lldb/include/lldb/Expression/ExpressionVariable.h
index fc36793b3a475c..a2175dee7dca9e 100644
--- a/lldb/include/lldb/Expression/ExpressionVariable.h
+++ b/lldb/include/lldb/Expression/ExpressionVariable.h
@@ -108,7 +108,14 @@ class ExpressionVariable
   FlagType m_flags; // takes elements of Flags
 
   // these should be private
+  /// A value object whose value's data lives in host (lldb's) memory.
   lldb::ValueObjectSP m_frozen_sp;
+  /// The ValueObject counterpart to m_frozen_sp that tracks the value in
+  /// inferior memory. This object may not always exist; its presence depends 
on
+  /// whether it is logical for the value to exist in the inferior memory. For
+  /// example, when evaluating a C++ expression that generates an r-value, such
+  /// as a single function call, there is no memory address in the inferior to
+  /// track.
   lldb::ValueObjectSP m_live_sp;
 };
 
diff --git a/lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h 
b/lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h
index dbd68160acb4dc..5509886a8965da 100644
--- a/lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h
+++ b/lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h
@@ -66,6 +66,10 @@ class ValueObjectConstResultImpl {
 
 private:
   ValueObject *m_impl_backend;
+  /// The memory address in the inferior process that this ValueObject tracks.
+  /// This address is used to request additional memory when the actual data
+  /// size exceeds the initial local buffer size, such as when a dynamic type
+  /// resolution results in a type larger than its statically determined type.
   lldb::addr_t m_live_address;
   AddressType m_live_address_type;
   lldb::ValueObjectSP m_address_of_backend;
diff --git a/lldb/source/Expression/Materializer.cpp 
b/lldb/source/Expression/Materializer.cpp
index 8cd050f9fdb7ef..500b8c098f7ca8 100644
--- a/lldb/source/Expression/Materializer.cpp
+++ b/lldb/source/Expression/Materializer.cpp
@@ -1187,6 +1187,7 @@ class EntityResultVariable : public Materializer::Entity {
 
 private:
   CompilerType m_type;
+  /// If this result entity can (and should) track the value on inferior 
memory.
   bool m_is_program_reference;
   bool m_keep_in_memory;
 

``




https://github.com/llvm/llvm-project/pull/124971
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits