[Lldb-commits] [lldb] [lldb-dap] Implement a MemoryMonitor for macOS & Linux (PR #129332)

2025-02-28 Thread John Harrison via lldb-commits

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

Looks great!

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


[Lldb-commits] [lldb] [lldb-dap] Add process picker command to VS Code extension (PR #128943)

2025-02-28 Thread John Harrison via lldb-commits


@@ -0,0 +1,38 @@
+import { ChildProcessWithoutNullStreams, spawn } from "child_process";
+import { BaseProcessTree, ProcessTreeParser } from "../base-process-tree";
+
+export class LinuxProcessTree extends BaseProcessTree {
+  protected override spawnProcess(): ChildProcessWithoutNullStreams {
+return spawn(
+  "ps",
+  ["-axo", `pid=PID,lstart=START,comm:128=COMMAND,command=ARGUMENTS`],
+  {
+stdio: "pipe",
+  },

ashgti wrote:

`stdio: "pipe"` is the default

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


[Lldb-commits] [lldb] [lldb] Add terminfo dependency for ncurses support (PR #126810)

2025-02-28 Thread Jordan R AW via lldb-commits

ajordanr-google wrote:

/cherry-pick 8d017e6c0178f2628b246c18b2a634909815e54f 
eec242aa97c8d153574923f8237754ca3fa6f0a6

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


[Lldb-commits] [lldb] [lldb] Add terminfo dependency for ncurses support (PR #126810)

2025-02-28 Thread via lldb-commits

llvmbot wrote:


>/cherry-pick 8d017e6c0178f2628b246c18b2a634909815e54f 
>eec242aa97c8d153574923f8237754ca3fa6f0a6

Error: Command failed due to missing milestone.

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


[Lldb-commits] [lldb] 11b9466 - [lldb] Add ability to inspect backing threads with `thread info` (#129275)

2025-02-28 Thread via lldb-commits

Author: Felipe de Azevedo Piovezan
Date: 2025-02-28T16:13:12-08:00
New Revision: 11b9466c04db4da7439fc1d9d8ba7241a9d68705

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

LOG: [lldb] Add ability to inspect backing threads with `thread info` (#129275)

When OS plugins are present, it can be helpful to query information
about the backing thread behind an OS thread, if it exists. There is no
mechanism to do so prior to this commit.

As a first step, this commit enhances `thread info` with a
`--backing-thread` flag, causing the command to use the backing thread
of the selected thread, if it exists.

Added: 


Modified: 
lldb/source/Commands/CommandObjectThread.cpp
lldb/source/Commands/Options.td
lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py

Removed: 




diff  --git a/lldb/source/Commands/CommandObjectThread.cpp 
b/lldb/source/Commands/CommandObjectThread.cpp
index cd3d2d89333f1..224c523e69c5c 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -1270,6 +1270,7 @@ class CommandObjectThreadInfo : public 
CommandObjectIterateOverThreads {
 void OptionParsingStarting(ExecutionContext *execution_context) override {
   m_json_thread = false;
   m_json_stopinfo = false;
+  m_backing_thread = false;
 }
 
 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
@@ -1286,6 +1287,10 @@ class CommandObjectThreadInfo : public 
CommandObjectIterateOverThreads {
 m_json_stopinfo = true;
 break;
 
+  case 'b':
+m_backing_thread = true;
+break;
+
   default:
 llvm_unreachable("Unimplemented option");
   }
@@ -1298,6 +1303,7 @@ class CommandObjectThreadInfo : public 
CommandObjectIterateOverThreads {
 
 bool m_json_thread;
 bool m_json_stopinfo;
+bool m_backing_thread;
   };
 
   CommandObjectThreadInfo(CommandInterpreter &interpreter)
@@ -1334,6 +1340,8 @@ class CommandObjectThreadInfo : public 
CommandObjectIterateOverThreads {
 }
 
 Thread *thread = thread_sp.get();
+if (m_options.m_backing_thread && thread->GetBackingThread())
+  thread = thread->GetBackingThread().get();
 
 Stream &strm = result.GetOutputStream();
 if (!thread->GetDescription(strm, eDescriptionLevelFull,

diff  --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 8831fed38435b..cc579d767eb06 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1108,6 +1108,9 @@ let Command = "thread info" in {
 " JSON format.">;
   def thread_info_stop_info : Option<"stop-info", "s">, Desc<"Display the "
 "extended stop info in JSON format.">;
+  def thread_info_backing_thread : Option<"backing-thread", "b">,
+Desc<"If this is an OS plugin thread, query the backing thread instead; 
has"
+" no effect otherwise.">;
 }
 
 let Command = "thread return" in {

diff  --git 
a/lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py 
b/lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py
index fe78edd98f4d4..e4997f0742d02 100644
--- 
a/lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py
+++ 
b/lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py
@@ -131,6 +131,26 @@ def run_python_os_funcionality(self):
 "Make sure there is no thread 0x3 after we unload the 
python OS plug-in",
 )
 
+tid_regex = re.compile(r"tid = ((0x)?[0-9a-fA-F]+)")
+
+def get_tid_from_thread_info_command(self, thread, use_backing_thread):
+interp = self.dbg.GetCommandInterpreter()
+result = lldb.SBCommandReturnObject()
+
+backing_thread_arg = ""
+if use_backing_thread:
+backing_thread_arg = "--backing-thread"
+
+interp.HandleCommand(
+"thread info {0} {1}".format(thread.GetIndexID(), 
backing_thread_arg),
+result,
+True,
+)
+self.assertTrue(result.Succeeded(), "failed to run thread info")
+match = self.tid_regex.search(result.GetOutput())
+self.assertNotEqual(match, None)
+return int(match.group(1), 0)
+
 def run_python_os_step(self):
 """Test that the Python operating system plugin works correctly and 
allows single stepping of a virtual thread that is backed by a real thread"""
 
@@ -209,6 +229,11 @@ def run_python_os_step(self):
 # it to
 thread.StepOver()
 
+tid_os = self.get_tid_from_thread_info_command(thread, False)
+self.assertEqual(tid_os, 0x1)
+tid_real = self.get_tid_from_thread_info_command(thread, True)
+self.assertNotEqual(tid_os, tid_real)
+
   

[Lldb-commits] [lldb] [lldb] Add terminfo dependency for ncurses support (PR #126810)

2025-02-28 Thread Jordan R AW via lldb-commits

ajordanr-google wrote:

/cherry-pick 8fff0c181f26a5e8b2344c061ebf2559118b1160 
bb6a273d9ab9ee90dbb957e541f4d810fffb22ee

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


[Lldb-commits] [lldb] Fix a bug copying the stop hooks from the dummy target. (PR #129340)

2025-02-28 Thread via lldb-commits

https://github.com/jimingham created 
https://github.com/llvm/llvm-project/pull/129340

We didn't also copy over the next stop hook id, which meant we would overwrite 
the stop hooks from the dummy target with stop hooks set after they are copied 
over.

>From 02e908312518e85f1d637529c9f62e3dd9551035 Mon Sep 17 00:00:00 2001
From: Jim Ingham 
Date: Fri, 28 Feb 2025 15:55:03 -0800
Subject: [PATCH] Fix a bug copying the stop hooks from the dummy target. We
 didn't also copy over the next stop hook id, which meant we would overwrite
 the stop hooks from the dummy target with stop hooks set after they are
 copied over.

---
 lldb/source/Target/Target.cpp |  1 +
 .../target/stop-hooks/TestStopHooks.py| 24 +--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index db289fe9c4b64..550424720e095 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -211,6 +211,7 @@ Target::~Target() {
 
 void Target::PrimeFromDummyTarget(Target &target) {
   m_stop_hooks = target.m_stop_hooks;
+  m_stop_hook_next_id = target.m_stop_hook_next_id;
 
   for (const auto &breakpoint_sp : target.m_breakpoint_list.Breakpoints()) {
 if (breakpoint_sp->IsInternal())
diff --git a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py 
b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
index fe59bd8a5d007..5215ec7258d14 100644
--- a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
+++ b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
@@ -26,10 +26,15 @@ def test_stop_hooks_step_out(self):
 self.step_out_test()
 
 def test_stop_hooks_after_expr(self):
-"""Test that a stop hook fires when hitting a breakpoint
-that runs an expression"""
+"""Test that a stop hook fires when hitting a breakpoint that
+   runs an expression"""
 self.after_expr_test()
 
+def test_stop_hooks_before_and_after_creation(self):
+"""Test that if we add a stop hook in the dummy target, we can
+   they don't collide with ones set directly in the target."""
+self.before_and_after_target()
+
 def step_out_test(self):
 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
 self, "Set a breakpoint here", self.main_source_file
@@ -85,3 +90,18 @@ def after_expr_test(self):
 var = target.FindFirstGlobalVariable("g_var")
 self.assertTrue(var.IsValid())
 self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var")
+
+def before_and_after_target(self):
+interp = self.dbg.GetCommandInterpreter()
+result = lldb.SBCommandReturnObject()
+interp.HandleCommand("target stop-hook add -o 'expr g_var++'", result)
+self.assertTrue(result.Succeeded(), "Set the target stop hook")
+
+(target, process, thread, first_bkpt) = 
lldbutil.run_to_source_breakpoint(
+self, "Set a breakpoint here", self.main_source_file
+)
+
+interp.HandleCommand("target stop-hook add -o 'thread backtrace'", 
result)
+self.assertTrue(result.Succeeded(), "Set the target stop hook")
+self.expect("target stop-hook list", substrs=["expr g_var++", "thread 
backtrace"])
+

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


[Lldb-commits] [lldb] Fix a bug copying the stop hooks from the dummy target. (PR #129340)

2025-02-28 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: None (jimingham)


Changes

We didn't also copy over the next stop hook id, which meant we would overwrite 
the stop hooks from the dummy target with stop hooks set after they are copied 
over.

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


2 Files Affected:

- (modified) lldb/source/Target/Target.cpp (+1) 
- (modified) lldb/test/API/commands/target/stop-hooks/TestStopHooks.py (+22-2) 


``diff
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index db289fe9c4b64..550424720e095 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -211,6 +211,7 @@ Target::~Target() {
 
 void Target::PrimeFromDummyTarget(Target &target) {
   m_stop_hooks = target.m_stop_hooks;
+  m_stop_hook_next_id = target.m_stop_hook_next_id;
 
   for (const auto &breakpoint_sp : target.m_breakpoint_list.Breakpoints()) {
 if (breakpoint_sp->IsInternal())
diff --git a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py 
b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
index fe59bd8a5d007..5215ec7258d14 100644
--- a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
+++ b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
@@ -26,10 +26,15 @@ def test_stop_hooks_step_out(self):
 self.step_out_test()
 
 def test_stop_hooks_after_expr(self):
-"""Test that a stop hook fires when hitting a breakpoint
-that runs an expression"""
+"""Test that a stop hook fires when hitting a breakpoint that
+   runs an expression"""
 self.after_expr_test()
 
+def test_stop_hooks_before_and_after_creation(self):
+"""Test that if we add a stop hook in the dummy target, we can
+   they don't collide with ones set directly in the target."""
+self.before_and_after_target()
+
 def step_out_test(self):
 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
 self, "Set a breakpoint here", self.main_source_file
@@ -85,3 +90,18 @@ def after_expr_test(self):
 var = target.FindFirstGlobalVariable("g_var")
 self.assertTrue(var.IsValid())
 self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var")
+
+def before_and_after_target(self):
+interp = self.dbg.GetCommandInterpreter()
+result = lldb.SBCommandReturnObject()
+interp.HandleCommand("target stop-hook add -o 'expr g_var++'", result)
+self.assertTrue(result.Succeeded(), "Set the target stop hook")
+
+(target, process, thread, first_bkpt) = 
lldbutil.run_to_source_breakpoint(
+self, "Set a breakpoint here", self.main_source_file
+)
+
+interp.HandleCommand("target stop-hook add -o 'thread backtrace'", 
result)
+self.assertTrue(result.Succeeded(), "Set the target stop hook")
+self.expect("target stop-hook list", substrs=["expr g_var++", "thread 
backtrace"])
+

``




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


[Lldb-commits] [lldb] [LLDB][Minidump]Update MinidumpFileBuilder to read and write in chunks (PR #129307)

2025-02-28 Thread Jacob Lalonde via lldb-commits

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


[Lldb-commits] [lldb] Fix a bug copying the stop hooks from the dummy target. (PR #129340)

2025-02-28 Thread via lldb-commits

github-actions[bot] wrote:




:warning: Python code formatter, darker found issues in your code. :warning:



You can test this locally with the following command:


``bash
darker --check --diff -r 
273fca94d4c4896df15f967a1388b7c533b76062...02e908312518e85f1d637529c9f62e3dd9551035
 lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
``





View the diff from darker here.


``diff
--- TestStopHooks.py2025-02-28 23:55:03.00 +
+++ TestStopHooks.py2025-03-01 00:01:09.460330 +
@@ -25,16 +25,16 @@
 """Test that stop hooks fire on step-out."""
 self.step_out_test()
 
 def test_stop_hooks_after_expr(self):
 """Test that a stop hook fires when hitting a breakpoint that
-   runs an expression"""
+runs an expression"""
 self.after_expr_test()
 
 def test_stop_hooks_before_and_after_creation(self):
 """Test that if we add a stop hook in the dummy target, we can
-   they don't collide with ones set directly in the target."""
+they don't collide with ones set directly in the target."""
 self.before_and_after_target()
 
 def step_out_test(self):
 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
 self, "Set a breakpoint here", self.main_source_file
@@ -101,7 +101,8 @@
 self, "Set a breakpoint here", self.main_source_file
 )
 
 interp.HandleCommand("target stop-hook add -o 'thread backtrace'", 
result)
 self.assertTrue(result.Succeeded(), "Set the target stop hook")
-self.expect("target stop-hook list", substrs=["expr g_var++", "thread 
backtrace"])
-
+self.expect(
+"target stop-hook list", substrs=["expr g_var++", "thread 
backtrace"]
+)

``




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


[Lldb-commits] [lldb] [lldb] Add terminfo dependency for ncurses support (PR #126810)

2025-02-28 Thread via lldb-commits

llvmbot wrote:

/pull-request llvm/llvm-project#129342

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


[Lldb-commits] [lldb] [lldb] Add ability to inspect backing threads with `thread info` (PR #129275)

2025-02-28 Thread Felipe de Azevedo Piovezan via lldb-commits

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


[Lldb-commits] [lldb] Fix a bug copying the stop hooks from the dummy target. (PR #129340)

2025-02-28 Thread via lldb-commits

https://github.com/jimingham updated 
https://github.com/llvm/llvm-project/pull/129340

>From 02e908312518e85f1d637529c9f62e3dd9551035 Mon Sep 17 00:00:00 2001
From: Jim Ingham 
Date: Fri, 28 Feb 2025 15:55:03 -0800
Subject: [PATCH 1/2] Fix a bug copying the stop hooks from the dummy target.
 We didn't also copy over the next stop hook id, which meant we would
 overwrite the stop hooks from the dummy target with stop hooks set after they
 are copied over.

---
 lldb/source/Target/Target.cpp |  1 +
 .../target/stop-hooks/TestStopHooks.py| 24 +--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index db289fe9c4b64..550424720e095 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -211,6 +211,7 @@ Target::~Target() {
 
 void Target::PrimeFromDummyTarget(Target &target) {
   m_stop_hooks = target.m_stop_hooks;
+  m_stop_hook_next_id = target.m_stop_hook_next_id;
 
   for (const auto &breakpoint_sp : target.m_breakpoint_list.Breakpoints()) {
 if (breakpoint_sp->IsInternal())
diff --git a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py 
b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
index fe59bd8a5d007..5215ec7258d14 100644
--- a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
+++ b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
@@ -26,10 +26,15 @@ def test_stop_hooks_step_out(self):
 self.step_out_test()
 
 def test_stop_hooks_after_expr(self):
-"""Test that a stop hook fires when hitting a breakpoint
-that runs an expression"""
+"""Test that a stop hook fires when hitting a breakpoint that
+   runs an expression"""
 self.after_expr_test()
 
+def test_stop_hooks_before_and_after_creation(self):
+"""Test that if we add a stop hook in the dummy target, we can
+   they don't collide with ones set directly in the target."""
+self.before_and_after_target()
+
 def step_out_test(self):
 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
 self, "Set a breakpoint here", self.main_source_file
@@ -85,3 +90,18 @@ def after_expr_test(self):
 var = target.FindFirstGlobalVariable("g_var")
 self.assertTrue(var.IsValid())
 self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var")
+
+def before_and_after_target(self):
+interp = self.dbg.GetCommandInterpreter()
+result = lldb.SBCommandReturnObject()
+interp.HandleCommand("target stop-hook add -o 'expr g_var++'", result)
+self.assertTrue(result.Succeeded(), "Set the target stop hook")
+
+(target, process, thread, first_bkpt) = 
lldbutil.run_to_source_breakpoint(
+self, "Set a breakpoint here", self.main_source_file
+)
+
+interp.HandleCommand("target stop-hook add -o 'thread backtrace'", 
result)
+self.assertTrue(result.Succeeded(), "Set the target stop hook")
+self.expect("target stop-hook list", substrs=["expr g_var++", "thread 
backtrace"])
+

>From 72e6f179525f1e13e7a1617ab04853304d116537 Mon Sep 17 00:00:00 2001
From: Jim Ingham 
Date: Fri, 28 Feb 2025 16:23:31 -0800
Subject: [PATCH 2/2] uglify

---
 .../test/API/commands/target/stop-hooks/TestStopHooks.py | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py 
b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
index 5215ec7258d14..c2cdcf0e2af52 100644
--- a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
+++ b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
@@ -27,12 +27,12 @@ def test_stop_hooks_step_out(self):
 
 def test_stop_hooks_after_expr(self):
 """Test that a stop hook fires when hitting a breakpoint that
-   runs an expression"""
+runs an expression"""
 self.after_expr_test()
 
 def test_stop_hooks_before_and_after_creation(self):
 """Test that if we add a stop hook in the dummy target, we can
-   they don't collide with ones set directly in the target."""
+they don't collide with ones set directly in the target."""
 self.before_and_after_target()
 
 def step_out_test(self):
@@ -103,5 +103,6 @@ def before_and_after_target(self):
 
 interp.HandleCommand("target stop-hook add -o 'thread backtrace'", 
result)
 self.assertTrue(result.Succeeded(), "Set the target stop hook")
-self.expect("target stop-hook list", substrs=["expr g_var++", "thread 
backtrace"])
-
+self.expect(
+"target stop-hook list", substrs=["expr g_var++", "thread 
backtrace"]
+)

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


[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)

2025-02-28 Thread Matthew Bastien via lldb-commits

https://github.com/matthewbastien updated 
https://github.com/llvm/llvm-project/pull/129262

>From b40c3e7e4ebb154c5f231676451acbd17e1f39f7 Mon Sep 17 00:00:00 2001
From: Matthew Bastien 
Date: Fri, 28 Feb 2025 11:08:25 -0500
Subject: [PATCH 1/2] allow providing debug adapter arguments

---
 lldb/tools/lldb-dap/package.json  | 23 ++
 .../lldb-dap/src-ts/debug-adapter-factory.ts  | 72 +--
 2 files changed, 72 insertions(+), 23 deletions(-)

diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index cd450a614b3f7..aa11d8bcaa66e 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -75,6 +75,15 @@
   "type": "string",
   "description": "The path to the lldb-dap binary."
 },
+"lldb-dap.arguments": {
+  "scope": "resource",
+  "type": "array",
+  "default": [],
+  "items": {
+"type": "string"
+  },
+  "description": "The arguments provided to the lldb-dap process."
+},
 "lldb-dap.log-path": {
   "scope": "resource",
   "type": "string",
@@ -162,6 +171,13 @@
 "type": "string",
 "markdownDescription": "The absolute path to the LLDB debug 
adapter executable to use."
   },
+  "debugAdapterArgs": {
+"type": "array",
+"items": {
+  "type": "string"
+},
+"markdownDescription": "The list of arguments used to launch 
the debug adapter executable."
+  },
   "program": {
 "type": "string",
 "description": "Path to the program to debug."
@@ -352,6 +368,13 @@
 "type": "string",
 "markdownDescription": "The absolute path to the LLDB debug 
adapter executable to use."
   },
+  "debugAdapterArgs": {
+"type": "array",
+"items": {
+  "type": "string"
+},
+"markdownDescription": "The list of arguments used to launch 
the debug adapter executable."
+  },
   "program": {
 "type": "string",
 "description": "Path to the program to attach to."
diff --git a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts 
b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
index 1f76fe31b00ad..51f45f87d660a 100644
--- a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
+++ b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
@@ -25,7 +25,7 @@ async function findWithXcrun(executable: string): 
Promise {
   if (stdout) {
 return stdout.toString().trimEnd();
   }
-} catch (error) { }
+} catch (error) {}
   }
   return undefined;
 }
@@ -93,13 +93,33 @@ async function getDAPExecutable(
   return undefined;
 }
 
+function getDAPArguments(session: vscode.DebugSession): string[] {
+  // Check the debug configuration for arguments first
+  const debugConfigArgs = session.configuration.debugAdapterArgs;
+  if (
+Array.isArray(debugConfigArgs) &&
+debugConfigArgs.findIndex((entry) => typeof entry !== "string") === -1
+  ) {
+return debugConfigArgs;
+  }
+  // Fall back on the workspace configuration
+  return vscode.workspace
+.getConfiguration("lldb-dap")
+.get("arguments", []);
+}
+
 /**
  * This class defines a factory used to find the lldb-dap binary to use
  * depending on the session configuration.
  */
 export class LLDBDapDescriptorFactory
-  implements vscode.DebugAdapterDescriptorFactory, vscode.Disposable {
-  private server?: Promise<{ process: child_process.ChildProcess, host: 
string, port: number }>;
+  implements vscode.DebugAdapterDescriptorFactory, vscode.Disposable
+{
+  private server?: Promise<{
+process: child_process.ChildProcess;
+host: string;
+port: number;
+  }>;
 
   dispose() {
 this.server?.then(({ process }) => {
@@ -109,7 +129,7 @@ export class LLDBDapDescriptorFactory
 
   async createDebugAdapterDescriptor(
 session: vscode.DebugSession,
-executable: vscode.DebugAdapterExecutable | undefined,
+_executable: vscode.DebugAdapterExecutable | undefined,
   ): Promise {
 const config = vscode.workspace.getConfiguration(
   "lldb-dap",
@@ -123,7 +143,7 @@ export class LLDBDapDescriptorFactory
 }
 const configEnvironment =
   config.get<{ [key: string]: string }>("environment") || {};
-const dapPath = (await getDAPExecutable(session)) ?? executable?.command;
+const dapPath = await getDAPExecutable(session);
 
 if (!dapPath) {
   LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage();
@@ -137,32 +157,38 @@ export class LLDBDapDescriptorFactory
 
 const dbgOptions = {
   env: {
-...executable?.options?.env,
 ...configEnvironment,
 ...env,
   },
 };
-const dbgArgs = executable?.args ?? [];
+

[Lldb-commits] [lldb] Update MinidumpFileBuilder to read and write in chunks (PR #129307)

2025-02-28 Thread Jacob Lalonde via lldb-commits

https://github.com/Jlalond created 
https://github.com/llvm/llvm-project/pull/129307

I recently received an internal error report that LLDB was OOM'ing when 
creating a Minidump. In my 64b refactor we made a decision to acquire buffers 
the size of the largest memory region so we could read all of the contents in 
one call. This made error handling very simple (and simpler coding for me!) but 
had the trade off of large allocations if huge pages were enabled.

This patch is one I've had on the back burner for awhile, but we can read and 
write the Minidump memory sections in discrete chunks which we already do for 
writing to disk.

I had to refactor the error handling a bit, but it remains the same. We make a 
best effort attempt to read as much of the memory region as possible, but fail 
immediately if we receive an error writing to disk. I did not add new tests for 
this because our existing test suite is quite good, but I did manually verify a 
few Minidumps couldn't read beyond the red_zone.

```
(lldb) reg read $sp
 rsp = 0x7fffc3b0
(lldb) p/x 0x7fffc3b0 - 128
(long) 0x7fffc330
(lldb) memory read 0x7fffc330
0x7fffc330: 60 c3 ff ff ff 7f 00 00 60 cd ff ff ff 7f 00 00  
`...`...
0x7fffc340: 60 c3 ff ff ff 7f 00 00 65 e6 26 00 00 00 00 00  
`...e.&.
(lldb) memory read 0x7fffc329
error: could not parse memory info
```

I'm not sure how to quantify the memory improvement other than we would 
allocate the largest size regardless of the size. So a 2gb unreadable region 
would cause a 2gb allocation even if we were reading 4096 kb. Now we will take 
the range size or the max chunk size of 128 mb.

>From 2f77beefb752ffdae908101d75381268203311d6 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde 
Date: Fri, 28 Feb 2025 11:38:35 -0800
Subject: [PATCH] Update MinidumpFileBuilder to read and write in chunks

---
 .../Minidump/MinidumpFileBuilder.cpp  | 130 --
 .../ObjectFile/Minidump/MinidumpFileBuilder.h |   7 +
 2 files changed, 97 insertions(+), 40 deletions(-)

diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp 
b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
index c5013ea5e3be4..e88b606f279cd 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
+++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
@@ -969,12 +969,82 @@ Status MinidumpFileBuilder::DumpDirectories() const {
   return error;
 }
 
-static uint64_t
-GetLargestRangeSize(const std::vector &ranges) {
-  uint64_t max_size = 0;
-  for (const auto &core_range : ranges)
-max_size = std::max(max_size, core_range.range.size());
-  return max_size;
+Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
+const lldb_private::CoreFileMemoryRange &range, uint64_t *bytes_read) {
+  Log *log = GetLog(LLDBLog::Object);
+  lldb::addr_t addr = range.range.start();
+  lldb::addr_t size = range.range.size();
+  // First we set the byte tally to 0, so if we do exit gracefully
+  // the caller doesn't think the random garbage on the stack is a
+  // success.
+  if (bytes_read)
+*bytes_read = 0;
+
+  uint64_t bytes_remaining = size;
+  uint64_t total_bytes_read = 0;
+  auto data_up = std::make_unique(
+  std::min(bytes_remaining, MAX_WRITE_CHUNK_SIZE), 0);
+  Status error;
+  while (bytes_remaining > 0) {
+// Get the next read chunk size as the minimum of the remaining bytes and
+// the write chunk max size.
+const size_t bytes_to_read =
+std::min(bytes_remaining, MAX_WRITE_CHUNK_SIZE);
+const size_t bytes_read_for_chunk =
+m_process_sp->ReadMemory(range.range.start() + total_bytes_read,
+ data_up->GetBytes(), bytes_to_read, error);
+if (error.Fail() || bytes_read_for_chunk == 0) {
+  LLDB_LOGF(log,
+"Failed to read memory region at: %" PRIx64
+". Bytes read: %zu, error: %s",
+addr, bytes_read_for_chunk, error.AsCString());
+  // If we've only read one byte we can just give up and return
+  if (total_bytes_read == 0)
+return Status();
+
+  // If we've read some bytes, we stop trying to read more and return
+  // this best effort attempt
+  bytes_remaining = 0;
+} else if (bytes_read_for_chunk != bytes_to_read) {
+  LLDB_LOGF(
+  log, "Memory region at: %" PRIx64 " failed to read %" PRIx64 " 
bytes",
+  addr, size);
+
+  // If we've read some bytes, we stop trying to read more and return
+  // this best effort attempt
+  bytes_remaining = 0;
+}
+
+// Write to the minidump file with the chunk potentially flushing to disk.
+// this is the only place we want to return a true error, so that we can
+// fail. If we get an error writing to disk we can't easily gaurauntee
+// that we won't corrupt the minidump.
+error = AddData(data_up->GetBytes(), bytes_read_for_chunk);
+if (error.Fail(

[Lldb-commits] [lldb] [lldb-dap] Add process picker command to VS Code extension (PR #128943)

2025-02-28 Thread Matthew Bastien via lldb-commits

https://github.com/matthewbastien updated 
https://github.com/llvm/llvm-project/pull/128943

>From b9083ea16c7b1dba70cc04acf78f5001f0fb86c6 Mon Sep 17 00:00:00 2001
From: Matthew Bastien 
Date: Wed, 26 Feb 2025 11:18:21 -0500
Subject: [PATCH 1/5] add a process picker for attaching by PID

---
 lldb/tools/lldb-dap/package.json  |  30 +-
 .../lldb-dap/src-ts/commands/pick-process.ts  |  37 +++
 lldb/tools/lldb-dap/src-ts/extension.ts   |   7 +-
 .../src-ts/process-tree/base-process-tree.ts  | 102 ++
 .../lldb-dap/src-ts/process-tree/index.ts |  36 +++
 .../platforms/darwin-process-tree.ts  |  16 +++
 .../platforms/linux-process-tree.ts   |  38 +++
 .../platforms/windows-process-tree.ts |  52 +
 8 files changed, 315 insertions(+), 3 deletions(-)
 create mode 100644 lldb/tools/lldb-dap/src-ts/commands/pick-process.ts
 create mode 100644 lldb/tools/lldb-dap/src-ts/process-tree/base-process-tree.ts
 create mode 100644 lldb/tools/lldb-dap/src-ts/process-tree/index.ts
 create mode 100644 
lldb/tools/lldb-dap/src-ts/process-tree/platforms/darwin-process-tree.ts
 create mode 100644 
lldb/tools/lldb-dap/src-ts/process-tree/platforms/linux-process-tree.ts
 create mode 100644 
lldb/tools/lldb-dap/src-ts/process-tree/platforms/windows-process-tree.ts

diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 31d808eda4c35..1bbdbf045dd1b 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -146,6 +146,9 @@
 "windows": {
   "program": "./bin/lldb-dap.exe"
 },
+"variables": {
+  "PickProcess": "lldb-dap.pickProcess"
+},
 "configurationAttributes": {
   "launch": {
 "required": [
@@ -517,6 +520,16 @@
   "cwd": "^\"\\${workspaceRoot}\""
 }
   },
+  {
+"label": "LLDB: Attach to Process",
+"description": "",
+"body": {
+  "type": "lldb-dap",
+  "request": "attach",
+  "name": "${1:Attach}",
+  "pid": "^\"\\${command:PickProcess}\""
+}
+  },
   {
 "label": "LLDB: Attach",
 "description": "",
@@ -541,6 +554,21 @@
   }
 ]
   }
-]
+],
+"commands": [
+  {
+"command": "lldb-dap.pickProcess",
+"title": "Pick Process",
+"category": "LLDB DAP"
+  }
+],
+"menus": {
+  "commandPalette": [
+{
+  "command": "lldb-dap.pickProcess",
+  "when": "false"
+}
+  ]
+}
   }
 }
diff --git a/lldb/tools/lldb-dap/src-ts/commands/pick-process.ts 
b/lldb/tools/lldb-dap/src-ts/commands/pick-process.ts
new file mode 100644
index 0..b83e749e7da7b
--- /dev/null
+++ b/lldb/tools/lldb-dap/src-ts/commands/pick-process.ts
@@ -0,0 +1,37 @@
+import * as path from "path";
+import * as vscode from "vscode";
+import { createProcessTree } from "../process-tree";
+
+interface ProcessQuickPick extends vscode.QuickPickItem {
+  processId: number;
+}
+
+/**
+ * Prompts the user to select a running process.
+ *
+ * @returns The pid of the process as a string or undefined if cancelled.
+ */
+export async function pickProcess(): Promise {
+  const processTree = createProcessTree();
+  const selectedProcess = await vscode.window.showQuickPick(
+processTree.listAllProcesses().then((processes): ProcessQuickPick[] => {
+  return processes
+.sort((a, b) => b.start - a.start) // Sort by start date in descending 
order
+.map((proc) => {
+  return {
+processId: proc.id,
+label: path.basename(proc.command),
+description: proc.id.toString(),
+detail: proc.arguments,
+  } satisfies ProcessQuickPick;
+});
+}),
+{
+  placeHolder: "Select a process to attach the debugger to",
+},
+  );
+  if (!selectedProcess) {
+return;
+  }
+  return selectedProcess.processId.toString();
+}
diff --git a/lldb/tools/lldb-dap/src-ts/extension.ts 
b/lldb/tools/lldb-dap/src-ts/extension.ts
index 71fd48298f8f5..3532a2143155b 100644
--- a/lldb/tools/lldb-dap/src-ts/extension.ts
+++ b/lldb/tools/lldb-dap/src-ts/extension.ts
@@ -1,7 +1,6 @@
-import * as path from "path";
-import * as util from "util";
 import * as vscode from "vscode";
 
+import { pickProcess } from "./commands/pick-process";
 import {
   LLDBDapDescriptorFactory,
   isExecutable,
@@ -38,6 +37,10 @@ export class LLDBDapExtension extends DisposableContext {
 }
   }),
 );
+
+this.pushSubscription(
+  vscode.commands.registerCommand("lldb-dap.pickProcess", pickProcess),
+);
   }
 }
 
diff --git a/lldb/tools/lldb-dap/src-ts/process-tree/base-process-tree.ts 
b/lldb/tools/lldb-dap/src-ts/process-tree/base-process-tree.ts
new file mode 100644
index 0..3c08f49035b35
--- /dev/null

[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread Jonas Devlieghere via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,22 @@
+#include "DAPLog.h"

JDevlieghere wrote:

Missing copyright header

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


[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread John Harrison via lldb-commits

https://github.com/ashgti updated 
https://github.com/llvm/llvm-project/pull/129294

>From 8d466e5c4b1b6913e788fd11d46689af8f0b8eec Mon Sep 17 00:00:00 2001
From: John Harrison 
Date: Thu, 27 Feb 2025 15:33:51 -0800
Subject: [PATCH 1/2] [lldb-dap] Updating the logging of lldb-dap to use
 existing LLDBLog.h helpers.

This only creates the basic types need to start using the LLDBLog.h helpers.
Today, logging is handling by a simple `std::ofstream *` for handling logging.
LLDBLog.h can help improve logging by adding new categories of logs and give us 
additional formatting support for log messages.
---
 lldb/tools/lldb-dap/CMakeLists.txt  |  1 +
 lldb/tools/lldb-dap/DAP.cpp | 62 
 lldb/tools/lldb-dap/DAP.h   | 11 ++---
 lldb/tools/lldb-dap/DAPLog.cpp  | 22 +
 lldb/tools/lldb-dap/DAPLog.h| 34 +
 lldb/tools/lldb-dap/EventHelper.cpp | 17 ---
 lldb/tools/lldb-dap/IOStream.cpp| 19 
 lldb/tools/lldb-dap/IOStream.h  |  7 ++-
 lldb/tools/lldb-dap/lldb-dap.cpp| 75 -
 9 files changed, 146 insertions(+), 102 deletions(-)
 create mode 100644 lldb/tools/lldb-dap/DAPLog.cpp
 create mode 100644 lldb/tools/lldb-dap/DAPLog.h

diff --git a/lldb/tools/lldb-dap/CMakeLists.txt 
b/lldb/tools/lldb-dap/CMakeLists.txt
index 8b3c520ec4360..d9f09f6d022ed 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -23,6 +23,7 @@ add_lldb_tool(lldb-dap
   Breakpoint.cpp
   BreakpointBase.cpp
   DAP.cpp
+  DAPLog.cpp
   EventHelper.cpp
   ExceptionBreakpoint.cpp
   FifoFiles.cpp
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 53c514b790f38..81f5205d4f6bd 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 
 #include "DAP.h"
+#include "DAPLog.h"
 #include "Handler/ResponseHandler.h"
 #include "JSONUtils.h"
 #include "LLDBUtils.h"
@@ -19,6 +20,7 @@
 #include "lldb/API/SBProcess.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/Utility/IOObject.h"
+#include "lldb/Utility/Log.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-enumerations.h"
@@ -50,6 +52,7 @@
 #endif
 
 using namespace lldb_dap;
+using namespace lldb_private;
 
 namespace {
 #ifdef _WIN32
@@ -61,13 +64,12 @@ const char DEV_NULL[] = "/dev/null";
 
 namespace lldb_dap {
 
-DAP::DAP(std::string name, llvm::StringRef path, std::ofstream *log,
- lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
+DAP::DAP(std::string name, llvm::StringRef path, lldb::IOObjectSP input,
+ lldb::IOObjectSP output, ReplMode repl_mode,
  std::vector pre_init_commands)
-: name(std::move(name)), debug_adapter_path(path), log(log),
-  input(std::move(input)), output(std::move(output)),
-  broadcaster("lldb-dap"), exception_breakpoints(),
-  pre_init_commands(std::move(pre_init_commands)),
+: name(std::move(name)), debug_adapter_path(path), input(std::move(input)),
+  output(std::move(output)), broadcaster("lldb-dap"),
+  exception_breakpoints(), pre_init_commands(std::move(pre_init_commands)),
   focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), 
is_attach(false),
   enable_auto_variable_summaries(false),
   enable_synthetic_child_debugging(false),
@@ -245,6 +247,8 @@ void DAP::SendJSON(const std::string &json_str) {
   output.write_full(llvm::utostr(json_str.size()));
   output.write_full("\r\n\r\n");
   output.write_full(json_str);
+
+  LLDB_LOG(GetLog(DAPLog::Transport), "{0} <-- {1}", name, json_str);
 }
 
 // Serialize the JSON value into a string and send the JSON packet to
@@ -256,15 +260,6 @@ void DAP::SendJSON(const llvm::json::Value &json) {
   static std::mutex mutex;
   std::lock_guard locker(mutex);
   SendJSON(json_str);
-
-  if (log) {
-auto now = std::chrono::duration(
-std::chrono::system_clock::now().time_since_epoch());
-*log << llvm::formatv("{0:f9} {1} <-- ", now.count(), name).str()
- << std::endl
- << "Content-Length: " << json_str.size() << "\r\n\r\n"
- << llvm::formatv("{0:2}", json).str() << std::endl;
-  }
 }
 
 // Read a JSON packet from the "in" stream.
@@ -273,28 +268,22 @@ std::string DAP::ReadJSON() {
   std::string json_str;
   int length;
 
-  if (!input.read_expected(log, "Content-Length: "))
+  if (!input.read_expected("Content-Length: "))
 return json_str;
 
-  if (!input.read_line(log, length_str))
+  if (!input.read_line(length_str))
 return json_str;
 
   if (!llvm::to_integer(length_str, length))
 return json_str;
 
-  if (!input.read_expected(log, "\r\n"))
+  if (!input.read_expected("\r\n"))
 return json_str;
 
-  if (!input.read_full(log, length, json_str))
+  if (!input.read_full(length, json_str))
 return json_str;
 
-  if (log) {
-auto now = std::chrono::duration(
- 

[Lldb-commits] [lldb] [lldb-dap] Adding server mode support to lldb-dap VSCode extension. (PR #128957)

2025-02-28 Thread John Harrison via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Add ability to inspect backing threads with `thread info` (PR #129275)

2025-02-28 Thread Felipe de Azevedo Piovezan via lldb-commits

https://github.com/felipepiovezan updated 
https://github.com/llvm/llvm-project/pull/129275

>From cd6661b5fb7a9a71352c79740d4b0c0601e61d43 Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan 
Date: Fri, 28 Feb 2025 09:11:11 -0800
Subject: [PATCH 1/4] [lldb] Add ability to inspect backing threads with
 `thread info`

When OS plugins are present, it can be helpful to query information
about the backing thread behind an OS thread, if it exists. There is no
mechanism to do so prior to this commit.

As a first step, this commit enhances `thread info` with a
`--backing-thread` flag, causing the command to use the backing thread
of the selected thread, if it exists.
---
 lldb/source/Commands/CommandObjectThread.cpp  |  8 +++
 lldb/source/Commands/Options.td   |  3 +++
 .../python_os_plugin/TestPythonOSPlugin.py| 24 +++
 3 files changed, 35 insertions(+)

diff --git a/lldb/source/Commands/CommandObjectThread.cpp 
b/lldb/source/Commands/CommandObjectThread.cpp
index cd3d2d89333f1..224c523e69c5c 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -1270,6 +1270,7 @@ class CommandObjectThreadInfo : public 
CommandObjectIterateOverThreads {
 void OptionParsingStarting(ExecutionContext *execution_context) override {
   m_json_thread = false;
   m_json_stopinfo = false;
+  m_backing_thread = false;
 }
 
 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
@@ -1286,6 +1287,10 @@ class CommandObjectThreadInfo : public 
CommandObjectIterateOverThreads {
 m_json_stopinfo = true;
 break;
 
+  case 'b':
+m_backing_thread = true;
+break;
+
   default:
 llvm_unreachable("Unimplemented option");
   }
@@ -1298,6 +1303,7 @@ class CommandObjectThreadInfo : public 
CommandObjectIterateOverThreads {
 
 bool m_json_thread;
 bool m_json_stopinfo;
+bool m_backing_thread;
   };
 
   CommandObjectThreadInfo(CommandInterpreter &interpreter)
@@ -1334,6 +1340,8 @@ class CommandObjectThreadInfo : public 
CommandObjectIterateOverThreads {
 }
 
 Thread *thread = thread_sp.get();
+if (m_options.m_backing_thread && thread->GetBackingThread())
+  thread = thread->GetBackingThread().get();
 
 Stream &strm = result.GetOutputStream();
 if (!thread->GetDescription(strm, eDescriptionLevelFull,
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 8831fed38435b..cc579d767eb06 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1108,6 +1108,9 @@ let Command = "thread info" in {
 " JSON format.">;
   def thread_info_stop_info : Option<"stop-info", "s">, Desc<"Display the "
 "extended stop info in JSON format.">;
+  def thread_info_backing_thread : Option<"backing-thread", "b">,
+Desc<"If this is an OS plugin thread, query the backing thread instead; 
has"
+" no effect otherwise.">;
 }
 
 let Command = "thread return" in {
diff --git 
a/lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py 
b/lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py
index fe78edd98f4d4..33e4f75adc0d0 100644
--- 
a/lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py
+++ 
b/lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py
@@ -131,6 +131,25 @@ def run_python_os_funcionality(self):
 "Make sure there is no thread 0x3 after we unload the 
python OS plug-in",
 )
 
+tid_regex = re.compile("tid = (0x[0-9a-fA-F]+)")
+def get_tid_from_thread_info_command(self, thread, use_backing_thread):
+interp = self.dbg.GetCommandInterpreter()
+result = lldb.SBCommandReturnObject()
+
+backing_thread_arg = ""
+if use_backing_thread:
+backing_thread_arg = "--backing-thread"
+
+interp.HandleCommand(
+"thread info {0} {1}".format(thread.GetIndexID(), 
backing_thread_arg),
+result,
+True,
+)
+self.assertTrue(result.Succeeded(), "failed to run thread info")
+match = self.tid_regex.search(result.GetOutput())
+self.assertNotEqual(match, None)
+return match.group(1)
+
 def run_python_os_step(self):
 """Test that the Python operating system plugin works correctly and 
allows single stepping of a virtual thread that is backed by a real thread"""
 
@@ -209,6 +228,11 @@ def run_python_os_step(self):
 # it to
 thread.StepOver()
 
+tid_os = self.get_tid_from_thread_info_command(thread, False)
+self.assertEqual(tid_os, "0x1")
+tid_real = self.get_tid_from_thread_info_command(thread, True)
+self.assertNotEqual(tid_os, tid_real)
+
 frame = thread.GetFrameAtIndex(0)
 self.assertTrue(
 frame.IsValid(), "Make sure we get a frame from thread 0x1"

>Fro

[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread John Harrison via lldb-commits

ashgti wrote:

Also, for reference, this does change the output format.

```
$ cat 
lldb-test-build.noindex/tools/lldb-dap/launch/TestDAP_launch.test_termination/dap.txt
1740771506.578514099 stdin/stdout --> 
{"command":"disconnect","type":"request","arguments":{},"seq":1}
1740771506.578675032 stdin/stdout <-- 
{"event":"terminated","seq":0,"type":"event"}
1740771506.579591990 stdin/stdout <-- 
{"command":"disconnect","request_seq":1,"seq":0,"success":true,"type":"response"}
```

Is an example of what things look like with this change.

Before this was formatted like:

```
  (<--|-->)
Content-Length: 

{...}
```

So its more compact now since we don't include the full protocol encoding 
header ("Content-Length: {size}\r\n\r\n").

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


[Lldb-commits] [lldb] [lldb-dap] Add process picker command to VS Code extension (PR #128943)

2025-02-28 Thread Matthew Bastien via lldb-commits

https://github.com/matthewbastien updated 
https://github.com/llvm/llvm-project/pull/128943

>From b9083ea16c7b1dba70cc04acf78f5001f0fb86c6 Mon Sep 17 00:00:00 2001
From: Matthew Bastien 
Date: Wed, 26 Feb 2025 11:18:21 -0500
Subject: [PATCH 1/5] add a process picker for attaching by PID

---
 lldb/tools/lldb-dap/package.json  |  30 +-
 .../lldb-dap/src-ts/commands/pick-process.ts  |  37 +++
 lldb/tools/lldb-dap/src-ts/extension.ts   |   7 +-
 .../src-ts/process-tree/base-process-tree.ts  | 102 ++
 .../lldb-dap/src-ts/process-tree/index.ts |  36 +++
 .../platforms/darwin-process-tree.ts  |  16 +++
 .../platforms/linux-process-tree.ts   |  38 +++
 .../platforms/windows-process-tree.ts |  52 +
 8 files changed, 315 insertions(+), 3 deletions(-)
 create mode 100644 lldb/tools/lldb-dap/src-ts/commands/pick-process.ts
 create mode 100644 lldb/tools/lldb-dap/src-ts/process-tree/base-process-tree.ts
 create mode 100644 lldb/tools/lldb-dap/src-ts/process-tree/index.ts
 create mode 100644 
lldb/tools/lldb-dap/src-ts/process-tree/platforms/darwin-process-tree.ts
 create mode 100644 
lldb/tools/lldb-dap/src-ts/process-tree/platforms/linux-process-tree.ts
 create mode 100644 
lldb/tools/lldb-dap/src-ts/process-tree/platforms/windows-process-tree.ts

diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 31d808eda4c35..1bbdbf045dd1b 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -146,6 +146,9 @@
 "windows": {
   "program": "./bin/lldb-dap.exe"
 },
+"variables": {
+  "PickProcess": "lldb-dap.pickProcess"
+},
 "configurationAttributes": {
   "launch": {
 "required": [
@@ -517,6 +520,16 @@
   "cwd": "^\"\\${workspaceRoot}\""
 }
   },
+  {
+"label": "LLDB: Attach to Process",
+"description": "",
+"body": {
+  "type": "lldb-dap",
+  "request": "attach",
+  "name": "${1:Attach}",
+  "pid": "^\"\\${command:PickProcess}\""
+}
+  },
   {
 "label": "LLDB: Attach",
 "description": "",
@@ -541,6 +554,21 @@
   }
 ]
   }
-]
+],
+"commands": [
+  {
+"command": "lldb-dap.pickProcess",
+"title": "Pick Process",
+"category": "LLDB DAP"
+  }
+],
+"menus": {
+  "commandPalette": [
+{
+  "command": "lldb-dap.pickProcess",
+  "when": "false"
+}
+  ]
+}
   }
 }
diff --git a/lldb/tools/lldb-dap/src-ts/commands/pick-process.ts 
b/lldb/tools/lldb-dap/src-ts/commands/pick-process.ts
new file mode 100644
index 0..b83e749e7da7b
--- /dev/null
+++ b/lldb/tools/lldb-dap/src-ts/commands/pick-process.ts
@@ -0,0 +1,37 @@
+import * as path from "path";
+import * as vscode from "vscode";
+import { createProcessTree } from "../process-tree";
+
+interface ProcessQuickPick extends vscode.QuickPickItem {
+  processId: number;
+}
+
+/**
+ * Prompts the user to select a running process.
+ *
+ * @returns The pid of the process as a string or undefined if cancelled.
+ */
+export async function pickProcess(): Promise {
+  const processTree = createProcessTree();
+  const selectedProcess = await vscode.window.showQuickPick(
+processTree.listAllProcesses().then((processes): ProcessQuickPick[] => {
+  return processes
+.sort((a, b) => b.start - a.start) // Sort by start date in descending 
order
+.map((proc) => {
+  return {
+processId: proc.id,
+label: path.basename(proc.command),
+description: proc.id.toString(),
+detail: proc.arguments,
+  } satisfies ProcessQuickPick;
+});
+}),
+{
+  placeHolder: "Select a process to attach the debugger to",
+},
+  );
+  if (!selectedProcess) {
+return;
+  }
+  return selectedProcess.processId.toString();
+}
diff --git a/lldb/tools/lldb-dap/src-ts/extension.ts 
b/lldb/tools/lldb-dap/src-ts/extension.ts
index 71fd48298f8f5..3532a2143155b 100644
--- a/lldb/tools/lldb-dap/src-ts/extension.ts
+++ b/lldb/tools/lldb-dap/src-ts/extension.ts
@@ -1,7 +1,6 @@
-import * as path from "path";
-import * as util from "util";
 import * as vscode from "vscode";
 
+import { pickProcess } from "./commands/pick-process";
 import {
   LLDBDapDescriptorFactory,
   isExecutable,
@@ -38,6 +37,10 @@ export class LLDBDapExtension extends DisposableContext {
 }
   }),
 );
+
+this.pushSubscription(
+  vscode.commands.registerCommand("lldb-dap.pickProcess", pickProcess),
+);
   }
 }
 
diff --git a/lldb/tools/lldb-dap/src-ts/process-tree/base-process-tree.ts 
b/lldb/tools/lldb-dap/src-ts/process-tree/base-process-tree.ts
new file mode 100644
index 0..3c08f49035b35
--- /dev/null

[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread John Harrison via lldb-commits

https://github.com/ashgti created 
https://github.com/llvm/llvm-project/pull/129294

Today, logging is handling by a simple `std::ofstream *` for handling logging. 

LLDBLog.h can help improve logging by adding new categories of logs and give us 
additional formatting support for log messages. We link against the libHost, 
which includes lldbUtility.

>From 71f82c81f04207f46713e9bf2c0c6bc84e3c5216 Mon Sep 17 00:00:00 2001
From: John Harrison 
Date: Thu, 27 Feb 2025 15:33:51 -0800
Subject: [PATCH] [lldb-dap] Updating the logging of lldb-dap to use existing
 LLDBLog.h helpers.

This only creates the basic types need to start using the LLDBLog.h helpers.
Today, logging is handling by a simple `std::ofstream *` for handling logging.
LLDBLog.h can help improve logging by adding new categories of logs and give us 
additional formatting support for log messages.
---
 lldb/tools/lldb-dap/CMakeLists.txt  |  1 +
 lldb/tools/lldb-dap/DAP.cpp | 62 
 lldb/tools/lldb-dap/DAP.h   | 11 ++---
 lldb/tools/lldb-dap/DAPLog.cpp  | 22 +
 lldb/tools/lldb-dap/DAPLog.h| 34 +
 lldb/tools/lldb-dap/EventHelper.cpp | 17 ---
 lldb/tools/lldb-dap/IOStream.cpp| 19 
 lldb/tools/lldb-dap/IOStream.h  |  7 ++-
 lldb/tools/lldb-dap/lldb-dap.cpp| 75 -
 9 files changed, 146 insertions(+), 102 deletions(-)
 create mode 100644 lldb/tools/lldb-dap/DAPLog.cpp
 create mode 100644 lldb/tools/lldb-dap/DAPLog.h

diff --git a/lldb/tools/lldb-dap/CMakeLists.txt 
b/lldb/tools/lldb-dap/CMakeLists.txt
index 8b3c520ec4360..d9f09f6d022ed 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -23,6 +23,7 @@ add_lldb_tool(lldb-dap
   Breakpoint.cpp
   BreakpointBase.cpp
   DAP.cpp
+  DAPLog.cpp
   EventHelper.cpp
   ExceptionBreakpoint.cpp
   FifoFiles.cpp
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 53c514b790f38..81f5205d4f6bd 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 
 #include "DAP.h"
+#include "DAPLog.h"
 #include "Handler/ResponseHandler.h"
 #include "JSONUtils.h"
 #include "LLDBUtils.h"
@@ -19,6 +20,7 @@
 #include "lldb/API/SBProcess.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/Utility/IOObject.h"
+#include "lldb/Utility/Log.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-enumerations.h"
@@ -50,6 +52,7 @@
 #endif
 
 using namespace lldb_dap;
+using namespace lldb_private;
 
 namespace {
 #ifdef _WIN32
@@ -61,13 +64,12 @@ const char DEV_NULL[] = "/dev/null";
 
 namespace lldb_dap {
 
-DAP::DAP(std::string name, llvm::StringRef path, std::ofstream *log,
- lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
+DAP::DAP(std::string name, llvm::StringRef path, lldb::IOObjectSP input,
+ lldb::IOObjectSP output, ReplMode repl_mode,
  std::vector pre_init_commands)
-: name(std::move(name)), debug_adapter_path(path), log(log),
-  input(std::move(input)), output(std::move(output)),
-  broadcaster("lldb-dap"), exception_breakpoints(),
-  pre_init_commands(std::move(pre_init_commands)),
+: name(std::move(name)), debug_adapter_path(path), input(std::move(input)),
+  output(std::move(output)), broadcaster("lldb-dap"),
+  exception_breakpoints(), pre_init_commands(std::move(pre_init_commands)),
   focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), 
is_attach(false),
   enable_auto_variable_summaries(false),
   enable_synthetic_child_debugging(false),
@@ -245,6 +247,8 @@ void DAP::SendJSON(const std::string &json_str) {
   output.write_full(llvm::utostr(json_str.size()));
   output.write_full("\r\n\r\n");
   output.write_full(json_str);
+
+  LLDB_LOG(GetLog(DAPLog::Transport), "{0} <-- {1}", name, json_str);
 }
 
 // Serialize the JSON value into a string and send the JSON packet to
@@ -256,15 +260,6 @@ void DAP::SendJSON(const llvm::json::Value &json) {
   static std::mutex mutex;
   std::lock_guard locker(mutex);
   SendJSON(json_str);
-
-  if (log) {
-auto now = std::chrono::duration(
-std::chrono::system_clock::now().time_since_epoch());
-*log << llvm::formatv("{0:f9} {1} <-- ", now.count(), name).str()
- << std::endl
- << "Content-Length: " << json_str.size() << "\r\n\r\n"
- << llvm::formatv("{0:2}", json).str() << std::endl;
-  }
 }
 
 // Read a JSON packet from the "in" stream.
@@ -273,28 +268,22 @@ std::string DAP::ReadJSON() {
   std::string json_str;
   int length;
 
-  if (!input.read_expected(log, "Content-Length: "))
+  if (!input.read_expected("Content-Length: "))
 return json_str;
 
-  if (!input.read_line(log, length_str))
+  if (!input.read_line(length_str))
 return json_str;
 
   if (!llvm::to_integer(length_str, length))
 return json_str;
 
-  if (!

[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread John Harrison via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread John Harrison via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Add terminfo dependency for ncurses support (PR #126810)

2025-02-28 Thread Jordan R AW via lldb-commits

ajordanr-google wrote:

We haven't had any issues since on our end. I'll check with Fuchsia again to be 
sure, then will try to backport.

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


[Lldb-commits] [lldb] [lldb-dap] Add process picker command to VS Code extension (PR #128943)

2025-02-28 Thread Matthew Bastien via lldb-commits


@@ -0,0 +1,102 @@
+import { ChildProcessWithoutNullStreams } from "child_process";
+import { Process, ProcessTree } from ".";
+import { Transform } from "stream";
+
+/** Parses process information from a given line of process output. */
+export type ProcessTreeParser = (line: string) => Process | undefined;
+
+/**
+ * Implements common behavior between the different {@link ProcessTree} 
implementations.
+ */
+export abstract class BaseProcessTree implements ProcessTree {
+  /**
+   * Spawn the process responsible for collecting all processes on the system.
+   */
+  protected abstract spawnProcess(): ChildProcessWithoutNullStreams;

matthewbastien wrote:

So it does! Fixed. Thanks!

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


[Lldb-commits] [lldb] Control the "step out through thunk" logic explicitly when pushing thread plans (PR #129301)

2025-02-28 Thread via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Add ability to inspect backing threads with `thread info` (PR #129275)

2025-02-28 Thread Felipe de Azevedo Piovezan via lldb-commits

https://github.com/felipepiovezan updated 
https://github.com/llvm/llvm-project/pull/129275

>From cd6661b5fb7a9a71352c79740d4b0c0601e61d43 Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan 
Date: Fri, 28 Feb 2025 09:11:11 -0800
Subject: [PATCH 1/3] [lldb] Add ability to inspect backing threads with
 `thread info`

When OS plugins are present, it can be helpful to query information
about the backing thread behind an OS thread, if it exists. There is no
mechanism to do so prior to this commit.

As a first step, this commit enhances `thread info` with a
`--backing-thread` flag, causing the command to use the backing thread
of the selected thread, if it exists.
---
 lldb/source/Commands/CommandObjectThread.cpp  |  8 +++
 lldb/source/Commands/Options.td   |  3 +++
 .../python_os_plugin/TestPythonOSPlugin.py| 24 +++
 3 files changed, 35 insertions(+)

diff --git a/lldb/source/Commands/CommandObjectThread.cpp 
b/lldb/source/Commands/CommandObjectThread.cpp
index cd3d2d89333f1..224c523e69c5c 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -1270,6 +1270,7 @@ class CommandObjectThreadInfo : public 
CommandObjectIterateOverThreads {
 void OptionParsingStarting(ExecutionContext *execution_context) override {
   m_json_thread = false;
   m_json_stopinfo = false;
+  m_backing_thread = false;
 }
 
 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
@@ -1286,6 +1287,10 @@ class CommandObjectThreadInfo : public 
CommandObjectIterateOverThreads {
 m_json_stopinfo = true;
 break;
 
+  case 'b':
+m_backing_thread = true;
+break;
+
   default:
 llvm_unreachable("Unimplemented option");
   }
@@ -1298,6 +1303,7 @@ class CommandObjectThreadInfo : public 
CommandObjectIterateOverThreads {
 
 bool m_json_thread;
 bool m_json_stopinfo;
+bool m_backing_thread;
   };
 
   CommandObjectThreadInfo(CommandInterpreter &interpreter)
@@ -1334,6 +1340,8 @@ class CommandObjectThreadInfo : public 
CommandObjectIterateOverThreads {
 }
 
 Thread *thread = thread_sp.get();
+if (m_options.m_backing_thread && thread->GetBackingThread())
+  thread = thread->GetBackingThread().get();
 
 Stream &strm = result.GetOutputStream();
 if (!thread->GetDescription(strm, eDescriptionLevelFull,
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 8831fed38435b..cc579d767eb06 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1108,6 +1108,9 @@ let Command = "thread info" in {
 " JSON format.">;
   def thread_info_stop_info : Option<"stop-info", "s">, Desc<"Display the "
 "extended stop info in JSON format.">;
+  def thread_info_backing_thread : Option<"backing-thread", "b">,
+Desc<"If this is an OS plugin thread, query the backing thread instead; 
has"
+" no effect otherwise.">;
 }
 
 let Command = "thread return" in {
diff --git 
a/lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py 
b/lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py
index fe78edd98f4d4..33e4f75adc0d0 100644
--- 
a/lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py
+++ 
b/lldb/test/API/functionalities/plugins/python_os_plugin/TestPythonOSPlugin.py
@@ -131,6 +131,25 @@ def run_python_os_funcionality(self):
 "Make sure there is no thread 0x3 after we unload the 
python OS plug-in",
 )
 
+tid_regex = re.compile("tid = (0x[0-9a-fA-F]+)")
+def get_tid_from_thread_info_command(self, thread, use_backing_thread):
+interp = self.dbg.GetCommandInterpreter()
+result = lldb.SBCommandReturnObject()
+
+backing_thread_arg = ""
+if use_backing_thread:
+backing_thread_arg = "--backing-thread"
+
+interp.HandleCommand(
+"thread info {0} {1}".format(thread.GetIndexID(), 
backing_thread_arg),
+result,
+True,
+)
+self.assertTrue(result.Succeeded(), "failed to run thread info")
+match = self.tid_regex.search(result.GetOutput())
+self.assertNotEqual(match, None)
+return match.group(1)
+
 def run_python_os_step(self):
 """Test that the Python operating system plugin works correctly and 
allows single stepping of a virtual thread that is backed by a real thread"""
 
@@ -209,6 +228,11 @@ def run_python_os_step(self):
 # it to
 thread.StepOver()
 
+tid_os = self.get_tid_from_thread_info_command(thread, False)
+self.assertEqual(tid_os, "0x1")
+tid_real = self.get_tid_from_thread_info_command(thread, True)
+self.assertNotEqual(tid_os, tid_real)
+
 frame = thread.GetFrameAtIndex(0)
 self.assertTrue(
 frame.IsValid(), "Make sure we get a frame from thread 0x1"

>Fro

[Lldb-commits] [lldb] Control the "step out through thunk" logic explicitly when pushing thread plans (PR #129301)

2025-02-28 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: None (jimingham)


Changes

Jonas recently added a trampoline handling strategy for simple language thunks 
that does: "step through language thunks stepping in one level deep and 
stopping if you hit user code".  That was actually pulled over from the swift 
implementation.  However, this strategy and the strategy we have to "step out 
past language thunks" when stepping out come into conflict if the thunk you are 
stepping through calls some other function before dispatching to the intended 
method.  When you step out of the called function back into the thunk, should 
you keep stepping out past the thunk or not?

In most cases, you want to step out past the thunk, but in this particular case 
you don't.

This patch adds a way to inform the thread plan (or really it's ShouldStopHere 
behavior) of which behavior it should have, and passes the don't step through 
thunks to the step through plan it uses to step through thunks.

I didn't add a test for this because I couldn't find a C++ thunk that calls 
another function before getting to the target function.  I asked the clang 
folks here if they could think of a case where clang would do this, and they 
couldn't.  If anyone can think of such a construct, it will be easy to write 
the step through test for it...

This does happen in swift, however, so when I cherry-pick this to the swift 
fork I'll test it there.

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


3 Files Affected:

- (modified) lldb/include/lldb/Target/ThreadPlanShouldStopHere.h (+2-1) 
- (modified) lldb/source/Target/ThreadPlanShouldStopHere.cpp (+11-4) 
- (modified) lldb/source/Target/ThreadPlanStepInRange.cpp (+2-1) 


``diff
diff --git a/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h 
b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
index 54b30291c3995..d0094c90b91a5 100644
--- a/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
+++ b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
@@ -59,7 +59,8 @@ class ThreadPlanShouldStopHere {
 eNone = 0,
 eAvoidInlines = (1 << 0),
 eStepInAvoidNoDebug = (1 << 1),
-eStepOutAvoidNoDebug = (1 << 2)
+eStepOutAvoidNoDebug = (1 << 2),
+eStepOutPastThunks = (1 << 3)
   };
 
   // Constructors and Destructors
diff --git a/lldb/source/Target/ThreadPlanShouldStopHere.cpp 
b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
index fa6bc08a9914d..be6bd981c72bc 100644
--- a/lldb/source/Target/ThreadPlanShouldStopHere.cpp
+++ b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
@@ -8,6 +8,7 @@
 
 #include "lldb/Target/ThreadPlanShouldStopHere.h"
 #include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/Language.h"
 #include "lldb/Target/LanguageRuntime.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Thread.h"
@@ -83,7 +84,11 @@ bool ThreadPlanShouldStopHere::DefaultShouldStopHereCallback(
 if (Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol) 
{
   ProcessSP process_sp(current_plan->GetThread().GetProcess());
   for (auto *runtime : process_sp->GetLanguageRuntimes()) {
-if (runtime->IsSymbolARuntimeThunk(*symbol)) {
+if (runtime->IsSymbolARuntimeThunk(*symbol)
+ && flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
+ LLDB_LOGF(log, "Stepping out past a language thunk %s for: %s",
+   frame->GetFunctionName(),
+   
Language::GetNameForLanguageType(runtime->GetLanguageType()));
   should_stop_here = false;
   break;
 }
@@ -131,9 +136,11 @@ ThreadPlanSP 
ThreadPlanShouldStopHere::DefaultStepFromHereCallback(
   // because it's marked line 0.
   bool is_thunk = false;
   for (auto *runtime : process_sp->GetLanguageRuntimes()) {
-if (runtime->IsSymbolARuntimeThunk(*sc.symbol)) {
-  LLDB_LOGF(log, "In runtime thunk %s - stepping out.",
-sc.symbol->GetName().GetCString());
+if (runtime->IsSymbolARuntimeThunk(*sc.symbol)
+ && flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
+  LLDB_LOGF(log, "Stepping out past a language thunk %s for: %s",
+   frame->GetFunctionName(),
+   
Language::GetNameForLanguageType(runtime->GetLanguageType()));
   is_thunk = true;
   break;
 }
diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp 
b/lldb/source/Target/ThreadPlanStepInRange.cpp
index 109d1b6b3435b..3affeae1ee388 100644
--- a/lldb/source/Target/ThreadPlanStepInRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepInRange.cpp
@@ -27,7 +27,8 @@ using namespace lldb;
 using namespace lldb_private;
 
 uint32_t ThreadPlanStepInRange::s_default_flag_values =
-ThreadPlanShouldStopHere::eStepInAvoidNoDebug;
+ThreadPlanShouldStopHere::eStepInAvoidNoDebug | 
+ThreadPlanShouldStopHere::eStepOutPastThunks;
 
 // ThreadPlanStepInRange: Step through a stack range, either steppi

[Lldb-commits] [lldb] [lldb] Add ability to inspect backing threads with `thread info` (PR #129275)

2025-02-28 Thread Felipe de Azevedo Piovezan via lldb-commits

felipepiovezan wrote:

Linux bots seem to print the TID using decimal numbers, so I updated the regex.

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


[Lldb-commits] [lldb] [lldb-dap] Add process picker command to VS Code extension (PR #128943)

2025-02-28 Thread John Harrison via lldb-commits


@@ -0,0 +1,102 @@
+import { ChildProcessWithoutNullStreams } from "child_process";
+import { Process, ProcessTree } from ".";
+import { Transform } from "stream";
+
+/** Parses process information from a given line of process output. */
+export type ProcessTreeParser = (line: string) => Process | undefined;
+
+/**
+ * Implements common behavior between the different {@link ProcessTree} 
implementations.
+ */
+export abstract class BaseProcessTree implements ProcessTree {
+  /**
+   * Spawn the process responsible for collecting all processes on the system.
+   */
+  protected abstract spawnProcess(): ChildProcessWithoutNullStreams;

ashgti wrote:

You can use `execFile`, which takes the program and arguments separately

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


[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread John Harrison via lldb-commits

https://github.com/ashgti updated 
https://github.com/llvm/llvm-project/pull/129294

>From 8d466e5c4b1b6913e788fd11d46689af8f0b8eec Mon Sep 17 00:00:00 2001
From: John Harrison 
Date: Thu, 27 Feb 2025 15:33:51 -0800
Subject: [PATCH 1/3] [lldb-dap] Updating the logging of lldb-dap to use
 existing LLDBLog.h helpers.

This only creates the basic types need to start using the LLDBLog.h helpers.
Today, logging is handling by a simple `std::ofstream *` for handling logging.
LLDBLog.h can help improve logging by adding new categories of logs and give us 
additional formatting support for log messages.
---
 lldb/tools/lldb-dap/CMakeLists.txt  |  1 +
 lldb/tools/lldb-dap/DAP.cpp | 62 
 lldb/tools/lldb-dap/DAP.h   | 11 ++---
 lldb/tools/lldb-dap/DAPLog.cpp  | 22 +
 lldb/tools/lldb-dap/DAPLog.h| 34 +
 lldb/tools/lldb-dap/EventHelper.cpp | 17 ---
 lldb/tools/lldb-dap/IOStream.cpp| 19 
 lldb/tools/lldb-dap/IOStream.h  |  7 ++-
 lldb/tools/lldb-dap/lldb-dap.cpp| 75 -
 9 files changed, 146 insertions(+), 102 deletions(-)
 create mode 100644 lldb/tools/lldb-dap/DAPLog.cpp
 create mode 100644 lldb/tools/lldb-dap/DAPLog.h

diff --git a/lldb/tools/lldb-dap/CMakeLists.txt 
b/lldb/tools/lldb-dap/CMakeLists.txt
index 8b3c520ec4360..d9f09f6d022ed 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -23,6 +23,7 @@ add_lldb_tool(lldb-dap
   Breakpoint.cpp
   BreakpointBase.cpp
   DAP.cpp
+  DAPLog.cpp
   EventHelper.cpp
   ExceptionBreakpoint.cpp
   FifoFiles.cpp
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 53c514b790f38..81f5205d4f6bd 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 
 #include "DAP.h"
+#include "DAPLog.h"
 #include "Handler/ResponseHandler.h"
 #include "JSONUtils.h"
 #include "LLDBUtils.h"
@@ -19,6 +20,7 @@
 #include "lldb/API/SBProcess.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/Utility/IOObject.h"
+#include "lldb/Utility/Log.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-enumerations.h"
@@ -50,6 +52,7 @@
 #endif
 
 using namespace lldb_dap;
+using namespace lldb_private;
 
 namespace {
 #ifdef _WIN32
@@ -61,13 +64,12 @@ const char DEV_NULL[] = "/dev/null";
 
 namespace lldb_dap {
 
-DAP::DAP(std::string name, llvm::StringRef path, std::ofstream *log,
- lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
+DAP::DAP(std::string name, llvm::StringRef path, lldb::IOObjectSP input,
+ lldb::IOObjectSP output, ReplMode repl_mode,
  std::vector pre_init_commands)
-: name(std::move(name)), debug_adapter_path(path), log(log),
-  input(std::move(input)), output(std::move(output)),
-  broadcaster("lldb-dap"), exception_breakpoints(),
-  pre_init_commands(std::move(pre_init_commands)),
+: name(std::move(name)), debug_adapter_path(path), input(std::move(input)),
+  output(std::move(output)), broadcaster("lldb-dap"),
+  exception_breakpoints(), pre_init_commands(std::move(pre_init_commands)),
   focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), 
is_attach(false),
   enable_auto_variable_summaries(false),
   enable_synthetic_child_debugging(false),
@@ -245,6 +247,8 @@ void DAP::SendJSON(const std::string &json_str) {
   output.write_full(llvm::utostr(json_str.size()));
   output.write_full("\r\n\r\n");
   output.write_full(json_str);
+
+  LLDB_LOG(GetLog(DAPLog::Transport), "{0} <-- {1}", name, json_str);
 }
 
 // Serialize the JSON value into a string and send the JSON packet to
@@ -256,15 +260,6 @@ void DAP::SendJSON(const llvm::json::Value &json) {
   static std::mutex mutex;
   std::lock_guard locker(mutex);
   SendJSON(json_str);
-
-  if (log) {
-auto now = std::chrono::duration(
-std::chrono::system_clock::now().time_since_epoch());
-*log << llvm::formatv("{0:f9} {1} <-- ", now.count(), name).str()
- << std::endl
- << "Content-Length: " << json_str.size() << "\r\n\r\n"
- << llvm::formatv("{0:2}", json).str() << std::endl;
-  }
 }
 
 // Read a JSON packet from the "in" stream.
@@ -273,28 +268,22 @@ std::string DAP::ReadJSON() {
   std::string json_str;
   int length;
 
-  if (!input.read_expected(log, "Content-Length: "))
+  if (!input.read_expected("Content-Length: "))
 return json_str;
 
-  if (!input.read_line(log, length_str))
+  if (!input.read_line(length_str))
 return json_str;
 
   if (!llvm::to_integer(length_str, length))
 return json_str;
 
-  if (!input.read_expected(log, "\r\n"))
+  if (!input.read_expected("\r\n"))
 return json_str;
 
-  if (!input.read_full(log, length, json_str))
+  if (!input.read_full(length, json_str))
 return json_str;
 
-  if (log) {
-auto now = std::chrono::duration(
- 

[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread John Harrison via lldb-commits


@@ -0,0 +1,34 @@
+//===-- DAPLog.h *- C++ 
-*-===//

ashgti wrote:

Done.

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


[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread John Harrison via lldb-commits


@@ -0,0 +1,22 @@
+#include "DAPLog.h"

ashgti wrote:

Added

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


[Lldb-commits] [lldb] Control the "step out through thunk" logic explicitly when pushing thread plans (PR #129301)

2025-02-28 Thread via lldb-commits

https://github.com/jimingham created 
https://github.com/llvm/llvm-project/pull/129301

Jonas recently added a trampoline handling strategy for simple language thunks 
that does: "step through language thunks stepping in one level deep and 
stopping if you hit user code".  That was actually pulled over from the swift 
implementation.  However, this strategy and the strategy we have to "step out 
past language thunks" when stepping out come into conflict if the thunk you are 
stepping through calls some other function before dispatching to the intended 
method.  When you step out of the called function back into the thunk, should 
you keep stepping out past the thunk or not?

In most cases, you want to step out past the thunk, but in this particular case 
you don't.

This patch adds a way to inform the thread plan (or really it's ShouldStopHere 
behavior) of which behavior it should have, and passes the don't step through 
thunks to the step through plan it uses to step through thunks.

I didn't add a test for this because I couldn't find a C++ thunk that calls 
another function before getting to the target function.  I asked the clang 
folks here if they could think of a case where clang would do this, and they 
couldn't.  If anyone can think of such a construct, it will be easy to write 
the step through test for it...

This does happen in swift, however, so when I cherry-pick this to the swift 
fork I'll test it there.

>From a26c5596ac599f1b51cffebd658f3823388e Mon Sep 17 00:00:00 2001
From: Jim Ingham 
Date: Fri, 28 Feb 2025 11:45:51 -0800
Subject: [PATCH] Control the "step out through thunk" logic explicitly when
 pushing thread plans.

That allow the thread plan that is trying to step through a thunk to its target
to step out of a function it has stepped into without also stepping out past
the thunk we were trying to step through.
---
 .../lldb/Target/ThreadPlanShouldStopHere.h|  3 ++-
 lldb/source/Target/ThreadPlanShouldStopHere.cpp   | 15 +++
 lldb/source/Target/ThreadPlanStepInRange.cpp  |  3 ++-
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h 
b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
index 54b30291c3995..d0094c90b91a5 100644
--- a/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
+++ b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
@@ -59,7 +59,8 @@ class ThreadPlanShouldStopHere {
 eNone = 0,
 eAvoidInlines = (1 << 0),
 eStepInAvoidNoDebug = (1 << 1),
-eStepOutAvoidNoDebug = (1 << 2)
+eStepOutAvoidNoDebug = (1 << 2),
+eStepOutPastThunks = (1 << 3)
   };
 
   // Constructors and Destructors
diff --git a/lldb/source/Target/ThreadPlanShouldStopHere.cpp 
b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
index fa6bc08a9914d..be6bd981c72bc 100644
--- a/lldb/source/Target/ThreadPlanShouldStopHere.cpp
+++ b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
@@ -8,6 +8,7 @@
 
 #include "lldb/Target/ThreadPlanShouldStopHere.h"
 #include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/Language.h"
 #include "lldb/Target/LanguageRuntime.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Thread.h"
@@ -83,7 +84,11 @@ bool ThreadPlanShouldStopHere::DefaultShouldStopHereCallback(
 if (Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol) 
{
   ProcessSP process_sp(current_plan->GetThread().GetProcess());
   for (auto *runtime : process_sp->GetLanguageRuntimes()) {
-if (runtime->IsSymbolARuntimeThunk(*symbol)) {
+if (runtime->IsSymbolARuntimeThunk(*symbol)
+ && flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
+ LLDB_LOGF(log, "Stepping out past a language thunk %s for: %s",
+   frame->GetFunctionName(),
+   
Language::GetNameForLanguageType(runtime->GetLanguageType()));
   should_stop_here = false;
   break;
 }
@@ -131,9 +136,11 @@ ThreadPlanSP 
ThreadPlanShouldStopHere::DefaultStepFromHereCallback(
   // because it's marked line 0.
   bool is_thunk = false;
   for (auto *runtime : process_sp->GetLanguageRuntimes()) {
-if (runtime->IsSymbolARuntimeThunk(*sc.symbol)) {
-  LLDB_LOGF(log, "In runtime thunk %s - stepping out.",
-sc.symbol->GetName().GetCString());
+if (runtime->IsSymbolARuntimeThunk(*sc.symbol)
+ && flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
+  LLDB_LOGF(log, "Stepping out past a language thunk %s for: %s",
+   frame->GetFunctionName(),
+   
Language::GetNameForLanguageType(runtime->GetLanguageType()));
   is_thunk = true;
   break;
 }
diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp 
b/lldb/source/Target/ThreadPlanStepInRange.cpp
index 109d1b6b3435b..3affeae1ee388 100644
--- a/lldb/source/Target/ThreadPlanStepInRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepInRa

[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread Jonas Devlieghere via lldb-commits

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

LGMT modulo copyright header & the patch file removed. 

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


[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,34 @@
+//===-- DAPLog.h *- C++ 
-*-===//

JDevlieghere wrote:

```suggestion
//===-- DAPLog.h --===//
```

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


[Lldb-commits] [lldb] [LLDB][Minidump]Update MinidumpFileBuilder to read and write in chunks (PR #129307)

2025-02-28 Thread Jacob Lalonde via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: John Harrison (ashgti)


Changes

Today, logging is handling by a simple `std::ofstream *` for handling logging.

LLDBLog.h can help improve logging by adding new categories of logs and give us 
additional formatting support for log messages. We link against the libHost, 
which includes lldbUtility. This also simplifies logging by not requiring the 
`std::ofstream *` pointer being passed to every function that includes logging.

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


9 Files Affected:

- (modified) lldb/tools/lldb-dap/CMakeLists.txt (+1) 
- (modified) lldb/tools/lldb-dap/DAP.cpp (+20-42) 
- (modified) lldb/tools/lldb-dap/DAP.h (+5-6) 
- (added) lldb/tools/lldb-dap/DAPLog.cpp (+22) 
- (added) lldb/tools/lldb-dap/DAPLog.h (+34) 
- (modified) lldb/tools/lldb-dap/EventHelper.cpp (+10-7) 
- (modified) lldb/tools/lldb-dap/IOStream.cpp (+9-10) 
- (modified) lldb/tools/lldb-dap/IOStream.h (+3-4) 
- (modified) lldb/tools/lldb-dap/lldb-dap.cpp (+42-33) 


``diff
diff --git a/lldb/tools/lldb-dap/CMakeLists.txt 
b/lldb/tools/lldb-dap/CMakeLists.txt
index 8b3c520ec4360..d9f09f6d022ed 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -23,6 +23,7 @@ add_lldb_tool(lldb-dap
   Breakpoint.cpp
   BreakpointBase.cpp
   DAP.cpp
+  DAPLog.cpp
   EventHelper.cpp
   ExceptionBreakpoint.cpp
   FifoFiles.cpp
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 53c514b790f38..81f5205d4f6bd 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 
 #include "DAP.h"
+#include "DAPLog.h"
 #include "Handler/ResponseHandler.h"
 #include "JSONUtils.h"
 #include "LLDBUtils.h"
@@ -19,6 +20,7 @@
 #include "lldb/API/SBProcess.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/Utility/IOObject.h"
+#include "lldb/Utility/Log.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-enumerations.h"
@@ -50,6 +52,7 @@
 #endif
 
 using namespace lldb_dap;
+using namespace lldb_private;
 
 namespace {
 #ifdef _WIN32
@@ -61,13 +64,12 @@ const char DEV_NULL[] = "/dev/null";
 
 namespace lldb_dap {
 
-DAP::DAP(std::string name, llvm::StringRef path, std::ofstream *log,
- lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
+DAP::DAP(std::string name, llvm::StringRef path, lldb::IOObjectSP input,
+ lldb::IOObjectSP output, ReplMode repl_mode,
  std::vector pre_init_commands)
-: name(std::move(name)), debug_adapter_path(path), log(log),
-  input(std::move(input)), output(std::move(output)),
-  broadcaster("lldb-dap"), exception_breakpoints(),
-  pre_init_commands(std::move(pre_init_commands)),
+: name(std::move(name)), debug_adapter_path(path), input(std::move(input)),
+  output(std::move(output)), broadcaster("lldb-dap"),
+  exception_breakpoints(), pre_init_commands(std::move(pre_init_commands)),
   focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), 
is_attach(false),
   enable_auto_variable_summaries(false),
   enable_synthetic_child_debugging(false),
@@ -245,6 +247,8 @@ void DAP::SendJSON(const std::string &json_str) {
   output.write_full(llvm::utostr(json_str.size()));
   output.write_full("\r\n\r\n");
   output.write_full(json_str);
+
+  LLDB_LOG(GetLog(DAPLog::Transport), "{0} <-- {1}", name, json_str);
 }
 
 // Serialize the JSON value into a string and send the JSON packet to
@@ -256,15 +260,6 @@ void DAP::SendJSON(const llvm::json::Value &json) {
   static std::mutex mutex;
   std::lock_guard locker(mutex);
   SendJSON(json_str);
-
-  if (log) {
-auto now = std::chrono::duration(
-std::chrono::system_clock::now().time_since_epoch());
-*log << llvm::formatv("{0:f9} {1} <-- ", now.count(), name).str()
- << std::endl
- << "Content-Length: " << json_str.size() << "\r\n\r\n"
- << llvm::formatv("{0:2}", json).str() << std::endl;
-  }
 }
 
 // Read a JSON packet from the "in" stream.
@@ -273,28 +268,22 @@ std::string DAP::ReadJSON() {
   std::string json_str;
   int length;
 
-  if (!input.read_expected(log, "Content-Length: "))
+  if (!input.read_expected("Content-Length: "))
 return json_str;
 
-  if (!input.read_line(log, length_str))
+  if (!input.read_line(length_str))
 return json_str;
 
   if (!llvm::to_integer(length_str, length))
 return json_str;
 
-  if (!input.read_expected(log, "\r\n"))
+  if (!input.read_expected("\r\n"))
 return json_str;
 
-  if (!input.read_full(log, length, json_str))
+  if (!input.read_full(length, json_str))
 return json_str;
 
-  if (log) {
-auto now = std::chrono::duration(
-std::chrono::system_clock::now().time_since_epoch());
-*log << llvm::formatv("{0:f9} {1} --> ", now.count(), name).str()
- << std::endl
- << "Content-Length: " 

[Lldb-commits] [lldb] [lldb-dap] Implement a MemoryMonitor for macOS & Linux (PR #129332)

2025-02-28 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,114 @@
+//===-- MemoryMonitor.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
+//
+//===--===//
+
+#include "MemoryMonitor.h"
+#include "llvm/ADT/ScopeExit.h"
+#include 
+#include 
+#include 
+#include 
+
+#if defined(__APPLE__)
+#include 
+#endif
+
+#if defined(__linux__)
+#include 
+#include 
+#include 
+#endif
+
+using namespace lldb_dap;
+
+#if defined(__APPLE__)
+class MemoryMonitorDarwin : public MemoryMonitor {
+  using MemoryMonitor::MemoryMonitor;
+  void Start() override {
+m_memory_pressure_source = dispatch_source_create(
+DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
+0, // system-wide monitoring
+DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL,
+dispatch_get_main_queue());

JDevlieghere wrote:

Good catch, I meant to use `dispatch_get_global_queue` and I confused it with 
`dispatch_get_main_queue` .

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


[Lldb-commits] [lldb] [LLDB][Minidump]Update MinidumpFileBuilder to read and write in chunks (PR #129307)

2025-02-28 Thread Jacob Lalonde via lldb-commits

https://github.com/Jlalond updated 
https://github.com/llvm/llvm-project/pull/129307

>From 2f77beefb752ffdae908101d75381268203311d6 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde 
Date: Fri, 28 Feb 2025 11:38:35 -0800
Subject: [PATCH 1/2] Update MinidumpFileBuilder to read and write in chunks

---
 .../Minidump/MinidumpFileBuilder.cpp  | 130 --
 .../ObjectFile/Minidump/MinidumpFileBuilder.h |   7 +
 2 files changed, 97 insertions(+), 40 deletions(-)

diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp 
b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
index c5013ea5e3be4..e88b606f279cd 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
+++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
@@ -969,12 +969,82 @@ Status MinidumpFileBuilder::DumpDirectories() const {
   return error;
 }
 
-static uint64_t
-GetLargestRangeSize(const std::vector &ranges) {
-  uint64_t max_size = 0;
-  for (const auto &core_range : ranges)
-max_size = std::max(max_size, core_range.range.size());
-  return max_size;
+Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
+const lldb_private::CoreFileMemoryRange &range, uint64_t *bytes_read) {
+  Log *log = GetLog(LLDBLog::Object);
+  lldb::addr_t addr = range.range.start();
+  lldb::addr_t size = range.range.size();
+  // First we set the byte tally to 0, so if we do exit gracefully
+  // the caller doesn't think the random garbage on the stack is a
+  // success.
+  if (bytes_read)
+*bytes_read = 0;
+
+  uint64_t bytes_remaining = size;
+  uint64_t total_bytes_read = 0;
+  auto data_up = std::make_unique(
+  std::min(bytes_remaining, MAX_WRITE_CHUNK_SIZE), 0);
+  Status error;
+  while (bytes_remaining > 0) {
+// Get the next read chunk size as the minimum of the remaining bytes and
+// the write chunk max size.
+const size_t bytes_to_read =
+std::min(bytes_remaining, MAX_WRITE_CHUNK_SIZE);
+const size_t bytes_read_for_chunk =
+m_process_sp->ReadMemory(range.range.start() + total_bytes_read,
+ data_up->GetBytes(), bytes_to_read, error);
+if (error.Fail() || bytes_read_for_chunk == 0) {
+  LLDB_LOGF(log,
+"Failed to read memory region at: %" PRIx64
+". Bytes read: %zu, error: %s",
+addr, bytes_read_for_chunk, error.AsCString());
+  // If we've only read one byte we can just give up and return
+  if (total_bytes_read == 0)
+return Status();
+
+  // If we've read some bytes, we stop trying to read more and return
+  // this best effort attempt
+  bytes_remaining = 0;
+} else if (bytes_read_for_chunk != bytes_to_read) {
+  LLDB_LOGF(
+  log, "Memory region at: %" PRIx64 " failed to read %" PRIx64 " 
bytes",
+  addr, size);
+
+  // If we've read some bytes, we stop trying to read more and return
+  // this best effort attempt
+  bytes_remaining = 0;
+}
+
+// Write to the minidump file with the chunk potentially flushing to disk.
+// this is the only place we want to return a true error, so that we can
+// fail. If we get an error writing to disk we can't easily gaurauntee
+// that we won't corrupt the minidump.
+error = AddData(data_up->GetBytes(), bytes_read_for_chunk);
+if (error.Fail())
+  return error;
+
+// This check is so we don't overflow when the error code above sets the
+// bytes to read to 0 (the graceful exit condition).
+if (bytes_remaining > 0)
+  bytes_remaining -= bytes_read_for_chunk;
+
+total_bytes_read += bytes_read_for_chunk;
+// If the caller wants a tally back of the bytes_read, update it as we
+// write. We do this in the loop so if we encounter an error we can
+// report the accurate total.
+if (bytes_read)
+  *bytes_read += bytes_read_for_chunk;
+
+// We clear the heap per loop, without checking if we
+// read the expected bytes this is so we don't allocate
+// more than the MAX_WRITE_CHUNK_SIZE. But we do check if
+// this is even worth clearing before we return and
+// destruct the heap.
+if (bytes_remaining > 0)
+  data_up->Clear();
+  }
+
+  return error;
 }
 
 Status
@@ -987,8 +1057,6 @@ 
MinidumpFileBuilder::AddMemoryList_32(std::vector &ranges,
 
   Log *log = GetLog(LLDBLog::Object);
   size_t region_index = 0;
-  auto data_up =
-  std::make_unique(GetLargestRangeSize(ranges), 0);
   for (const auto &core_range : ranges) {
 // Take the offset before we write.
 const offset_t offset_for_data = GetCurrentDataEndOffset();
@@ -1003,18 +1071,15 @@ 
MinidumpFileBuilder::AddMemoryList_32(std::vector &ranges,
 ++region_index;
 
 progress.Increment(1, "Adding Memory Range " + core_range.Dump());
-const size_t bytes_read =
-m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
-if (error.Fail() || bytes_read == 0) {

[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread via lldb-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff a3ac1f2278dec155e0e0b4d06ec816ba325f6979 
8d466e5c4b1b6913e788fd11d46689af8f0b8eec --extensions h,cpp -- 
lldb/tools/lldb-dap/DAPLog.cpp lldb/tools/lldb-dap/DAPLog.h 
lldb/tools/lldb-dap/DAP.cpp lldb/tools/lldb-dap/DAP.h 
lldb/tools/lldb-dap/EventHelper.cpp lldb/tools/lldb-dap/IOStream.cpp 
lldb/tools/lldb-dap/IOStream.h lldb/tools/lldb-dap/lldb-dap.cpp
``





View the diff from clang-format here.


``diff
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index ea5e17eb5d..d587d36b9e 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -125,21 +125,21 @@ struct Variables {
 
 struct StartDebuggingRequestHandler : public lldb::SBCommandPluginInterface {
   DAP &dap;
-  explicit StartDebuggingRequestHandler(DAP &d) : dap(d){};
+  explicit StartDebuggingRequestHandler(DAP &d) : dap(d) {};
   bool DoExecute(lldb::SBDebugger debugger, char **command,
  lldb::SBCommandReturnObject &result) override;
 };
 
 struct ReplModeRequestHandler : public lldb::SBCommandPluginInterface {
   DAP &dap;
-  explicit ReplModeRequestHandler(DAP &d) : dap(d){};
+  explicit ReplModeRequestHandler(DAP &d) : dap(d) {};
   bool DoExecute(lldb::SBDebugger debugger, char **command,
  lldb::SBCommandReturnObject &result) override;
 };
 
 struct SendEventRequestHandler : public lldb::SBCommandPluginInterface {
   DAP &dap;
-  explicit SendEventRequestHandler(DAP &d) : dap(d){};
+  explicit SendEventRequestHandler(DAP &d) : dap(d) {};
   bool DoExecute(lldb::SBDebugger debugger, char **command,
  lldb::SBCommandReturnObject &result) override;
 };

``




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


[Lldb-commits] [lldb] Control the "step out through thunk" logic explicitly when pushing thread plans (PR #129301)

2025-02-28 Thread Felipe de Azevedo Piovezan via lldb-commits

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

LGTM!

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


[Lldb-commits] [lldb] Control the "step out through thunk" logic explicitly when pushing thread plans (PR #129301)

2025-02-28 Thread via lldb-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 56cc9299b7804257549edb4a7ba15999cbb5 
a26c5596ac599f1b51cffebd658f3823388e --extensions cpp,h -- 
lldb/include/lldb/Target/ThreadPlanShouldStopHere.h 
lldb/source/Target/ThreadPlanShouldStopHere.cpp 
lldb/source/Target/ThreadPlanStepInRange.cpp
``





View the diff from clang-format here.


``diff
diff --git a/lldb/source/Target/ThreadPlanShouldStopHere.cpp 
b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
index be6bd981c7..d2cca49987 100644
--- a/lldb/source/Target/ThreadPlanShouldStopHere.cpp
+++ b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
@@ -84,11 +84,12 @@ bool 
ThreadPlanShouldStopHere::DefaultShouldStopHereCallback(
 if (Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol) 
{
   ProcessSP process_sp(current_plan->GetThread().GetProcess());
   for (auto *runtime : process_sp->GetLanguageRuntimes()) {
-if (runtime->IsSymbolARuntimeThunk(*symbol)
- && flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
- LLDB_LOGF(log, "Stepping out past a language thunk %s for: %s",
-   frame->GetFunctionName(),
-   
Language::GetNameForLanguageType(runtime->GetLanguageType()));
+if (runtime->IsSymbolARuntimeThunk(*symbol) &&
+flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
+  LLDB_LOGF(
+  log, "Stepping out past a language thunk %s for: %s",
+  frame->GetFunctionName(),
+  Language::GetNameForLanguageType(runtime->GetLanguageType()));
   should_stop_here = false;
   break;
 }
@@ -136,11 +137,12 @@ ThreadPlanSP 
ThreadPlanShouldStopHere::DefaultStepFromHereCallback(
   // because it's marked line 0.
   bool is_thunk = false;
   for (auto *runtime : process_sp->GetLanguageRuntimes()) {
-if (runtime->IsSymbolARuntimeThunk(*sc.symbol)
- && flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
-  LLDB_LOGF(log, "Stepping out past a language thunk %s for: %s",
-   frame->GetFunctionName(),
-   
Language::GetNameForLanguageType(runtime->GetLanguageType()));
+if (runtime->IsSymbolARuntimeThunk(*sc.symbol) &&
+flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
+  LLDB_LOGF(
+  log, "Stepping out past a language thunk %s for: %s",
+  frame->GetFunctionName(),
+  Language::GetNameForLanguageType(runtime->GetLanguageType()));
   is_thunk = true;
   break;
 }
diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp 
b/lldb/source/Target/ThreadPlanStepInRange.cpp
index 3affeae1ee..8a2417e9da 100644
--- a/lldb/source/Target/ThreadPlanStepInRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepInRange.cpp
@@ -27,7 +27,7 @@ using namespace lldb;
 using namespace lldb_private;
 
 uint32_t ThreadPlanStepInRange::s_default_flag_values =
-ThreadPlanShouldStopHere::eStepInAvoidNoDebug | 
+ThreadPlanShouldStopHere::eStepInAvoidNoDebug |
 ThreadPlanShouldStopHere::eStepOutPastThunks;
 
 // ThreadPlanStepInRange: Step through a stack range, either stepping over or

``




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


[Lldb-commits] [lldb] Control the "step out through thunk" logic explicitly when pushing thread plans (PR #129301)

2025-02-28 Thread via lldb-commits

https://github.com/jimingham updated 
https://github.com/llvm/llvm-project/pull/129301

>From a26c5596ac599f1b51cffebd658f3823388e Mon Sep 17 00:00:00 2001
From: Jim Ingham 
Date: Fri, 28 Feb 2025 11:45:51 -0800
Subject: [PATCH 1/2] Control the "step out through thunk" logic explicitly
 when pushing thread plans.

That allow the thread plan that is trying to step through a thunk to its target
to step out of a function it has stepped into without also stepping out past
the thunk we were trying to step through.
---
 .../lldb/Target/ThreadPlanShouldStopHere.h|  3 ++-
 lldb/source/Target/ThreadPlanShouldStopHere.cpp   | 15 +++
 lldb/source/Target/ThreadPlanStepInRange.cpp  |  3 ++-
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h 
b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
index 54b30291c3995..d0094c90b91a5 100644
--- a/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
+++ b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
@@ -59,7 +59,8 @@ class ThreadPlanShouldStopHere {
 eNone = 0,
 eAvoidInlines = (1 << 0),
 eStepInAvoidNoDebug = (1 << 1),
-eStepOutAvoidNoDebug = (1 << 2)
+eStepOutAvoidNoDebug = (1 << 2),
+eStepOutPastThunks = (1 << 3)
   };
 
   // Constructors and Destructors
diff --git a/lldb/source/Target/ThreadPlanShouldStopHere.cpp 
b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
index fa6bc08a9914d..be6bd981c72bc 100644
--- a/lldb/source/Target/ThreadPlanShouldStopHere.cpp
+++ b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
@@ -8,6 +8,7 @@
 
 #include "lldb/Target/ThreadPlanShouldStopHere.h"
 #include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/Language.h"
 #include "lldb/Target/LanguageRuntime.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Thread.h"
@@ -83,7 +84,11 @@ bool ThreadPlanShouldStopHere::DefaultShouldStopHereCallback(
 if (Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol) 
{
   ProcessSP process_sp(current_plan->GetThread().GetProcess());
   for (auto *runtime : process_sp->GetLanguageRuntimes()) {
-if (runtime->IsSymbolARuntimeThunk(*symbol)) {
+if (runtime->IsSymbolARuntimeThunk(*symbol)
+ && flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
+ LLDB_LOGF(log, "Stepping out past a language thunk %s for: %s",
+   frame->GetFunctionName(),
+   
Language::GetNameForLanguageType(runtime->GetLanguageType()));
   should_stop_here = false;
   break;
 }
@@ -131,9 +136,11 @@ ThreadPlanSP 
ThreadPlanShouldStopHere::DefaultStepFromHereCallback(
   // because it's marked line 0.
   bool is_thunk = false;
   for (auto *runtime : process_sp->GetLanguageRuntimes()) {
-if (runtime->IsSymbolARuntimeThunk(*sc.symbol)) {
-  LLDB_LOGF(log, "In runtime thunk %s - stepping out.",
-sc.symbol->GetName().GetCString());
+if (runtime->IsSymbolARuntimeThunk(*sc.symbol)
+ && flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
+  LLDB_LOGF(log, "Stepping out past a language thunk %s for: %s",
+   frame->GetFunctionName(),
+   
Language::GetNameForLanguageType(runtime->GetLanguageType()));
   is_thunk = true;
   break;
 }
diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp 
b/lldb/source/Target/ThreadPlanStepInRange.cpp
index 109d1b6b3435b..3affeae1ee388 100644
--- a/lldb/source/Target/ThreadPlanStepInRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepInRange.cpp
@@ -27,7 +27,8 @@ using namespace lldb;
 using namespace lldb_private;
 
 uint32_t ThreadPlanStepInRange::s_default_flag_values =
-ThreadPlanShouldStopHere::eStepInAvoidNoDebug;
+ThreadPlanShouldStopHere::eStepInAvoidNoDebug | 
+ThreadPlanShouldStopHere::eStepOutPastThunks;
 
 // ThreadPlanStepInRange: Step through a stack range, either stepping over or
 // into based on the value of \a type.

>From 2ce4ca483a7f6a812d35b94a99425b250fe4a43a Mon Sep 17 00:00:00 2001
From: Jim Ingham 
Date: Fri, 28 Feb 2025 13:40:05 -0800
Subject: [PATCH 2/2] clang-format

---
 .../Target/ThreadPlanShouldStopHere.cpp   | 22 ++-
 lldb/source/Target/ThreadPlanStepInRange.cpp  |  2 +-
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/lldb/source/Target/ThreadPlanShouldStopHere.cpp 
b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
index be6bd981c72bc..d2cca49987f0f 100644
--- a/lldb/source/Target/ThreadPlanShouldStopHere.cpp
+++ b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
@@ -84,11 +84,12 @@ bool 
ThreadPlanShouldStopHere::DefaultShouldStopHereCallback(
 if (Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol) 
{
   ProcessSP process_sp(current_plan->GetThread().GetProcess());
   for (auto *runtime : process_sp->GetLanguageRuntimes()) {
-if (runtime->IsSymb

[Lldb-commits] [lldb] [LLDB][Minidump]Update MinidumpFileBuilder to read and write in chunks (PR #129307)

2025-02-28 Thread Jacob Lalonde via lldb-commits

Jlalond wrote:

@labath / @clayborg  to preempt some expected feedback, I intend to expose this 
chunk size in a future setting

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


[Lldb-commits] [lldb] Update MinidumpFileBuilder to read and write in chunks (PR #129307)

2025-02-28 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Jacob Lalonde (Jlalond)


Changes

I recently received an internal error report that LLDB was OOM'ing when 
creating a Minidump. In my 64b refactor we made a decision to acquire buffers 
the size of the largest memory region so we could read all of the contents in 
one call. This made error handling very simple (and simpler coding for me!) but 
had the trade off of large allocations if huge pages were enabled.

This patch is one I've had on the back burner for awhile, but we can read and 
write the Minidump memory sections in discrete chunks which we already do for 
writing to disk.

I had to refactor the error handling a bit, but it remains the same. We make a 
best effort attempt to read as much of the memory region as possible, but fail 
immediately if we receive an error writing to disk. I did not add new tests for 
this because our existing test suite is quite good, but I did manually verify a 
few Minidumps couldn't read beyond the red_zone.

```
(lldb) reg read $sp
 rsp = 0x7fffc3b0
(lldb) p/x 0x7fffc3b0 - 128
(long) 0x7fffc330
(lldb) memory read 0x7fffc330
0x7fffc330: 60 c3 ff ff ff 7f 00 00 60 cd ff ff ff 7f 00 00  
`...`...
0x7fffc340: 60 c3 ff ff ff 7f 00 00 65 e6 26 00 00 00 00 00  
`...e.&.
(lldb) memory read 0x7fffc329
error: could not parse memory info
```

I'm not sure how to quantify the memory improvement other than we would 
allocate the largest size regardless of the size. So a 2gb unreadable region 
would cause a 2gb allocation even if we were reading 4096 kb. Now we will take 
the range size or the max chunk size of 128 mb.

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


2 Files Affected:

- (modified) lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp 
(+90-40) 
- (modified) lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h (+7) 


``diff
diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp 
b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
index c5013ea5e3be4..e88b606f279cd 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
+++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
@@ -969,12 +969,82 @@ Status MinidumpFileBuilder::DumpDirectories() const {
   return error;
 }
 
-static uint64_t
-GetLargestRangeSize(const std::vector &ranges) {
-  uint64_t max_size = 0;
-  for (const auto &core_range : ranges)
-max_size = std::max(max_size, core_range.range.size());
-  return max_size;
+Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
+const lldb_private::CoreFileMemoryRange &range, uint64_t *bytes_read) {
+  Log *log = GetLog(LLDBLog::Object);
+  lldb::addr_t addr = range.range.start();
+  lldb::addr_t size = range.range.size();
+  // First we set the byte tally to 0, so if we do exit gracefully
+  // the caller doesn't think the random garbage on the stack is a
+  // success.
+  if (bytes_read)
+*bytes_read = 0;
+
+  uint64_t bytes_remaining = size;
+  uint64_t total_bytes_read = 0;
+  auto data_up = std::make_unique(
+  std::min(bytes_remaining, MAX_WRITE_CHUNK_SIZE), 0);
+  Status error;
+  while (bytes_remaining > 0) {
+// Get the next read chunk size as the minimum of the remaining bytes and
+// the write chunk max size.
+const size_t bytes_to_read =
+std::min(bytes_remaining, MAX_WRITE_CHUNK_SIZE);
+const size_t bytes_read_for_chunk =
+m_process_sp->ReadMemory(range.range.start() + total_bytes_read,
+ data_up->GetBytes(), bytes_to_read, error);
+if (error.Fail() || bytes_read_for_chunk == 0) {
+  LLDB_LOGF(log,
+"Failed to read memory region at: %" PRIx64
+". Bytes read: %zu, error: %s",
+addr, bytes_read_for_chunk, error.AsCString());
+  // If we've only read one byte we can just give up and return
+  if (total_bytes_read == 0)
+return Status();
+
+  // If we've read some bytes, we stop trying to read more and return
+  // this best effort attempt
+  bytes_remaining = 0;
+} else if (bytes_read_for_chunk != bytes_to_read) {
+  LLDB_LOGF(
+  log, "Memory region at: %" PRIx64 " failed to read %" PRIx64 " 
bytes",
+  addr, size);
+
+  // If we've read some bytes, we stop trying to read more and return
+  // this best effort attempt
+  bytes_remaining = 0;
+}
+
+// Write to the minidump file with the chunk potentially flushing to disk.
+// this is the only place we want to return a true error, so that we can
+// fail. If we get an error writing to disk we can't easily gaurauntee
+// that we won't corrupt the minidump.
+error = AddData(data_up->GetBytes(), bytes_read_for_chunk);
+if (error.Fail())
+  return error;
+
+// This check is so we don't overflow when the error code above sets the
+

[Lldb-commits] [lldb] ddbce2f - Control the "step out through thunk" logic explicitly when pushing thread plans (#129301)

2025-02-28 Thread via lldb-commits

Author: jimingham
Date: 2025-02-28T13:44:17-08:00
New Revision: ddbce2fd2380a4eafce9065ad991318f46a3292b

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

LOG: Control the "step out through thunk" logic explicitly when pushing thread 
plans (#129301)

Jonas recently added a trampoline handling strategy for simple language
thunks that does: "step through language thunks stepping in one level
deep and stopping if you hit user code". That was actually pulled over
from the swift implementation. However, this strategy and the strategy
we have to "step out past language thunks" when stepping out come into
conflict if the thunk you are stepping through calls some other function
before dispatching to the intended method. When you step out of the
called function back into the thunk, should you keep stepping out past
the thunk or not?

In most cases, you want to step out past the thunk, but in this
particular case you don't.

This patch adds a way to inform the thread plan (or really it's
ShouldStopHere behavior) of which behavior it should have, and passes
the don't step through thunks to the step through plan it uses to step
through thunks.

I didn't add a test for this because I couldn't find a C++ thunk that
calls another function before getting to the target function. I asked
the clang folks here if they could think of a case where clang would do
this, and they couldn't. If anyone can think of such a construct, it
will be easy to write the step through test for it...

This does happen in swift, however, so when I cherry-pick this to the
swift fork I'll test it there.

Added: 


Modified: 
lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
lldb/source/Target/ThreadPlanShouldStopHere.cpp
lldb/source/Target/ThreadPlanStepInRange.cpp

Removed: 




diff  --git a/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h 
b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
index 54b30291c3995..d0094c90b91a5 100644
--- a/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
+++ b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
@@ -59,7 +59,8 @@ class ThreadPlanShouldStopHere {
 eNone = 0,
 eAvoidInlines = (1 << 0),
 eStepInAvoidNoDebug = (1 << 1),
-eStepOutAvoidNoDebug = (1 << 2)
+eStepOutAvoidNoDebug = (1 << 2),
+eStepOutPastThunks = (1 << 3)
   };
 
   // Constructors and Destructors

diff  --git a/lldb/source/Target/ThreadPlanShouldStopHere.cpp 
b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
index fa6bc08a9914d..d2cca49987f0f 100644
--- a/lldb/source/Target/ThreadPlanShouldStopHere.cpp
+++ b/lldb/source/Target/ThreadPlanShouldStopHere.cpp
@@ -8,6 +8,7 @@
 
 #include "lldb/Target/ThreadPlanShouldStopHere.h"
 #include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/Language.h"
 #include "lldb/Target/LanguageRuntime.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Thread.h"
@@ -83,7 +84,12 @@ bool ThreadPlanShouldStopHere::DefaultShouldStopHereCallback(
 if (Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol) 
{
   ProcessSP process_sp(current_plan->GetThread().GetProcess());
   for (auto *runtime : process_sp->GetLanguageRuntimes()) {
-if (runtime->IsSymbolARuntimeThunk(*symbol)) {
+if (runtime->IsSymbolARuntimeThunk(*symbol) &&
+flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
+  LLDB_LOGF(
+  log, "Stepping out past a language thunk %s for: %s",
+  frame->GetFunctionName(),
+  Language::GetNameForLanguageType(runtime->GetLanguageType()));
   should_stop_here = false;
   break;
 }
@@ -131,9 +137,12 @@ ThreadPlanSP 
ThreadPlanShouldStopHere::DefaultStepFromHereCallback(
   // because it's marked line 0.
   bool is_thunk = false;
   for (auto *runtime : process_sp->GetLanguageRuntimes()) {
-if (runtime->IsSymbolARuntimeThunk(*sc.symbol)) {
-  LLDB_LOGF(log, "In runtime thunk %s - stepping out.",
-sc.symbol->GetName().GetCString());
+if (runtime->IsSymbolARuntimeThunk(*sc.symbol) &&
+flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
+  LLDB_LOGF(
+  log, "Stepping out past a language thunk %s for: %s",
+  frame->GetFunctionName(),
+  Language::GetNameForLanguageType(runtime->GetLanguageType()));
   is_thunk = true;
   break;
 }

diff  --git a/lldb/source/Target/ThreadPlanStepInRange.cpp 
b/lldb/source/Target/ThreadPlanStepInRange.cpp
index 109d1b6b3435b..8a2417e9da326 100644
--- a/lldb/source/Target/ThreadPlanStepInRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepInRange.cpp
@@ -27,7 +27,8 @@ using namespace lldb;
 using namespace lldb_private;
 
 uint32_t Threa

[Lldb-commits] [lldb] [lldb-dap] Implement a MemoryMonitor for macOS & Linux (PR #129332)

2025-02-28 Thread Jonas Devlieghere via lldb-commits

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

This implements a memory monitor for macOS & Linux, and registers a callback 
that invokes SBDebugger::MemoryPressureDetected() when a low memory event is 
detected.

>From c63350db79ac6bcc6f180cc84a37e829d1c8b2a8 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere 
Date: Fri, 28 Feb 2025 14:54:42 -0600
Subject: [PATCH] [lldb-dap] Implement a MemoryMonitor for macOS & Linux

This implements a memory monitor for macOS & Linux, and registers a
callback that invokes SBDebugger::MemoryPressureDetected() when a low
memory event is detected.
---
 lldb/tools/lldb-dap/CMakeLists.txt|   1 +
 lldb/tools/lldb-dap/MemoryMonitor.cpp | 114 ++
 lldb/tools/lldb-dap/MemoryMonitor.h   |  41 +
 lldb/tools/lldb-dap/lldb-dap.cpp  |  17 +++-
 4 files changed, 171 insertions(+), 2 deletions(-)
 create mode 100644 lldb/tools/lldb-dap/MemoryMonitor.cpp
 create mode 100644 lldb/tools/lldb-dap/MemoryMonitor.h

diff --git a/lldb/tools/lldb-dap/CMakeLists.txt 
b/lldb/tools/lldb-dap/CMakeLists.txt
index 8b3c520ec4360..8db377e31c3c6 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -36,6 +36,7 @@ add_lldb_tool(lldb-dap
   RunInTerminal.cpp
   SourceBreakpoint.cpp
   Watchpoint.cpp
+  MemoryMonitor.cpp
 
   Handler/ResponseHandler.cpp
   Handler/AttachRequestHandler.cpp
diff --git a/lldb/tools/lldb-dap/MemoryMonitor.cpp 
b/lldb/tools/lldb-dap/MemoryMonitor.cpp
new file mode 100644
index 0..da3da42fe9b0f
--- /dev/null
+++ b/lldb/tools/lldb-dap/MemoryMonitor.cpp
@@ -0,0 +1,114 @@
+//===-- MemoryMonitor.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
+//
+//===--===//
+
+#include "MemoryMonitor.h"
+#include "llvm/ADT/ScopeExit.h"
+#include 
+#include 
+#include 
+#include 
+
+#if defined(__APPLE__)
+#include 
+#endif
+
+#if defined(__linux__)
+#include 
+#include 
+#include 
+#endif
+
+using namespace lldb_dap;
+
+#if defined(__APPLE__)
+class MemoryMonitorDarwin : public MemoryMonitor {
+  using MemoryMonitor::MemoryMonitor;
+  void Start() override {
+m_memory_pressure_source = dispatch_source_create(
+DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
+0, // system-wide monitoring
+DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL,
+dispatch_get_main_queue());
+
+dispatch_source_set_event_handler(m_memory_pressure_source, ^{
+  dispatch_source_memorypressure_flags_t pressureLevel =
+  dispatch_source_get_data(m_memory_pressure_source);
+  if (pressureLevel &
+  (DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL)) {
+m_callback();
+  }
+});
+  }
+
+  void Stop() override { dispatch_source_cancel(m_memory_pressure_source); }
+
+private:
+  dispatch_source_t m_memory_pressure_source;
+};
+#endif
+
+#if defined(__linux__)
+static void MonitorThread(std::atomic &done,
+  MemoryMonitor::Callback callback) {
+  struct pollfd fds;
+  fds.fd = open("/proc/pressure/memory", O_RDWR | O_NONBLOCK);
+  if (fds.fd < 0)
+return;
+  fds.events = POLLPRI;
+
+  auto cleanup = llvm::make_scope_exit([&]() { close(fds.fd); });
+
+  // Detect a 50ms stall in a 2 second time window.
+  const char trig[] = "some 5 200";
+  if (write(fds.fd, trig, strlen(trig) + 1) < 0)
+return;
+
+  while (!done) {
+int n = poll(&fds, 1, 1000);
+if (n > 0) {
+  if (fds.revents & POLLERR)
+return;
+  if (fds.revents & POLLPRI)
+callback();
+}
+  }
+}
+
+class MemoryMonitorLinux : public MemoryMonitor {
+public:
+  using MemoryMonitor::MemoryMonitor;
+
+  void Start() override {
+m_memory_pressure_thread =
+std::thread(MonitorThread, std::ref(m_done), m_callback);
+  }
+
+  void Stop() override {
+if (m_memory_pressure_thread.joinable()) {
+  m_done = true;
+  m_memory_pressure_thread.join();
+}
+  }
+
+private:
+  std::atomic m_done = false;
+  std::thread m_memory_pressure_thread;
+};
+#endif
+
+std::unique_ptr MemoryMonitor::Create(Callback callback) {
+#if defined(__APPLE__)
+  return std::make_unique(callback);
+#endif
+
+#if defined(__linux__)
+  return std::make_unique(callback);
+#endif
+
+  return nullptr;
+}
diff --git a/lldb/tools/lldb-dap/MemoryMonitor.h 
b/lldb/tools/lldb-dap/MemoryMonitor.h
new file mode 100644
index 0..e07c3bde9e85c
--- /dev/null
+++ b/lldb/tools/lldb-dap/MemoryMonitor.h
@@ -0,0 +1,41 @@
+//===-- MemoryMonitor.h 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/L

[Lldb-commits] [lldb] [lldb-dap] Implement a MemoryMonitor for macOS & Linux (PR #129332)

2025-02-28 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)


Changes

This implements a memory monitor for macOS & Linux, and registers a 
callback that invokes SBDebugger::MemoryPressureDetected() when a low memory 
event is detected.

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


4 Files Affected:

- (modified) lldb/tools/lldb-dap/CMakeLists.txt (+1) 
- (added) lldb/tools/lldb-dap/MemoryMonitor.cpp (+114) 
- (added) lldb/tools/lldb-dap/MemoryMonitor.h (+41) 
- (modified) lldb/tools/lldb-dap/lldb-dap.cpp (+15-2) 


``diff
diff --git a/lldb/tools/lldb-dap/CMakeLists.txt 
b/lldb/tools/lldb-dap/CMakeLists.txt
index 8b3c520ec4360..8db377e31c3c6 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -36,6 +36,7 @@ add_lldb_tool(lldb-dap
   RunInTerminal.cpp
   SourceBreakpoint.cpp
   Watchpoint.cpp
+  MemoryMonitor.cpp
 
   Handler/ResponseHandler.cpp
   Handler/AttachRequestHandler.cpp
diff --git a/lldb/tools/lldb-dap/MemoryMonitor.cpp 
b/lldb/tools/lldb-dap/MemoryMonitor.cpp
new file mode 100644
index 0..da3da42fe9b0f
--- /dev/null
+++ b/lldb/tools/lldb-dap/MemoryMonitor.cpp
@@ -0,0 +1,114 @@
+//===-- MemoryMonitor.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
+//
+//===--===//
+
+#include "MemoryMonitor.h"
+#include "llvm/ADT/ScopeExit.h"
+#include 
+#include 
+#include 
+#include 
+
+#if defined(__APPLE__)
+#include 
+#endif
+
+#if defined(__linux__)
+#include 
+#include 
+#include 
+#endif
+
+using namespace lldb_dap;
+
+#if defined(__APPLE__)
+class MemoryMonitorDarwin : public MemoryMonitor {
+  using MemoryMonitor::MemoryMonitor;
+  void Start() override {
+m_memory_pressure_source = dispatch_source_create(
+DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
+0, // system-wide monitoring
+DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL,
+dispatch_get_main_queue());
+
+dispatch_source_set_event_handler(m_memory_pressure_source, ^{
+  dispatch_source_memorypressure_flags_t pressureLevel =
+  dispatch_source_get_data(m_memory_pressure_source);
+  if (pressureLevel &
+  (DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL)) {
+m_callback();
+  }
+});
+  }
+
+  void Stop() override { dispatch_source_cancel(m_memory_pressure_source); }
+
+private:
+  dispatch_source_t m_memory_pressure_source;
+};
+#endif
+
+#if defined(__linux__)
+static void MonitorThread(std::atomic &done,
+  MemoryMonitor::Callback callback) {
+  struct pollfd fds;
+  fds.fd = open("/proc/pressure/memory", O_RDWR | O_NONBLOCK);
+  if (fds.fd < 0)
+return;
+  fds.events = POLLPRI;
+
+  auto cleanup = llvm::make_scope_exit([&]() { close(fds.fd); });
+
+  // Detect a 50ms stall in a 2 second time window.
+  const char trig[] = "some 5 200";
+  if (write(fds.fd, trig, strlen(trig) + 1) < 0)
+return;
+
+  while (!done) {
+int n = poll(&fds, 1, 1000);
+if (n > 0) {
+  if (fds.revents & POLLERR)
+return;
+  if (fds.revents & POLLPRI)
+callback();
+}
+  }
+}
+
+class MemoryMonitorLinux : public MemoryMonitor {
+public:
+  using MemoryMonitor::MemoryMonitor;
+
+  void Start() override {
+m_memory_pressure_thread =
+std::thread(MonitorThread, std::ref(m_done), m_callback);
+  }
+
+  void Stop() override {
+if (m_memory_pressure_thread.joinable()) {
+  m_done = true;
+  m_memory_pressure_thread.join();
+}
+  }
+
+private:
+  std::atomic m_done = false;
+  std::thread m_memory_pressure_thread;
+};
+#endif
+
+std::unique_ptr MemoryMonitor::Create(Callback callback) {
+#if defined(__APPLE__)
+  return std::make_unique(callback);
+#endif
+
+#if defined(__linux__)
+  return std::make_unique(callback);
+#endif
+
+  return nullptr;
+}
diff --git a/lldb/tools/lldb-dap/MemoryMonitor.h 
b/lldb/tools/lldb-dap/MemoryMonitor.h
new file mode 100644
index 0..e07c3bde9e85c
--- /dev/null
+++ b/lldb/tools/lldb-dap/MemoryMonitor.h
@@ -0,0 +1,41 @@
+//===-- MemoryMonitor.h 
---===//
+//
+// 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
+//
+//===--===//
+
+#ifndef LLDB_TOOLS_LLDB_DAP_WATCHPOINT_H
+#define LLDB_TOOLS_LLDB_DAP_WATCHPOINT_H
+
+#include 
+#include 
+
+namespace lldb_dap {
+
+class MemoryMonitor {
+public:
+  using Callback = std::function;
+
+  MemoryMonitor(Callback callback) : m_callback

[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread John Harrison via lldb-commits

https://github.com/ashgti updated 
https://github.com/llvm/llvm-project/pull/129294

>From 8d466e5c4b1b6913e788fd11d46689af8f0b8eec Mon Sep 17 00:00:00 2001
From: John Harrison 
Date: Thu, 27 Feb 2025 15:33:51 -0800
Subject: [PATCH 1/3] [lldb-dap] Updating the logging of lldb-dap to use
 existing LLDBLog.h helpers.

This only creates the basic types need to start using the LLDBLog.h helpers.
Today, logging is handling by a simple `std::ofstream *` for handling logging.
LLDBLog.h can help improve logging by adding new categories of logs and give us 
additional formatting support for log messages.
---
 lldb/tools/lldb-dap/CMakeLists.txt  |  1 +
 lldb/tools/lldb-dap/DAP.cpp | 62 
 lldb/tools/lldb-dap/DAP.h   | 11 ++---
 lldb/tools/lldb-dap/DAPLog.cpp  | 22 +
 lldb/tools/lldb-dap/DAPLog.h| 34 +
 lldb/tools/lldb-dap/EventHelper.cpp | 17 ---
 lldb/tools/lldb-dap/IOStream.cpp| 19 
 lldb/tools/lldb-dap/IOStream.h  |  7 ++-
 lldb/tools/lldb-dap/lldb-dap.cpp| 75 -
 9 files changed, 146 insertions(+), 102 deletions(-)
 create mode 100644 lldb/tools/lldb-dap/DAPLog.cpp
 create mode 100644 lldb/tools/lldb-dap/DAPLog.h

diff --git a/lldb/tools/lldb-dap/CMakeLists.txt 
b/lldb/tools/lldb-dap/CMakeLists.txt
index 8b3c520ec4360..d9f09f6d022ed 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -23,6 +23,7 @@ add_lldb_tool(lldb-dap
   Breakpoint.cpp
   BreakpointBase.cpp
   DAP.cpp
+  DAPLog.cpp
   EventHelper.cpp
   ExceptionBreakpoint.cpp
   FifoFiles.cpp
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 53c514b790f38..81f5205d4f6bd 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 
 #include "DAP.h"
+#include "DAPLog.h"
 #include "Handler/ResponseHandler.h"
 #include "JSONUtils.h"
 #include "LLDBUtils.h"
@@ -19,6 +20,7 @@
 #include "lldb/API/SBProcess.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/Utility/IOObject.h"
+#include "lldb/Utility/Log.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-enumerations.h"
@@ -50,6 +52,7 @@
 #endif
 
 using namespace lldb_dap;
+using namespace lldb_private;
 
 namespace {
 #ifdef _WIN32
@@ -61,13 +64,12 @@ const char DEV_NULL[] = "/dev/null";
 
 namespace lldb_dap {
 
-DAP::DAP(std::string name, llvm::StringRef path, std::ofstream *log,
- lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
+DAP::DAP(std::string name, llvm::StringRef path, lldb::IOObjectSP input,
+ lldb::IOObjectSP output, ReplMode repl_mode,
  std::vector pre_init_commands)
-: name(std::move(name)), debug_adapter_path(path), log(log),
-  input(std::move(input)), output(std::move(output)),
-  broadcaster("lldb-dap"), exception_breakpoints(),
-  pre_init_commands(std::move(pre_init_commands)),
+: name(std::move(name)), debug_adapter_path(path), input(std::move(input)),
+  output(std::move(output)), broadcaster("lldb-dap"),
+  exception_breakpoints(), pre_init_commands(std::move(pre_init_commands)),
   focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), 
is_attach(false),
   enable_auto_variable_summaries(false),
   enable_synthetic_child_debugging(false),
@@ -245,6 +247,8 @@ void DAP::SendJSON(const std::string &json_str) {
   output.write_full(llvm::utostr(json_str.size()));
   output.write_full("\r\n\r\n");
   output.write_full(json_str);
+
+  LLDB_LOG(GetLog(DAPLog::Transport), "{0} <-- {1}", name, json_str);
 }
 
 // Serialize the JSON value into a string and send the JSON packet to
@@ -256,15 +260,6 @@ void DAP::SendJSON(const llvm::json::Value &json) {
   static std::mutex mutex;
   std::lock_guard locker(mutex);
   SendJSON(json_str);
-
-  if (log) {
-auto now = std::chrono::duration(
-std::chrono::system_clock::now().time_since_epoch());
-*log << llvm::formatv("{0:f9} {1} <-- ", now.count(), name).str()
- << std::endl
- << "Content-Length: " << json_str.size() << "\r\n\r\n"
- << llvm::formatv("{0:2}", json).str() << std::endl;
-  }
 }
 
 // Read a JSON packet from the "in" stream.
@@ -273,28 +268,22 @@ std::string DAP::ReadJSON() {
   std::string json_str;
   int length;
 
-  if (!input.read_expected(log, "Content-Length: "))
+  if (!input.read_expected("Content-Length: "))
 return json_str;
 
-  if (!input.read_line(log, length_str))
+  if (!input.read_line(length_str))
 return json_str;
 
   if (!llvm::to_integer(length_str, length))
 return json_str;
 
-  if (!input.read_expected(log, "\r\n"))
+  if (!input.read_expected("\r\n"))
 return json_str;
 
-  if (!input.read_full(log, length, json_str))
+  if (!input.read_full(length, json_str))
 return json_str;
 
-  if (log) {
-auto now = std::chrono::duration(
- 

[Lldb-commits] [lldb] Fix a bug copying the stop hooks from the dummy target. (PR #129340)

2025-02-28 Thread via lldb-commits

https://github.com/jimingham updated 
https://github.com/llvm/llvm-project/pull/129340

>From 02e908312518e85f1d637529c9f62e3dd9551035 Mon Sep 17 00:00:00 2001
From: Jim Ingham 
Date: Fri, 28 Feb 2025 15:55:03 -0800
Subject: [PATCH 1/3] Fix a bug copying the stop hooks from the dummy target.
 We didn't also copy over the next stop hook id, which meant we would
 overwrite the stop hooks from the dummy target with stop hooks set after they
 are copied over.

---
 lldb/source/Target/Target.cpp |  1 +
 .../target/stop-hooks/TestStopHooks.py| 24 +--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index db289fe9c4b64..550424720e095 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -211,6 +211,7 @@ Target::~Target() {
 
 void Target::PrimeFromDummyTarget(Target &target) {
   m_stop_hooks = target.m_stop_hooks;
+  m_stop_hook_next_id = target.m_stop_hook_next_id;
 
   for (const auto &breakpoint_sp : target.m_breakpoint_list.Breakpoints()) {
 if (breakpoint_sp->IsInternal())
diff --git a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py 
b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
index fe59bd8a5d007..5215ec7258d14 100644
--- a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
+++ b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
@@ -26,10 +26,15 @@ def test_stop_hooks_step_out(self):
 self.step_out_test()
 
 def test_stop_hooks_after_expr(self):
-"""Test that a stop hook fires when hitting a breakpoint
-that runs an expression"""
+"""Test that a stop hook fires when hitting a breakpoint that
+   runs an expression"""
 self.after_expr_test()
 
+def test_stop_hooks_before_and_after_creation(self):
+"""Test that if we add a stop hook in the dummy target, we can
+   they don't collide with ones set directly in the target."""
+self.before_and_after_target()
+
 def step_out_test(self):
 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
 self, "Set a breakpoint here", self.main_source_file
@@ -85,3 +90,18 @@ def after_expr_test(self):
 var = target.FindFirstGlobalVariable("g_var")
 self.assertTrue(var.IsValid())
 self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var")
+
+def before_and_after_target(self):
+interp = self.dbg.GetCommandInterpreter()
+result = lldb.SBCommandReturnObject()
+interp.HandleCommand("target stop-hook add -o 'expr g_var++'", result)
+self.assertTrue(result.Succeeded(), "Set the target stop hook")
+
+(target, process, thread, first_bkpt) = 
lldbutil.run_to_source_breakpoint(
+self, "Set a breakpoint here", self.main_source_file
+)
+
+interp.HandleCommand("target stop-hook add -o 'thread backtrace'", 
result)
+self.assertTrue(result.Succeeded(), "Set the target stop hook")
+self.expect("target stop-hook list", substrs=["expr g_var++", "thread 
backtrace"])
+

>From 72e6f179525f1e13e7a1617ab04853304d116537 Mon Sep 17 00:00:00 2001
From: Jim Ingham 
Date: Fri, 28 Feb 2025 16:23:31 -0800
Subject: [PATCH 2/3] uglify

---
 .../test/API/commands/target/stop-hooks/TestStopHooks.py | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py 
b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
index 5215ec7258d14..c2cdcf0e2af52 100644
--- a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
+++ b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py
@@ -27,12 +27,12 @@ def test_stop_hooks_step_out(self):
 
 def test_stop_hooks_after_expr(self):
 """Test that a stop hook fires when hitting a breakpoint that
-   runs an expression"""
+runs an expression"""
 self.after_expr_test()
 
 def test_stop_hooks_before_and_after_creation(self):
 """Test that if we add a stop hook in the dummy target, we can
-   they don't collide with ones set directly in the target."""
+they don't collide with ones set directly in the target."""
 self.before_and_after_target()
 
 def step_out_test(self):
@@ -103,5 +103,6 @@ def before_and_after_target(self):
 
 interp.HandleCommand("target stop-hook add -o 'thread backtrace'", 
result)
 self.assertTrue(result.Succeeded(), "Set the target stop hook")
-self.expect("target stop-hook list", substrs=["expr g_var++", "thread 
backtrace"])
-
+self.expect(
+"target stop-hook list", substrs=["expr g_var++", "thread 
backtrace"]
+)

>From 1f2d82a0d89c7eef48753840d06d63624b1fb8fd Mon Sep 17 00:00:00 2001
From: Jim Ingham 
Date: Fri, 28 Feb 2025 16:59:54 -0800
Subject: [PATCH 3/3] Better comment on the test.

---
 lldb/test/API/commands/target/sto

[Lldb-commits] [lldb] [lldb] Restore register state if PrepareTrivialCall fails (PR #129038)

2025-02-28 Thread David Spickett via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Adding server mode support to lldb-dap VSCode extension. (PR #128957)

2025-02-28 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang commented:

Thank you for your persistence to get this across the finish line! 🎉 

A couple of (late) review comments below. Sorry for the late review :/

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


[Lldb-commits] [lldb] [lldb-dap] Adding server mode support to lldb-dap VSCode extension. (PR #128957)

2025-02-28 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Adding server mode support to lldb-dap VSCode extension. (PR #128957)

2025-02-28 Thread Adrian Vogelsgesang via lldb-commits


@@ -115,41 +123,71 @@ export class LLDBDapDescriptorFactory
 }
 const configEnvironment =
   config.get<{ [key: string]: string }>("environment") || {};
-const dapPath = await getDAPExecutable(session);
+const dapPath = (await getDAPExecutable(session)) ?? executable?.command;
+
+if (!dapPath) {
+  LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage();
+  return undefined;
+}
+
+if (!(await isExecutable(dapPath))) {
+  LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
+  return;
+}
+
 const dbgOptions = {
   env: {
 ...executable?.options?.env,
 ...configEnvironment,
 ...env,
   },
 };
-if (dapPath) {
-  if (!(await isExecutable(dapPath))) {
-LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(dapPath, [], dbgOptions);
-} else if (executable) {
-  if (!(await isExecutable(executable.command))) {
-
LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(executable.command);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(
-executable.command,
-executable.args,
-dbgOptions,
-  );
+const dbgArgs = executable?.args ?? [];
+
+const serverMode = config.get('serverMode', false);
+if (serverMode) {
+  const { host, port } = await this.startServer(dapPath, dbgArgs, 
dbgOptions);
+  return new vscode.DebugAdapterServer(port, host);
 }
-return undefined;
+
+return new vscode.DebugAdapterExecutable(dapPath, dbgArgs, dbgOptions);
+  }
+
+  startServer(dapPath: string, args: string[], options: 
child_process.CommonSpawnOptions): Promise<{ host: string, port: number }> {
+if (this.server) return this.server;

vogelsgesang wrote:

afaict, this does not work correctly in combination with #126803. We might end 
up reusing the wrong lldb-dap binary

Not sure what this means for us, though... We also can't just kill the old 
server when we receive a different lldb-dap path, because we could have two 
separate debugging sessions running at the same time, each one using a 
different server binary. I guess the most robust solution would be to use a 
`Map` to associate each lldb-dap path with its own `Promise<{ process: 
child_process.ChildProcess, host: string, port: number }>`?

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


[Lldb-commits] [lldb] [lldb-dap] Adding server mode support to lldb-dap VSCode extension. (PR #128957)

2025-02-28 Thread Adrian Vogelsgesang via lldb-commits


@@ -115,41 +123,71 @@ export class LLDBDapDescriptorFactory
 }
 const configEnvironment =
   config.get<{ [key: string]: string }>("environment") || {};
-const dapPath = await getDAPExecutable(session);
+const dapPath = (await getDAPExecutable(session)) ?? executable?.command;
+
+if (!dapPath) {
+  LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage();
+  return undefined;
+}
+
+if (!(await isExecutable(dapPath))) {
+  LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
+  return;
+}
+
 const dbgOptions = {
   env: {
 ...executable?.options?.env,
 ...configEnvironment,
 ...env,
   },
 };
-if (dapPath) {
-  if (!(await isExecutable(dapPath))) {
-LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(dapPath, [], dbgOptions);
-} else if (executable) {
-  if (!(await isExecutable(executable.command))) {
-
LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(executable.command);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(
-executable.command,
-executable.args,
-dbgOptions,
-  );
+const dbgArgs = executable?.args ?? [];
+
+const serverMode = config.get('serverMode', false);
+if (serverMode) {
+  const { host, port } = await this.startServer(dapPath, dbgArgs, 
dbgOptions);
+  return new vscode.DebugAdapterServer(port, host);
 }
-return undefined;
+
+return new vscode.DebugAdapterExecutable(dapPath, dbgArgs, dbgOptions);
+  }
+
+  startServer(dapPath: string, args: string[], options: 
child_process.CommonSpawnOptions): Promise<{ host: string, port: number }> {
+if (this.server) return this.server;
+
+this.server = new Promise(resolve => {
+  args.push(
+'--connection',
+'connect://localhost:0'
+  );
+  const server = child_process.spawn(dapPath, args, options);
+  server.stdout!.setEncoding('utf8').once('data', (data: string) => {

vogelsgesang wrote:

Is this actually "race-free" (for lack of a better term)?

Looking at https://nodejs.org/api/stream.html#event-data I am not sure if we 
have a guarantee that the complete stdout content will be delivered in a single 
`data` event or if the `connection://...` string could be split across multiple 
`data` events?

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


[Lldb-commits] [lldb] Fix a bug copying the stop hooks from the dummy target. (PR #129340)

2025-02-28 Thread Alex Langford via lldb-commits


@@ -26,10 +26,15 @@ def test_stop_hooks_step_out(self):
 self.step_out_test()
 
 def test_stop_hooks_after_expr(self):
-"""Test that a stop hook fires when hitting a breakpoint
-that runs an expression"""
+"""Test that a stop hook fires when hitting a breakpoint that
+runs an expression"""
 self.after_expr_test()
 
+def test_stop_hooks_before_and_after_creation(self):
+"""Test that if we add a stop hook in the dummy target, we can
+they don't collide with ones set directly in the target."""

bulbazord wrote:

I think you forgot a word? `we can they don't collide`

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


[Lldb-commits] [lldb] [LLDB][Telemetry]Define DebuggerTelemetryInfo and related methods (PR #127696)

2025-02-28 Thread Vy Nguyen via lldb-commits

https://github.com/oontvoo updated 
https://github.com/llvm/llvm-project/pull/127696

>From 24e9f78744f98ecf3ac01f1f719f1eac9b3479f0 Mon Sep 17 00:00:00 2001
From: Vy Nguyen 
Date: Tue, 18 Feb 2025 15:58:08 -0500
Subject: [PATCH 01/25] [LLDB][Telemetry]Define DebuggerTelemetryInfo and
 related methods

- This type of entry is used to collect data about the debugger startup/exit
- Tests will be added (They may need to be shell test with a "test-only" 
TelemetryManager plugin defined. I'm trying to figure out how to get that 
linked only when tests are running and not to the LLDB binary all the time.
---
 lldb/include/lldb/Core/Telemetry.h |  78 +++
 lldb/source/Core/Debugger.cpp  |  40 ++
 lldb/source/Core/Telemetry.cpp | 115 +
 3 files changed, 220 insertions(+), 13 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index b72556ecaf3c9..d6eec5dc687be 100644
--- a/lldb/include/lldb/Core/Telemetry.h
+++ b/lldb/include/lldb/Core/Telemetry.h
@@ -13,6 +13,7 @@
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Utility/StructuredData.h"
 #include "lldb/lldb-forward.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/JSON.h"
@@ -29,6 +30,9 @@ namespace telemetry {
 
 struct LLDBEntryKind : public ::llvm::telemetry::EntryKind {
   static const llvm::telemetry::KindType BaseInfo = 0b11000;
+  static const llvm::telemetry::KindType DebuggerInfo = 0b11001;
+  // There are other entries in between (added in separate PRs)
+  static const llvm::telemetry::KindType MiscInfo = 0b0;
 };
 
 /// Defines a convenient type for timestamp of various events.
@@ -56,6 +60,71 @@ struct LLDBBaseTelemetryInfo : public 
llvm::telemetry::TelemetryInfo {
   void serialize(llvm::telemetry::Serializer &serializer) const override;
 };
 
+/// Describes the exit status of a debugger.
+struct ExitDescription {
+  int exit_code;
+  std::string description;
+};
+
+struct DebuggerTelemetryInfo : public LLDBBaseTelemetryInfo {
+  std::string username;
+  std::string lldb_git_sha;
+  std::string lldb_path;
+  std::string cwd;
+  std::optional exit_desc;
+
+  DebuggerTelemetryInfo() = default;
+
+  // Provide a copy ctor because we may need to make a copy before
+  // sanitizing the data.
+  // (The sanitization might differ between different Destination classes).
+  DebuggerTelemetryInfo(const DebuggerTelemetryInfo &other) {
+username = other.username;
+lldb_git_sha = other.lldb_git_sha;
+lldb_path = other.lldb_path;
+cwd = other.cwd;
+  };
+
+  llvm::telemetry::KindType getKind() const override {
+return LLDBEntryKind::DebuggerInfo;
+  }
+
+  static bool classof(const llvm::telemetry::TelemetryInfo *T) {
+return T->getKind() == LLDBEntryKind::DebuggerInfo;
+  }
+
+  void serialize(llvm::telemetry::Serializer &serializer) const override;
+};
+
+/// The "catch-all" entry to store a set of non-standard data, such as
+/// error-messages, etc.
+struct MiscTelemetryInfo : public LLDBBaseTelemetryInfo {
+  /// If the event is/can be associated with a target entry,
+  /// this field contains that target's UUID.
+  ///  otherwise.
+  std::string target_uuid;
+
+  /// Set of key-value pairs for any optional (or impl-specific) data
+  std::map meta_data;
+
+  MiscTelemetryInfo() = default;
+
+  MiscTelemetryInfo(const MiscTelemetryInfo &other) {
+target_uuid = other.target_uuid;
+meta_data = other.meta_data;
+  }
+
+  llvm::telemetry::KindType getKind() const override {
+return LLDBEntryKind::MiscInfo;
+  }
+
+  static bool classof(const llvm::telemetry::TelemetryInfo *T) {
+return T->getKind() == LLDBEntryKind::MiscInfo;
+  }
+
+  void serialize(llvm::telemetry::Serializer &serializer) const override;
+};
+
 /// The base Telemetry manager instance in LLDB.
 /// This class declares additional instrumentation points
 /// applicable to LLDB.
@@ -63,6 +132,11 @@ class TelemetryManager : public llvm::telemetry::Manager {
 public:
   llvm::Error preDispatch(llvm::telemetry::TelemetryInfo *entry) override;
 
+  const llvm::telemetry::Config *getConfig();
+
+  void atDebuggerStartup(DebuggerTelemetryInfo *entry);
+  void atDebuggerExit(DebuggerTelemetryInfo *entry);
+
   virtual llvm::StringRef GetInstanceName() const = 0;
   static TelemetryManager *getInstance();
 
@@ -73,6 +147,10 @@ class TelemetryManager : public llvm::telemetry::Manager {
 
 private:
   std::unique_ptr m_config;
+  // Each debugger is assigned a unique ID (session_id).
+  // All TelemetryInfo entries emitted for the same debugger instance
+  // will get the same session_id.
+  llvm::DenseMap session_ids;
   static std::unique_ptr g_instance;
 };
 
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 18569e155b517..b458abc798a9e 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -62,6 +62,7 @@

[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)

2025-02-28 Thread Adrian Vogelsgesang via lldb-commits


@@ -137,53 +157,59 @@ export class LLDBDapDescriptorFactory
 
 const dbgOptions = {
   env: {
-...executable?.options?.env,
 ...configEnvironment,
 ...env,
   },
 };
-const dbgArgs = executable?.args ?? [];

vogelsgesang wrote:

There might be some downstream users who are actually bundling an `lldb-dap` 
binary into their re-packaged distribution of this VS-Code extension.

At least the commit message from 
https://github.com/llvm/llvm-project/commit/b5d4332286154838557a8ab5c76b794e85d946b3
 indicates, that there were some thoughts that downstream consumers might 
inject the lldb-dap path when using this extension as a library.

@JDevlieghere @walter-erquinigo are you aware if anyone is re-packaging this 
VS-Code extension together with an lldb-dap binary and might be relying on 
setting the lldb-dap path through the `package.json`?

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


[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)

2025-02-28 Thread Adrian Vogelsgesang via lldb-commits


@@ -137,53 +157,59 @@ export class LLDBDapDescriptorFactory
 
 const dbgOptions = {
   env: {
-...executable?.options?.env,
 ...configEnvironment,
 ...env,
   },
 };
-const dbgArgs = executable?.args ?? [];
+const dbgArgs = getDAPArguments(session);
 
-const serverMode = config.get('serverMode', false);
+const serverMode = config.get("serverMode", false);
 if (serverMode) {
-  const { host, port } = await this.startServer(dapPath, dbgArgs, 
dbgOptions);
+  const { host, port } = await this.startServer(
+dapPath,
+dbgArgs,
+dbgOptions,
+  );
   return new vscode.DebugAdapterServer(port, host);
 }
 
 return new vscode.DebugAdapterExecutable(dapPath, dbgArgs, dbgOptions);
   }
 
-  startServer(dapPath: string, args: string[], options: 
child_process.CommonSpawnOptions): Promise<{ host: string, port: number }> {
-if (this.server) return this.server;
+  startServer(
+dapPath: string,
+args: string[],
+options: child_process.CommonSpawnOptions,
+  ): Promise<{ host: string; port: number }> {
+if (this.server) {
+  return this.server;
+}
 
-this.server = new Promise(resolve => {
-  args.push(
-'--connection',
-'connect://localhost:0'
-  );
+this.server = new Promise((resolve) => {
+  args.push("--connection", "connect://localhost:0");
   const server = child_process.spawn(dapPath, args, options);
-  server.stdout!.setEncoding('utf8').once('data', (data: string) => {
+  server.stdout!.setEncoding("utf8").once("data", (data: string) => {
 const connection = /connection:\/\/\[([^\]]+)\]:(\d+)/.exec(data);
 if (connection) {
   const host = connection[1];
   const port = Number(connection[2]);
   resolve({ process: server, host, port });
 }
   });
-  server.on('exit', () => {
+  server.on("exit", () => {
 this.server = undefined;
-  })
+  });
 });
 return this.server;
   }
 
   /**
* Shows a message box when the debug adapter's path is not found
*/
-  static async showLLDBDapNotFoundMessage(path?: string) {
+  static async showLLDBDapNotFoundMessage(path?: string | undefined) {

vogelsgesang wrote:

Afaict, the `?` already marks `path` as potentially `undefined`? Why add the `| 
undefined` in addition?

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


[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)

2025-02-28 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)

2025-02-28 Thread Adrian Vogelsgesang via lldb-commits


@@ -137,53 +157,59 @@ export class LLDBDapDescriptorFactory
 
 const dbgOptions = {
   env: {
-...executable?.options?.env,
 ...configEnvironment,
 ...env,
   },
 };
-const dbgArgs = executable?.args ?? [];
+const dbgArgs = getDAPArguments(session);
 
-const serverMode = config.get('serverMode', false);
+const serverMode = config.get("serverMode", false);
 if (serverMode) {
-  const { host, port } = await this.startServer(dapPath, dbgArgs, 
dbgOptions);
+  const { host, port } = await this.startServer(
+dapPath,
+dbgArgs,
+dbgOptions,
+  );
   return new vscode.DebugAdapterServer(port, host);
 }
 
 return new vscode.DebugAdapterExecutable(dapPath, dbgArgs, dbgOptions);
   }
 
-  startServer(dapPath: string, args: string[], options: 
child_process.CommonSpawnOptions): Promise<{ host: string, port: number }> {
-if (this.server) return this.server;
+  startServer(
+dapPath: string,
+args: string[],
+options: child_process.CommonSpawnOptions,
+  ): Promise<{ host: string; port: number }> {
+if (this.server) {
+  return this.server;
+}

vogelsgesang wrote:

This does not interact correctly with the new 
`session.configuration.debugAdapterArgs` settings. We might be reusing a 
lldb-dap instance which was launched with different arguments, effectively 
ignoring the `debugAdapterArgs` specified in the launch config.

We already have the same issue with the `dapPath`, where we might end up 
reusing the wrong lldb-dap binary (see my other comment in 
https://github.com/llvm/llvm-project/pull/128957#discussion_r1976226941).

But I think this commit is unfortunately further into the direction of 
incorrectly caching the server processes. Not sure how we want to proceed 
here...

WDYT, @ashgti and @JDevlieghere ? Is it fine merging this PR as is? Or should 
we first fix our logic on when to reuse the server and when not?

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


[Lldb-commits] [lldb] [lldb-dap] Adding server mode support to lldb-dap VSCode extension. (PR #128957)

2025-02-28 Thread John Harrison via lldb-commits


@@ -115,41 +123,71 @@ export class LLDBDapDescriptorFactory
 }
 const configEnvironment =
   config.get<{ [key: string]: string }>("environment") || {};
-const dapPath = await getDAPExecutable(session);
+const dapPath = (await getDAPExecutable(session)) ?? executable?.command;
+
+if (!dapPath) {
+  LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage();
+  return undefined;
+}
+
+if (!(await isExecutable(dapPath))) {
+  LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
+  return;
+}
+
 const dbgOptions = {
   env: {
 ...executable?.options?.env,
 ...configEnvironment,
 ...env,
   },
 };
-if (dapPath) {
-  if (!(await isExecutable(dapPath))) {
-LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(dapPath, [], dbgOptions);
-} else if (executable) {
-  if (!(await isExecutable(executable.command))) {
-
LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(executable.command);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(
-executable.command,
-executable.args,
-dbgOptions,
-  );
+const dbgArgs = executable?.args ?? [];
+
+const serverMode = config.get('serverMode', false);
+if (serverMode) {
+  const { host, port } = await this.startServer(dapPath, dbgArgs, 
dbgOptions);
+  return new vscode.DebugAdapterServer(port, host);
 }
-return undefined;
+
+return new vscode.DebugAdapterExecutable(dapPath, dbgArgs, dbgOptions);
+  }
+
+  startServer(dapPath: string, args: string[], options: 
child_process.CommonSpawnOptions): Promise<{ host: string, port: number }> {
+if (this.server) return this.server;

ashgti wrote:

I think a simple solution could be to just ask the user if we can kill the 
running server or if they want to reuse the existing server. I don't expect 
that users will be changing lldb-dap paths often, I hope.

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


[Lldb-commits] [lldb] [lldb-dap] Updating the logging of lldb-dap to use existing LLDBLog. (PR #129294)

2025-02-28 Thread John Harrison via lldb-commits

https://github.com/ashgti updated 
https://github.com/llvm/llvm-project/pull/129294

>From 8d466e5c4b1b6913e788fd11d46689af8f0b8eec Mon Sep 17 00:00:00 2001
From: John Harrison 
Date: Thu, 27 Feb 2025 15:33:51 -0800
Subject: [PATCH] [lldb-dap] Updating the logging of lldb-dap to use existing
 LLDBLog.h helpers.

This only creates the basic types need to start using the LLDBLog.h helpers.
Today, logging is handling by a simple `std::ofstream *` for handling logging.
LLDBLog.h can help improve logging by adding new categories of logs and give us 
additional formatting support for log messages.
---
 lldb/tools/lldb-dap/CMakeLists.txt  |  1 +
 lldb/tools/lldb-dap/DAP.cpp | 62 
 lldb/tools/lldb-dap/DAP.h   | 11 ++---
 lldb/tools/lldb-dap/DAPLog.cpp  | 22 +
 lldb/tools/lldb-dap/DAPLog.h| 34 +
 lldb/tools/lldb-dap/EventHelper.cpp | 17 ---
 lldb/tools/lldb-dap/IOStream.cpp| 19 
 lldb/tools/lldb-dap/IOStream.h  |  7 ++-
 lldb/tools/lldb-dap/lldb-dap.cpp| 75 -
 9 files changed, 146 insertions(+), 102 deletions(-)
 create mode 100644 lldb/tools/lldb-dap/DAPLog.cpp
 create mode 100644 lldb/tools/lldb-dap/DAPLog.h

diff --git a/lldb/tools/lldb-dap/CMakeLists.txt 
b/lldb/tools/lldb-dap/CMakeLists.txt
index 8b3c520ec4360..d9f09f6d022ed 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -23,6 +23,7 @@ add_lldb_tool(lldb-dap
   Breakpoint.cpp
   BreakpointBase.cpp
   DAP.cpp
+  DAPLog.cpp
   EventHelper.cpp
   ExceptionBreakpoint.cpp
   FifoFiles.cpp
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 53c514b790f38..81f5205d4f6bd 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 
 #include "DAP.h"
+#include "DAPLog.h"
 #include "Handler/ResponseHandler.h"
 #include "JSONUtils.h"
 #include "LLDBUtils.h"
@@ -19,6 +20,7 @@
 #include "lldb/API/SBProcess.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/Utility/IOObject.h"
+#include "lldb/Utility/Log.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-enumerations.h"
@@ -50,6 +52,7 @@
 #endif
 
 using namespace lldb_dap;
+using namespace lldb_private;
 
 namespace {
 #ifdef _WIN32
@@ -61,13 +64,12 @@ const char DEV_NULL[] = "/dev/null";
 
 namespace lldb_dap {
 
-DAP::DAP(std::string name, llvm::StringRef path, std::ofstream *log,
- lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
+DAP::DAP(std::string name, llvm::StringRef path, lldb::IOObjectSP input,
+ lldb::IOObjectSP output, ReplMode repl_mode,
  std::vector pre_init_commands)
-: name(std::move(name)), debug_adapter_path(path), log(log),
-  input(std::move(input)), output(std::move(output)),
-  broadcaster("lldb-dap"), exception_breakpoints(),
-  pre_init_commands(std::move(pre_init_commands)),
+: name(std::move(name)), debug_adapter_path(path), input(std::move(input)),
+  output(std::move(output)), broadcaster("lldb-dap"),
+  exception_breakpoints(), pre_init_commands(std::move(pre_init_commands)),
   focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), 
is_attach(false),
   enable_auto_variable_summaries(false),
   enable_synthetic_child_debugging(false),
@@ -245,6 +247,8 @@ void DAP::SendJSON(const std::string &json_str) {
   output.write_full(llvm::utostr(json_str.size()));
   output.write_full("\r\n\r\n");
   output.write_full(json_str);
+
+  LLDB_LOG(GetLog(DAPLog::Transport), "{0} <-- {1}", name, json_str);
 }
 
 // Serialize the JSON value into a string and send the JSON packet to
@@ -256,15 +260,6 @@ void DAP::SendJSON(const llvm::json::Value &json) {
   static std::mutex mutex;
   std::lock_guard locker(mutex);
   SendJSON(json_str);
-
-  if (log) {
-auto now = std::chrono::duration(
-std::chrono::system_clock::now().time_since_epoch());
-*log << llvm::formatv("{0:f9} {1} <-- ", now.count(), name).str()
- << std::endl
- << "Content-Length: " << json_str.size() << "\r\n\r\n"
- << llvm::formatv("{0:2}", json).str() << std::endl;
-  }
 }
 
 // Read a JSON packet from the "in" stream.
@@ -273,28 +268,22 @@ std::string DAP::ReadJSON() {
   std::string json_str;
   int length;
 
-  if (!input.read_expected(log, "Content-Length: "))
+  if (!input.read_expected("Content-Length: "))
 return json_str;
 
-  if (!input.read_line(log, length_str))
+  if (!input.read_line(length_str))
 return json_str;
 
   if (!llvm::to_integer(length_str, length))
 return json_str;
 
-  if (!input.read_expected(log, "\r\n"))
+  if (!input.read_expected("\r\n"))
 return json_str;
 
-  if (!input.read_full(log, length, json_str))
+  if (!input.read_full(length, json_str))
 return json_str;
 
-  if (log) {
-auto now = std::chrono::duration(
- 

[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments (PR #129262)

2025-02-28 Thread Matthew Bastien via lldb-commits

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

Added a new setting called lldb-dap.arguments and a debug configuration 
attribute called debugAdapterArgs that can be used to set the arguments used to 
launch the debug adapter. Right now this is mostly useful for debugging 
purposes to add the `--wait-for-debugger` option to lldb-dap.

I've also removed the check for the `executable` argument in 
`LLDBDapDescriptorFactory.createDebugAdapterDescriptor()`. This argument is 
only set by VS Code when the debug adapter executable properties are set in the 
`package.json`. The LLDB DAP extension does not currently do this (and I don't 
think it ever will). So, this makes the debug adapter descriptor factory a 
little easier to read.

>From 8926756d800b9ecd171b6d645a459b01342e9458 Mon Sep 17 00:00:00 2001
From: Matthew Bastien 
Date: Fri, 28 Feb 2025 11:08:25 -0500
Subject: [PATCH] allow providing debug adapter arguments

---
 lldb/tools/lldb-dap/package.json  | 23 +
 .../lldb-dap/src-ts/debug-adapter-factory.ts  | 48 +++
 2 files changed, 50 insertions(+), 21 deletions(-)

diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 31d808eda4c35..0859b6e388a4e 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -75,6 +75,15 @@
   "type": "string",
   "description": "The path to the lldb-dap binary."
 },
+"lldb-dap.arguments": {
+  "scope": "resource",
+  "type": "array",
+  "default": [],
+  "items": {
+"type": "string"
+  },
+  "description": "The arguments provided to the lldb-dap process."
+},
 "lldb-dap.log-path": {
   "scope": "resource",
   "type": "string",
@@ -156,6 +165,13 @@
 "type": "string",
 "markdownDescription": "The absolute path to the LLDB debug 
adapter executable to use."
   },
+  "debugAdapterArgs": {
+"type": "array",
+"items": {
+  "type": "string"
+},
+"markdownDescription": "The list of arguments used to launch 
the debug adapter executable."
+  },
   "program": {
 "type": "string",
 "description": "Path to the program to debug."
@@ -346,6 +362,13 @@
 "type": "string",
 "markdownDescription": "The absolute path to the LLDB debug 
adapter executable to use."
   },
+  "debugAdapterArgs": {
+"type": "array",
+"items": {
+  "type": "string"
+},
+"markdownDescription": "The list of arguments used to launch 
the debug adapter executable."
+  },
   "program": {
 "type": "string",
 "description": "Path to the program to attach to."
diff --git a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts 
b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
index 36107336ebc4d..ea7b4ce97ac1d 100644
--- a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
+++ b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
@@ -92,6 +92,21 @@ async function getDAPExecutable(
   return undefined;
 }
 
+function getDAPArguments(session: vscode.DebugSession): string[] {
+  // Check the debug configuration for arguments first
+  const debugConfigArgs = session.configuration.debugAdapterArgs;
+  if (
+Array.isArray(debugConfigArgs) &&
+debugConfigArgs.findIndex((entry) => typeof entry !== "string") === -1
+  ) {
+return debugConfigArgs;
+  }
+  // Fall back on the workspace configuration
+  return vscode.workspace
+.getConfiguration("lldb-dap")
+.get("arguments", []);
+}
+
 /**
  * This class defines a factory used to find the lldb-dap binary to use
  * depending on the session configuration.
@@ -101,7 +116,7 @@ export class LLDBDapDescriptorFactory
 {
   async createDebugAdapterDescriptor(
 session: vscode.DebugSession,
-executable: vscode.DebugAdapterExecutable | undefined,
+_executable: vscode.DebugAdapterExecutable | undefined,
   ): Promise {
 const config = vscode.workspace.getConfiguration(
   "lldb-dap",
@@ -116,40 +131,31 @@ export class LLDBDapDescriptorFactory
 const configEnvironment =
   config.get<{ [key: string]: string }>("environment") || {};
 const dapPath = await getDAPExecutable(session);
+const dapArgs = getDAPArguments(session);
 const dbgOptions = {
   env: {
-...executable?.options?.env,
 ...configEnvironment,
 ...env,
   },
 };
-if (dapPath) {
-  if (!(await isExecutable(dapPath))) {
-LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(dapPath, [], dbgO

[Lldb-commits] [lldb] [lldb-dap] Adding server mode support to lldb-dap VSCode extension. (PR #128957)

2025-02-28 Thread John Harrison via lldb-commits


@@ -115,41 +123,71 @@ export class LLDBDapDescriptorFactory
 }
 const configEnvironment =
   config.get<{ [key: string]: string }>("environment") || {};
-const dapPath = await getDAPExecutable(session);
+const dapPath = (await getDAPExecutable(session)) ?? executable?.command;
+
+if (!dapPath) {
+  LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage();
+  return undefined;
+}
+
+if (!(await isExecutable(dapPath))) {
+  LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
+  return;
+}
+
 const dbgOptions = {
   env: {
 ...executable?.options?.env,
 ...configEnvironment,
 ...env,
   },
 };
-if (dapPath) {
-  if (!(await isExecutable(dapPath))) {
-LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(dapPath, [], dbgOptions);
-} else if (executable) {
-  if (!(await isExecutable(executable.command))) {
-
LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(executable.command);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(
-executable.command,
-executable.args,
-dbgOptions,
-  );
+const dbgArgs = executable?.args ?? [];
+
+const serverMode = config.get('serverMode', false);
+if (serverMode) {
+  const { host, port } = await this.startServer(dapPath, dbgArgs, 
dbgOptions);
+  return new vscode.DebugAdapterServer(port, host);
 }
-return undefined;
+
+return new vscode.DebugAdapterExecutable(dapPath, dbgArgs, dbgOptions);
+  }
+
+  startServer(dapPath: string, args: string[], options: 
child_process.CommonSpawnOptions): Promise<{ host: string, port: number }> {
+if (this.server) return this.server;
+
+this.server = new Promise(resolve => {
+  args.push(
+'--connection',
+'connect://localhost:0'
+  );
+  const server = child_process.spawn(dapPath, args, options);
+  server.stdout!.setEncoding('utf8').once('data', (data: string) => {

ashgti wrote:

A single 'data' event usually corresponds to a single 'write' event which 
https://github.com/llvm/llvm-project/blob/cef6dbbe544ff4c49fca65cdc50df783d8c39c28/lldb/tools/lldb-dap/lldb-dap.cpp#L298
 should correspond to one call.

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


[Lldb-commits] [lldb] [lldb-dap] Adding server mode support to lldb-dap VSCode extension. (PR #128957)

2025-02-28 Thread John Harrison via lldb-commits

ashgti wrote:

> Random question: what happens when the server crashes? Do you get a popup in 
> the UI telling you?

If the server is killed while the debug session is running then the debug 
session stops. This is the same behavior as today when running not in server 
mode.

If the server crashes between debug sessions a new one will be spawned on 
demand. I don't currently alert the user if it shuts down or is killed and I 
don't have an idle timeout or anything. The server is running under the 
extension host process and VS Code uses one extension host process per window. 
That means the server will be around until the window is closed or the user 
quits VS Code.

As far as server management goes, I don't have any explicit logic for that at 
the moment, but we could add it in the future. 

Some thoughts:

* The server could shut itself down if the process gets a low memory warning 
and there are no active clients.
* The server could have an idle timeout and shutdown if there are not active 
clients after some configurable period.
* The extension could alert the user to unexpected crashes or exits.
* The extension could have commands to manually start / stop the server.

At the moment though, I am keeping this relatively simple.

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


[Lldb-commits] [lldb] [lldb] Add terminfo dependency for ncurses support (PR #126810)

2025-02-28 Thread David Spickett via lldb-commits

DavidSpickett wrote:

If this and the follow up are working well, consider backporting them to 20.x.

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


[Lldb-commits] [lldb] [lldb-dap] Implement `runInTerminal` for Windows (PR #121269)

2025-02-28 Thread Hu Jialun via lldb-commits

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


[Lldb-commits] [lldb] [LLDB][Telemetry]Define DebuggerTelemetryInfo and related methods (PR #127696)

2025-02-28 Thread Pavel Labath via lldb-commits


@@ -987,6 +998,16 @@ void Debugger::Clear() {
   // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp);
   // static void Debugger::Terminate();
   llvm::call_once(m_clear_once, [this]() {
+lldb_private::telemetry::ScopedDispatcher<
+lldb_private::telemetry::DebuggerInfo>

labath wrote:

```suggestion
telemetry::ScopedDispatcher
```

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


[Lldb-commits] [lldb] [LLDB][Telemetry]Define DebuggerTelemetryInfo and related methods (PR #127696)

2025-02-28 Thread Pavel Labath via lldb-commits


@@ -18,25 +18,35 @@
 
 namespace lldb_private {
 
-struct FakeTelemetryInfo : public llvm::telemetry::TelemetryInfo {
+struct FakeTelemetryInfo : public telemetry::LLDBBaseTelemetryInfo {
   std::string msg;
+  int num;
+
+  ::llvm::telemetry::KindType getKind() const override { return 0b1; }
 };
 
 class TestDestination : public llvm::telemetry::Destination {
 public:
-  TestDestination(std::vector *entries)
+  TestDestination(std::vector *entries)

labath wrote:

```suggestion
  explicit 
TestDestination(std::vector> 
&entries)
```

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


[Lldb-commits] [lldb] [LLDB][Telemetry]Define DebuggerTelemetryInfo and related methods (PR #127696)

2025-02-28 Thread Pavel Labath via lldb-commits


@@ -761,7 +765,14 @@ void Debugger::InstanceInitialize() {
 
 DebuggerSP Debugger::CreateInstance(lldb::LogOutputCallback log_callback,
 void *baton) {
+  lldb_private::telemetry::ScopedDispatcher<
+  lldb_private::telemetry::DebuggerInfo>
+  helper([](lldb_private::telemetry::DebuggerInfo *entry) {
+entry->lldb_version = lldb_private::GetVersion();
+  });
   DebuggerSP debugger_sp(new Debugger(log_callback, baton));
+  helper.SetDebugger(debugger_sp.get());

labath wrote:

This is definitely better, but lambdas tend to add some boilerplate of their 
own. They may be useful in some cases (if you need to set some field at the 
very end) but I think that in many cases (this one included) we could just set 
the field directly, so I want to float this idea: I think this would be shorter 
if we had the dispatcher object expose the telemetry entry it is managing 
directly:
```suggestion
  telemetry::ScopedDispatcher helper;
  DebuggerSP debugger_sp(new Debugger(log_callback, baton));
  if (telemetry::DebuggerInfo *info = helper.GetEntry()) {// returns NULL if 
telemetry is disabled
info->debugger = debugger_sp.get();
info->lldb_version = lldb_private::GetVersion();
  }
```

(and if we do need a callback, I don't see a reason why this couldn't coexist 
with that)

Any thoughts @JDevlieghere ?

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


[Lldb-commits] [lldb] [LLDB][Telemetry]Define DebuggerTelemetryInfo and related methods (PR #127696)

2025-02-28 Thread Vy Nguyen via lldb-commits

https://github.com/oontvoo updated 
https://github.com/llvm/llvm-project/pull/127696

>From 24e9f78744f98ecf3ac01f1f719f1eac9b3479f0 Mon Sep 17 00:00:00 2001
From: Vy Nguyen 
Date: Tue, 18 Feb 2025 15:58:08 -0500
Subject: [PATCH 01/23] [LLDB][Telemetry]Define DebuggerTelemetryInfo and
 related methods

- This type of entry is used to collect data about the debugger startup/exit
- Tests will be added (They may need to be shell test with a "test-only" 
TelemetryManager plugin defined. I'm trying to figure out how to get that 
linked only when tests are running and not to the LLDB binary all the time.
---
 lldb/include/lldb/Core/Telemetry.h |  78 +++
 lldb/source/Core/Debugger.cpp  |  40 ++
 lldb/source/Core/Telemetry.cpp | 115 +
 3 files changed, 220 insertions(+), 13 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index b72556ecaf3c9..d6eec5dc687be 100644
--- a/lldb/include/lldb/Core/Telemetry.h
+++ b/lldb/include/lldb/Core/Telemetry.h
@@ -13,6 +13,7 @@
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Utility/StructuredData.h"
 #include "lldb/lldb-forward.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/JSON.h"
@@ -29,6 +30,9 @@ namespace telemetry {
 
 struct LLDBEntryKind : public ::llvm::telemetry::EntryKind {
   static const llvm::telemetry::KindType BaseInfo = 0b11000;
+  static const llvm::telemetry::KindType DebuggerInfo = 0b11001;
+  // There are other entries in between (added in separate PRs)
+  static const llvm::telemetry::KindType MiscInfo = 0b0;
 };
 
 /// Defines a convenient type for timestamp of various events.
@@ -56,6 +60,71 @@ struct LLDBBaseTelemetryInfo : public 
llvm::telemetry::TelemetryInfo {
   void serialize(llvm::telemetry::Serializer &serializer) const override;
 };
 
+/// Describes the exit status of a debugger.
+struct ExitDescription {
+  int exit_code;
+  std::string description;
+};
+
+struct DebuggerTelemetryInfo : public LLDBBaseTelemetryInfo {
+  std::string username;
+  std::string lldb_git_sha;
+  std::string lldb_path;
+  std::string cwd;
+  std::optional exit_desc;
+
+  DebuggerTelemetryInfo() = default;
+
+  // Provide a copy ctor because we may need to make a copy before
+  // sanitizing the data.
+  // (The sanitization might differ between different Destination classes).
+  DebuggerTelemetryInfo(const DebuggerTelemetryInfo &other) {
+username = other.username;
+lldb_git_sha = other.lldb_git_sha;
+lldb_path = other.lldb_path;
+cwd = other.cwd;
+  };
+
+  llvm::telemetry::KindType getKind() const override {
+return LLDBEntryKind::DebuggerInfo;
+  }
+
+  static bool classof(const llvm::telemetry::TelemetryInfo *T) {
+return T->getKind() == LLDBEntryKind::DebuggerInfo;
+  }
+
+  void serialize(llvm::telemetry::Serializer &serializer) const override;
+};
+
+/// The "catch-all" entry to store a set of non-standard data, such as
+/// error-messages, etc.
+struct MiscTelemetryInfo : public LLDBBaseTelemetryInfo {
+  /// If the event is/can be associated with a target entry,
+  /// this field contains that target's UUID.
+  ///  otherwise.
+  std::string target_uuid;
+
+  /// Set of key-value pairs for any optional (or impl-specific) data
+  std::map meta_data;
+
+  MiscTelemetryInfo() = default;
+
+  MiscTelemetryInfo(const MiscTelemetryInfo &other) {
+target_uuid = other.target_uuid;
+meta_data = other.meta_data;
+  }
+
+  llvm::telemetry::KindType getKind() const override {
+return LLDBEntryKind::MiscInfo;
+  }
+
+  static bool classof(const llvm::telemetry::TelemetryInfo *T) {
+return T->getKind() == LLDBEntryKind::MiscInfo;
+  }
+
+  void serialize(llvm::telemetry::Serializer &serializer) const override;
+};
+
 /// The base Telemetry manager instance in LLDB.
 /// This class declares additional instrumentation points
 /// applicable to LLDB.
@@ -63,6 +132,11 @@ class TelemetryManager : public llvm::telemetry::Manager {
 public:
   llvm::Error preDispatch(llvm::telemetry::TelemetryInfo *entry) override;
 
+  const llvm::telemetry::Config *getConfig();
+
+  void atDebuggerStartup(DebuggerTelemetryInfo *entry);
+  void atDebuggerExit(DebuggerTelemetryInfo *entry);
+
   virtual llvm::StringRef GetInstanceName() const = 0;
   static TelemetryManager *getInstance();
 
@@ -73,6 +147,10 @@ class TelemetryManager : public llvm::telemetry::Manager {
 
 private:
   std::unique_ptr m_config;
+  // Each debugger is assigned a unique ID (session_id).
+  // All TelemetryInfo entries emitted for the same debugger instance
+  // will get the same session_id.
+  llvm::DenseMap session_ids;
   static std::unique_ptr g_instance;
 };
 
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 18569e155b517..b458abc798a9e 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -62,6 +62,7 @@

[Lldb-commits] [lldb] [LLDB][Telemetry]Define DebuggerTelemetryInfo and related methods (PR #127696)

2025-02-28 Thread Vy Nguyen via lldb-commits


@@ -56,13 +58,38 @@ struct LLDBBaseTelemetryInfo : public 
llvm::telemetry::TelemetryInfo {
   void serialize(llvm::telemetry::Serializer &serializer) const override;
 };
 
+/// Describes the exit status of a debugger.
+struct ExitDescription {
+  int exit_code;
+  std::string description;
+};
+
+struct DebuggerInfo : public LLDBBaseTelemetryInfo {

oontvoo wrote:

I definitely need this class to be extensible. 
Can you clarify what changes are needed to allow this? 

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


[Lldb-commits] [lldb] [LLDB][Telemetry]Define DebuggerTelemetryInfo and related methods (PR #127696)

2025-02-28 Thread Vy Nguyen via lldb-commits

oontvoo wrote:

@labath 
> IOW, can we drop the exit_desc field from this struct?

Well, we need a way to distinguish the start and the exit entries 
How about just keeping `exit_code` (which is set to zero)

> I still think it's important to have a simple and succinct way to check 
> whether telemetry is "actually" enabled at a given moment

We can have a `static TelemetryManager::TelemetryCurrentEnabled()` which does 
the check.



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


[Lldb-commits] [lldb] [LLDB][Telemetry]Define DebuggerTelemetryInfo and related methods (PR #127696)

2025-02-28 Thread Pavel Labath via lldb-commits

labath wrote:

> @labath
> 
> > IOW, can we drop the exit_desc field from this struct?
> 
> Well, we need a way to distinguish the start and the exit entries How about 
> just keeping `exit_code` (which is set to zero)

You could distinguish them with a bool or enum field. I don't think an 
exit_code field makes sense if it's always going to be set to zero. I think it 
would make sense if you set it to `GetCommandInterpreter().GetQuitExitCode()`.

> 
> > I still think it's important to have a simple and succinct way to check 
> > whether telemetry is "actually" enabled at a given moment
> 
> We can have a `static TelemetryManager::TelemetryCurrentEnabled()` which does 
> the check.

Maybe. Or maybe `TelemetryManager::GetInstanceIfEnabled` (not necessarily with 
that name) so you don't have to follow this up with a call to GetInstance(). 
Let's see how the code develops...

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


[Lldb-commits] [lldb] [LLDB][Telemetry]Define DebuggerTelemetryInfo and related methods (PR #127696)

2025-02-28 Thread Vy Nguyen via lldb-commits


@@ -73,9 +100,50 @@ class TelemetryManager : public llvm::telemetry::Manager {
 
 private:
   std::unique_ptr m_config;
+  // Each instance of a TelemetryManager is assigned a unique ID.
+  const std::string m_id;

oontvoo wrote:

> One reason for storing it in the UUID form might be if we think that someone 
> could be interested in storing/transmitting the UUID in a binary form

This is the TelemetryManager - it is never transmitted or serialised anywhere. 
So why does compactness matter?

If you mean storing the id as UUID in the `TelemetryInfo` object, then we'd 
need to update the llvm base interface. However, the reason the id was a string 
in the base interface was because people wanted flexibility in what the id 
could be in each implementation.
Also the downside of storing it as UUID object is that you may have different 
`telemetry::Serializer` objects generating different values for the same UUID 
(ie.,different separators?). That's potentially problematic because ultimately, 
the point of this field is for grouping entries from the same session. We need 
the key to be identical across entries and not  "accidentally" differ because 
of serialisation methods.



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


[Lldb-commits] [lldb] [LLDB][Telemetry]Define DebuggerTelemetryInfo and related methods (PR #127696)

2025-02-28 Thread Pavel Labath via lldb-commits


@@ -56,13 +58,38 @@ struct LLDBBaseTelemetryInfo : public 
llvm::telemetry::TelemetryInfo {
   void serialize(llvm::telemetry::Serializer &serializer) const override;
 };
 
+/// Describes the exit status of a debugger.
+struct ExitDescription {
+  int exit_code;
+  std::string description;
+};
+
+struct DebuggerInfo : public LLDBBaseTelemetryInfo {

labath wrote:

`DebuggerInfo::classof(subclass_of_debugger_info)` should return true, which I 
guess means changing the implementation to something like `return 
T->getKind()&LLDBEntryKind::DebuggerInfo == LLDBEntryKind::DebuggerInfo`

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


[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)

2025-02-28 Thread Matthew Bastien via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)

2025-02-28 Thread Matthew Bastien via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)

2025-02-28 Thread Jonas Devlieghere via lldb-commits


@@ -75,6 +75,15 @@
   "type": "string",
   "description": "The path to the lldb-dap binary."
 },
+"lldb-dap.arguments": {
+  "scope": "resource",
+  "type": "array",
+  "default": [],
+  "items": {
+"type": "string"
+  },
+  "description": "The arguments provided to the lldb-dap process."

JDevlieghere wrote:

Any reason the description here is different from the ones below? Also, should 
the description say "The list of _additional_ arguments", as the extension 
itself might specify others (e.g. with #128957  if you enable server mode)? 

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


[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)

2025-02-28 Thread Matthew Bastien via lldb-commits

https://github.com/matthewbastien updated 
https://github.com/llvm/llvm-project/pull/129262

>From 8926756d800b9ecd171b6d645a459b01342e9458 Mon Sep 17 00:00:00 2001
From: Matthew Bastien 
Date: Fri, 28 Feb 2025 11:08:25 -0500
Subject: [PATCH 1/2] allow providing debug adapter arguments

---
 lldb/tools/lldb-dap/package.json  | 23 +
 .../lldb-dap/src-ts/debug-adapter-factory.ts  | 48 +++
 2 files changed, 50 insertions(+), 21 deletions(-)

diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 31d808eda4c35..0859b6e388a4e 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -75,6 +75,15 @@
   "type": "string",
   "description": "The path to the lldb-dap binary."
 },
+"lldb-dap.arguments": {
+  "scope": "resource",
+  "type": "array",
+  "default": [],
+  "items": {
+"type": "string"
+  },
+  "description": "The arguments provided to the lldb-dap process."
+},
 "lldb-dap.log-path": {
   "scope": "resource",
   "type": "string",
@@ -156,6 +165,13 @@
 "type": "string",
 "markdownDescription": "The absolute path to the LLDB debug 
adapter executable to use."
   },
+  "debugAdapterArgs": {
+"type": "array",
+"items": {
+  "type": "string"
+},
+"markdownDescription": "The list of arguments used to launch 
the debug adapter executable."
+  },
   "program": {
 "type": "string",
 "description": "Path to the program to debug."
@@ -346,6 +362,13 @@
 "type": "string",
 "markdownDescription": "The absolute path to the LLDB debug 
adapter executable to use."
   },
+  "debugAdapterArgs": {
+"type": "array",
+"items": {
+  "type": "string"
+},
+"markdownDescription": "The list of arguments used to launch 
the debug adapter executable."
+  },
   "program": {
 "type": "string",
 "description": "Path to the program to attach to."
diff --git a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts 
b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
index 36107336ebc4d..ea7b4ce97ac1d 100644
--- a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
+++ b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
@@ -92,6 +92,21 @@ async function getDAPExecutable(
   return undefined;
 }
 
+function getDAPArguments(session: vscode.DebugSession): string[] {
+  // Check the debug configuration for arguments first
+  const debugConfigArgs = session.configuration.debugAdapterArgs;
+  if (
+Array.isArray(debugConfigArgs) &&
+debugConfigArgs.findIndex((entry) => typeof entry !== "string") === -1
+  ) {
+return debugConfigArgs;
+  }
+  // Fall back on the workspace configuration
+  return vscode.workspace
+.getConfiguration("lldb-dap")
+.get("arguments", []);
+}
+
 /**
  * This class defines a factory used to find the lldb-dap binary to use
  * depending on the session configuration.
@@ -101,7 +116,7 @@ export class LLDBDapDescriptorFactory
 {
   async createDebugAdapterDescriptor(
 session: vscode.DebugSession,
-executable: vscode.DebugAdapterExecutable | undefined,
+_executable: vscode.DebugAdapterExecutable | undefined,
   ): Promise {
 const config = vscode.workspace.getConfiguration(
   "lldb-dap",
@@ -116,40 +131,31 @@ export class LLDBDapDescriptorFactory
 const configEnvironment =
   config.get<{ [key: string]: string }>("environment") || {};
 const dapPath = await getDAPExecutable(session);
+const dapArgs = getDAPArguments(session);
 const dbgOptions = {
   env: {
-...executable?.options?.env,
 ...configEnvironment,
 ...env,
   },
 };
-if (dapPath) {
-  if (!(await isExecutable(dapPath))) {
-LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(dapPath, [], dbgOptions);
-} else if (executable) {
-  if (!(await isExecutable(executable.command))) {
-
LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(executable.command);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(
-executable.command,
-executable.args,
-dbgOptions,
-  );
+if (dapPath === undefined || !(await isExecutable(dapPath))) {
+  LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
+  return undefined;
 }
-return undefined;
+return new vscode.DebugAdapterExecutable(dapPath, dapArgs, dbgOptions);
   }
 
   /**
* Shows a message box when the debug adapter's pat

[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)

2025-02-28 Thread Matthew Bastien via lldb-commits

https://github.com/matthewbastien updated 
https://github.com/llvm/llvm-project/pull/129262

>From 8926756d800b9ecd171b6d645a459b01342e9458 Mon Sep 17 00:00:00 2001
From: Matthew Bastien 
Date: Fri, 28 Feb 2025 11:08:25 -0500
Subject: [PATCH 1/2] allow providing debug adapter arguments

---
 lldb/tools/lldb-dap/package.json  | 23 +
 .../lldb-dap/src-ts/debug-adapter-factory.ts  | 48 +++
 2 files changed, 50 insertions(+), 21 deletions(-)

diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 31d808eda4c35..0859b6e388a4e 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -75,6 +75,15 @@
   "type": "string",
   "description": "The path to the lldb-dap binary."
 },
+"lldb-dap.arguments": {
+  "scope": "resource",
+  "type": "array",
+  "default": [],
+  "items": {
+"type": "string"
+  },
+  "description": "The arguments provided to the lldb-dap process."
+},
 "lldb-dap.log-path": {
   "scope": "resource",
   "type": "string",
@@ -156,6 +165,13 @@
 "type": "string",
 "markdownDescription": "The absolute path to the LLDB debug 
adapter executable to use."
   },
+  "debugAdapterArgs": {
+"type": "array",
+"items": {
+  "type": "string"
+},
+"markdownDescription": "The list of arguments used to launch 
the debug adapter executable."
+  },
   "program": {
 "type": "string",
 "description": "Path to the program to debug."
@@ -346,6 +362,13 @@
 "type": "string",
 "markdownDescription": "The absolute path to the LLDB debug 
adapter executable to use."
   },
+  "debugAdapterArgs": {
+"type": "array",
+"items": {
+  "type": "string"
+},
+"markdownDescription": "The list of arguments used to launch 
the debug adapter executable."
+  },
   "program": {
 "type": "string",
 "description": "Path to the program to attach to."
diff --git a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts 
b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
index 36107336ebc4d..ea7b4ce97ac1d 100644
--- a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
+++ b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
@@ -92,6 +92,21 @@ async function getDAPExecutable(
   return undefined;
 }
 
+function getDAPArguments(session: vscode.DebugSession): string[] {
+  // Check the debug configuration for arguments first
+  const debugConfigArgs = session.configuration.debugAdapterArgs;
+  if (
+Array.isArray(debugConfigArgs) &&
+debugConfigArgs.findIndex((entry) => typeof entry !== "string") === -1
+  ) {
+return debugConfigArgs;
+  }
+  // Fall back on the workspace configuration
+  return vscode.workspace
+.getConfiguration("lldb-dap")
+.get("arguments", []);
+}
+
 /**
  * This class defines a factory used to find the lldb-dap binary to use
  * depending on the session configuration.
@@ -101,7 +116,7 @@ export class LLDBDapDescriptorFactory
 {
   async createDebugAdapterDescriptor(
 session: vscode.DebugSession,
-executable: vscode.DebugAdapterExecutable | undefined,
+_executable: vscode.DebugAdapterExecutable | undefined,
   ): Promise {
 const config = vscode.workspace.getConfiguration(
   "lldb-dap",
@@ -116,40 +131,31 @@ export class LLDBDapDescriptorFactory
 const configEnvironment =
   config.get<{ [key: string]: string }>("environment") || {};
 const dapPath = await getDAPExecutable(session);
+const dapArgs = getDAPArguments(session);
 const dbgOptions = {
   env: {
-...executable?.options?.env,
 ...configEnvironment,
 ...env,
   },
 };
-if (dapPath) {
-  if (!(await isExecutable(dapPath))) {
-LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(dapPath, [], dbgOptions);
-} else if (executable) {
-  if (!(await isExecutable(executable.command))) {
-
LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(executable.command);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(
-executable.command,
-executable.args,
-dbgOptions,
-  );
+if (dapPath === undefined || !(await isExecutable(dapPath))) {
+  LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
+  return undefined;
 }
-return undefined;
+return new vscode.DebugAdapterExecutable(dapPath, dapArgs, dbgOptions);
   }
 
   /**
* Shows a message box when the debug adapter's pat

[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)

2025-02-28 Thread Matthew Bastien via lldb-commits


@@ -75,6 +75,15 @@
   "type": "string",
   "description": "The path to the lldb-dap binary."
 },
+"lldb-dap.arguments": {
+  "scope": "resource",
+  "type": "array",
+  "default": [],
+  "items": {
+"type": "string"
+  },
+  "description": "The arguments provided to the lldb-dap process."

matthewbastien wrote:

No reason in particular. You're right. I've updated the wording with your 
suggestions.

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


[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)

2025-02-28 Thread Matthew Bastien via lldb-commits


@@ -116,40 +131,31 @@ export class LLDBDapDescriptorFactory
 const configEnvironment =
   config.get<{ [key: string]: string }>("environment") || {};
 const dapPath = await getDAPExecutable(session);
+const dapArgs = getDAPArguments(session);
 const dbgOptions = {
   env: {
-...executable?.options?.env,
 ...configEnvironment,
 ...env,
   },
 };
-if (dapPath) {
-  if (!(await isExecutable(dapPath))) {
-LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(dapPath, [], dbgOptions);
-} else if (executable) {
-  if (!(await isExecutable(executable.command))) {
-
LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(executable.command);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(
-executable.command,
-executable.args,
-dbgOptions,
-  );
+if (dapPath === undefined || !(await isExecutable(dapPath))) {
+  LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
+  return undefined;
 }
-return undefined;
+return new vscode.DebugAdapterExecutable(dapPath, dapArgs, dbgOptions);
   }
 
   /**
* Shows a message box when the debug adapter's path is not found
*/
-  static async showLLDBDapNotFoundMessage(path: string) {
+  static async showLLDBDapNotFoundMessage(path: string | undefined) {
 const openSettingsAction = "Open Settings";
+const message =
+  path === undefined
+? "Unable to find the LLDB debug adapter executable."
+: `Debug adapter path: ${path} is not a valid file`;

matthewbastien wrote:

Good call. This is the only place that we show notifications as far as I can 
tell. So, I'm leaning towards having the period at the end and changed both to 
match.

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


[Lldb-commits] [lldb] [lldb-dap] Add process picker command to VS Code extension (PR #128943)

2025-02-28 Thread John Harrison via lldb-commits


@@ -0,0 +1,102 @@
+import { ChildProcessWithoutNullStreams } from "child_process";
+import { Process, ProcessTree } from ".";
+import { Transform } from "stream";
+
+/** Parses process information from a given line of process output. */
+export type ProcessTreeParser = (line: string) => Process | undefined;
+
+/**
+ * Implements common behavior between the different {@link ProcessTree} 
implementations.
+ */
+export abstract class BaseProcessTree implements ProcessTree {
+  /**
+   * Spawn the process responsible for collecting all processes on the system.
+   */
+  protected abstract spawnProcess(): ChildProcessWithoutNullStreams;

ashgti wrote:

It may be easer to use the `exec`/`execFile`. If you use the promise form of 
the `exec`/`execFile` call you get the output as a single chunk which 
simplifies processing.

You could use something like:
```
const exec = util.promisify(child_process.execFile); // this can go at the top 
of the file
const { stdout } = await exec("ps", [...]);
for (const line of stdout.split('\n')) {
  /* process lines */
}
```

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


[Lldb-commits] [lldb] a3ac1f2 - [lldb-dap] Adding server mode support to lldb-dap VSCode extension. (#128957)

2025-02-28 Thread via lldb-commits

Author: John Harrison
Date: 2025-02-28T10:49:24-08:00
New Revision: a3ac1f2278dec155e0e0b4d06ec816ba325f6979

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

LOG: [lldb-dap] Adding server mode support to lldb-dap VSCode extension. 
(#128957)

This adds support for launching lldb-dap in server mode. The extension
will start lldb-dap in server mode on-demand and retain the server until
the VSCode window is closed (when the extension context is disposed).
While running in server mode, launch performance for binaries is greatly
improved by improving caching between debug sessions.

For example, on my local M1 Max laptop it takes ~5s to attach for the
first attach to an iOS Simulator process and ~0.5s to attach each time
after the first.

Added: 


Modified: 
lldb/tools/lldb-dap/package.json
lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
lldb/tools/lldb-dap/src-ts/extension.ts

Removed: 




diff  --git a/lldb/tools/lldb-dap/package.json 
b/lldb/tools/lldb-dap/package.json
index 31d808eda4c35..cd450a614b3f7 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -88,6 +88,12 @@
   "additionalProperties": {
 "type": "string"
   }
+},
+"lldb-dap.serverMode": {
+  "scope": "resource",
+  "type": "boolean",
+  "markdownDescription": "Run lldb-dap in server mode.\n\nWhen 
enabled, lldb-dap will start a background server that will be reused between 
debug sessions. This allows caching of debug symbols between sessions and 
improves launch performance.",
+  "default": false
 }
   }
 },
@@ -543,4 +549,4 @@
   }
 ]
   }
-}
+}
\ No newline at end of file

diff  --git a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts 
b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
index 36107336ebc4d..1f76fe31b00ad 100644
--- a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
+++ b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
@@ -4,6 +4,8 @@ import * as vscode from "vscode";
 import * as child_process from "child_process";
 import * as fs from "node:fs/promises";
 
+const exec = util.promisify(child_process.execFile);
+
 export async function isExecutable(path: string): Promise {
   try {
 await fs.access(path, fs.constants.X_OK);
@@ -16,7 +18,6 @@ export async function isExecutable(path: string): 
Promise {
 async function findWithXcrun(executable: string): Promise {
   if (process.platform === "darwin") {
 try {
-  const exec = util.promisify(child_process.execFile);
   let { stdout, stderr } = await exec("/usr/bin/xcrun", [
 "-find",
 executable,
@@ -24,7 +25,7 @@ async function findWithXcrun(executable: string): 
Promise {
   if (stdout) {
 return stdout.toString().trimEnd();
   }
-} catch (error) {}
+} catch (error) { }
   }
   return undefined;
 }
@@ -97,8 +98,15 @@ async function getDAPExecutable(
  * depending on the session configuration.
  */
 export class LLDBDapDescriptorFactory
-  implements vscode.DebugAdapterDescriptorFactory
-{
+  implements vscode.DebugAdapterDescriptorFactory, vscode.Disposable {
+  private server?: Promise<{ process: child_process.ChildProcess, host: 
string, port: number }>;
+
+  dispose() {
+this.server?.then(({ process }) => {
+  process.kill();
+});
+  }
+
   async createDebugAdapterDescriptor(
 session: vscode.DebugSession,
 executable: vscode.DebugAdapterExecutable | undefined,
@@ -115,7 +123,18 @@ export class LLDBDapDescriptorFactory
 }
 const configEnvironment =
   config.get<{ [key: string]: string }>("environment") || {};
-const dapPath = await getDAPExecutable(session);
+const dapPath = (await getDAPExecutable(session)) ?? executable?.command;
+
+if (!dapPath) {
+  LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage();
+  return undefined;
+}
+
+if (!(await isExecutable(dapPath))) {
+  LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
+  return;
+}
+
 const dbgOptions = {
   env: {
 ...executable?.options?.env,
@@ -123,33 +142,52 @@ export class LLDBDapDescriptorFactory
 ...env,
   },
 };
-if (dapPath) {
-  if (!(await isExecutable(dapPath))) {
-LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(dapPath, [], dbgOptions);
-} else if (executable) {
-  if (!(await isExecutable(executable.command))) {
-
LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(executable.command);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(
-executable.command,
-executable.arg

[Lldb-commits] [lldb] [lldb] fix(lldb/**.py): fix invalid escape sequences (PR #94034)

2025-02-28 Thread David Spickett via lldb-commits

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


[Lldb-commits] [lldb] [lldb] fix(lldb/**.py): fix invalid escape sequences (PR #94034)

2025-02-28 Thread David Spickett via lldb-commits

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

LGTM

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


[Lldb-commits] [lldb] [lldb] Restore register state if PrepareTrivialCall fails (PR #129038)

2025-02-28 Thread David Spickett via lldb-commits

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

>From 67e0bd38889c1a62c9f457432f9e9d46c6ece8dc Mon Sep 17 00:00:00 2001
From: David Spickett 
Date: Wed, 26 Feb 2025 10:01:39 +
Subject: [PATCH] [lldb] Restore register state if PrepareTrivialCall fails

Fixes #124269

PrepareTrivalCall always had the possibility of failing, but
given that it only wrote to general purpose registers, if it
did, you had bigger problems.

When it failed, we did not mark the thread plan valid and
when it was torn down we didn't try to restore the register
state. This meant that if you tried to continue, the program
unlikely to work.

When I added GCS, I needed to handle the situation where the
GCS pointer points to unmapped memory and we fail to write
the extra entry we need. So I added code to restore the gcspr_el0
register specifically if this happened, and ordered the operations
such that we tried this first.

In this change I've made the teardown of an invalid thread plan
restore the register state if one was saved. It may be there isn't
one if ConstructorSetup fails, but this is ok because that function
does not modify anything.

Now that we're doing that, I don't need the GCS specific code
anymore, and all thread plans are protected from this in the rare
event something does fail.

Testing is done by the existing GCS test case that points
the gcspr into unmapped memory which causes PrepareTrivialCall
to fail.

I tried adding a simulated test using a mock gdb server. This
was not possible because they all use DynamicLoaderStatic which
disables all JIT features.
---
 lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp |  7 +--
 lldb/source/Target/ThreadPlanCallFunction.cpp | 13 -
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp 
b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
index 280ec5ba37100..4bca879143a33 100644
--- a/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
+++ b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
@@ -102,12 +102,7 @@ static Status PushToLinuxGuardedControlStack(addr_t 
return_addr,
   size_t wrote = thread.GetProcess()->WriteMemory(gcspr_el0, &return_addr,
   sizeof(return_addr), error);
   if ((wrote != sizeof(return_addr) || error.Fail())) {
-// When PrepareTrivialCall fails, the register context is not restored,
-// unlike when an expression fails to execute. This is arguably a bug,
-// see https://github.com/llvm/llvm-project/issues/124269.
-// For now we are handling this here specifically. We can assume this
-// write will work as the one to decrement the register did.
-reg_ctx->WriteRegisterFromUnsigned(gcspr_el0_info, gcspr_el0 + 8);
+// gcspr_el0 will be restored by the ThreadPlan's DoTakedown.
 return Status("Failed to write new Guarded Control Stack entry.");
   }
 
diff --git a/lldb/source/Target/ThreadPlanCallFunction.cpp 
b/lldb/source/Target/ThreadPlanCallFunction.cpp
index 50dcb66b9719f..218111d4faf60 100644
--- a/lldb/source/Target/ThreadPlanCallFunction.cpp
+++ b/lldb/source/Target/ThreadPlanCallFunction.cpp
@@ -174,8 +174,20 @@ void ThreadPlanCallFunction::ReportRegisterState(const 
char *message) {
 
 void ThreadPlanCallFunction::DoTakedown(bool success) {
   Log *log = GetLog(LLDBLog::Step);
+  Thread &thread = GetThread();
 
   if (!m_valid) {
+// If ConstructorSetup was succesfull but PrepareTrivialCall was not,
+// we will have a saved register state and potentially modified registers.
+// Restore those.
+if (m_stored_thread_state.register_backup_sp)
+  if (!thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state))
+LLDB_LOGF(
+log,
+"ThreadPlanCallFunction(%p): Failed to restore register state from 
"
+"invalid plan that contained a saved register state.",
+static_cast(this));
+
 // Don't call DoTakedown if we were never valid to begin with.
 LLDB_LOGF(log,
   "ThreadPlanCallFunction(%p): Log called on "
@@ -185,7 +197,6 @@ void ThreadPlanCallFunction::DoTakedown(bool success) {
   }
 
   if (!m_takedown_done) {
-Thread &thread = GetThread();
 if (success) {
   SetReturnValue();
 }

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


[Lldb-commits] [lldb] [lldb] Add ability to inspect backing threads with `thread info` (PR #129275)

2025-02-28 Thread via lldb-commits

jimingham wrote:

Apparently I need more coffee...  This is just in the info command (somehow I 
thought the change was to ThreadObjectIterateOverThreads...  Done this way, 
that's okay.

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


[Lldb-commits] [lldb] [lldb] Add ability to inspect backing threads with `thread info` (PR #129275)

2025-02-28 Thread via lldb-commits

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

LGTM

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


[Lldb-commits] [lldb] [lldb] fix(lldb/**.py): fix invalid escape sequences (PR #94034)

2025-02-28 Thread via lldb-commits

github-actions[bot] wrote:



@e-kwsm Congratulations on having your first Pull Request (PR) merged into the 
LLVM Project!

Your changes will be combined with recent changes from other authors, then 
tested by our [build bots](https://lab.llvm.org/buildbot/). If there is a 
problem with a build, you may receive a report in an email or a comment on this 
PR.

Please check whether problems have been caused by your change specifically, as 
the builds can include changes from many authors. It is not uncommon for your 
change to be included in a build that fails due to someone else's changes, or 
infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail 
[here](https://llvm.org/docs/MyFirstTypoFix.html#myfirsttypofix-issues-after-landing-your-pr).

If your change does cause a problem, it may be reverted, or you can revert it 
yourself. This is a normal part of [LLVM 
development](https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy).
 You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are 
working as expected, well done!


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


[Lldb-commits] [lldb] Push down the swig module to avoid an import cycle (PR #129135)

2025-02-28 Thread Jonas Devlieghere via lldb-commits

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

LGTM. Thanks for adding the comment with the motivation!

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


[Lldb-commits] [lldb] [LLDB][Telemetry]Define DebuggerTelemetryInfo and related methods (PR #127696)

2025-02-28 Thread Vy Nguyen via lldb-commits

https://github.com/oontvoo updated 
https://github.com/llvm/llvm-project/pull/127696

>From 24e9f78744f98ecf3ac01f1f719f1eac9b3479f0 Mon Sep 17 00:00:00 2001
From: Vy Nguyen 
Date: Tue, 18 Feb 2025 15:58:08 -0500
Subject: [PATCH 01/24] [LLDB][Telemetry]Define DebuggerTelemetryInfo and
 related methods

- This type of entry is used to collect data about the debugger startup/exit
- Tests will be added (They may need to be shell test with a "test-only" 
TelemetryManager plugin defined. I'm trying to figure out how to get that 
linked only when tests are running and not to the LLDB binary all the time.
---
 lldb/include/lldb/Core/Telemetry.h |  78 +++
 lldb/source/Core/Debugger.cpp  |  40 ++
 lldb/source/Core/Telemetry.cpp | 115 +
 3 files changed, 220 insertions(+), 13 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index b72556ecaf3c9..d6eec5dc687be 100644
--- a/lldb/include/lldb/Core/Telemetry.h
+++ b/lldb/include/lldb/Core/Telemetry.h
@@ -13,6 +13,7 @@
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Utility/StructuredData.h"
 #include "lldb/lldb-forward.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/JSON.h"
@@ -29,6 +30,9 @@ namespace telemetry {
 
 struct LLDBEntryKind : public ::llvm::telemetry::EntryKind {
   static const llvm::telemetry::KindType BaseInfo = 0b11000;
+  static const llvm::telemetry::KindType DebuggerInfo = 0b11001;
+  // There are other entries in between (added in separate PRs)
+  static const llvm::telemetry::KindType MiscInfo = 0b0;
 };
 
 /// Defines a convenient type for timestamp of various events.
@@ -56,6 +60,71 @@ struct LLDBBaseTelemetryInfo : public 
llvm::telemetry::TelemetryInfo {
   void serialize(llvm::telemetry::Serializer &serializer) const override;
 };
 
+/// Describes the exit status of a debugger.
+struct ExitDescription {
+  int exit_code;
+  std::string description;
+};
+
+struct DebuggerTelemetryInfo : public LLDBBaseTelemetryInfo {
+  std::string username;
+  std::string lldb_git_sha;
+  std::string lldb_path;
+  std::string cwd;
+  std::optional exit_desc;
+
+  DebuggerTelemetryInfo() = default;
+
+  // Provide a copy ctor because we may need to make a copy before
+  // sanitizing the data.
+  // (The sanitization might differ between different Destination classes).
+  DebuggerTelemetryInfo(const DebuggerTelemetryInfo &other) {
+username = other.username;
+lldb_git_sha = other.lldb_git_sha;
+lldb_path = other.lldb_path;
+cwd = other.cwd;
+  };
+
+  llvm::telemetry::KindType getKind() const override {
+return LLDBEntryKind::DebuggerInfo;
+  }
+
+  static bool classof(const llvm::telemetry::TelemetryInfo *T) {
+return T->getKind() == LLDBEntryKind::DebuggerInfo;
+  }
+
+  void serialize(llvm::telemetry::Serializer &serializer) const override;
+};
+
+/// The "catch-all" entry to store a set of non-standard data, such as
+/// error-messages, etc.
+struct MiscTelemetryInfo : public LLDBBaseTelemetryInfo {
+  /// If the event is/can be associated with a target entry,
+  /// this field contains that target's UUID.
+  ///  otherwise.
+  std::string target_uuid;
+
+  /// Set of key-value pairs for any optional (or impl-specific) data
+  std::map meta_data;
+
+  MiscTelemetryInfo() = default;
+
+  MiscTelemetryInfo(const MiscTelemetryInfo &other) {
+target_uuid = other.target_uuid;
+meta_data = other.meta_data;
+  }
+
+  llvm::telemetry::KindType getKind() const override {
+return LLDBEntryKind::MiscInfo;
+  }
+
+  static bool classof(const llvm::telemetry::TelemetryInfo *T) {
+return T->getKind() == LLDBEntryKind::MiscInfo;
+  }
+
+  void serialize(llvm::telemetry::Serializer &serializer) const override;
+};
+
 /// The base Telemetry manager instance in LLDB.
 /// This class declares additional instrumentation points
 /// applicable to LLDB.
@@ -63,6 +132,11 @@ class TelemetryManager : public llvm::telemetry::Manager {
 public:
   llvm::Error preDispatch(llvm::telemetry::TelemetryInfo *entry) override;
 
+  const llvm::telemetry::Config *getConfig();
+
+  void atDebuggerStartup(DebuggerTelemetryInfo *entry);
+  void atDebuggerExit(DebuggerTelemetryInfo *entry);
+
   virtual llvm::StringRef GetInstanceName() const = 0;
   static TelemetryManager *getInstance();
 
@@ -73,6 +147,10 @@ class TelemetryManager : public llvm::telemetry::Manager {
 
 private:
   std::unique_ptr m_config;
+  // Each debugger is assigned a unique ID (session_id).
+  // All TelemetryInfo entries emitted for the same debugger instance
+  // will get the same session_id.
+  llvm::DenseMap session_ids;
   static std::unique_ptr g_instance;
 };
 
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 18569e155b517..b458abc798a9e 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -62,6 +62,7 @@

[Lldb-commits] [lldb] [lldb][HostInfoMacOSX] Search CommandLineTools directory when looking up SDK paths (PR #128712)

2025-02-28 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere commented:

I definitely like this approach much better. Two suggestions:

 - Should this use a FileSpec instead of a `std::string` for the sysroot? 
 - I like the simplicity of a `std::pair` but on the other hand it's hard to 
tell what the string represents. I think it would help to either store the 
`sysroot` in the `XcodeSDK` (potentially as an `std::optional`) or having this 
return a `struct` with named fiels (e.g. `xcode_sdk`, `sysroot`). Putting the 
sysroot in the XcodeSDK means you don't have to update the Doxygen comments 
which are now all outdated. 

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


[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)

2025-02-28 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Matthew Bastien (matthewbastien)


Changes

Added a new setting called lldb-dap.arguments and a debug configuration 
attribute called debugAdapterArgs that can be used to set the arguments used to 
launch the debug adapter. Right now this is mostly useful for debugging 
purposes to add the `--wait-for-debugger` option to lldb-dap.

I've also removed the check for the `executable` argument in 
`LLDBDapDescriptorFactory.createDebugAdapterDescriptor()`. This argument is 
only set by VS Code when the debug adapter executable properties are set in the 
`package.json`. The LLDB DAP extension does not currently do this (and I don't 
think it ever will). So, this makes the debug adapter descriptor factory a 
little easier to read.

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


2 Files Affected:

- (modified) lldb/tools/lldb-dap/package.json (+23) 
- (modified) lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts (+27-21) 


``diff
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 31d808eda4c35..0859b6e388a4e 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -75,6 +75,15 @@
   "type": "string",
   "description": "The path to the lldb-dap binary."
 },
+"lldb-dap.arguments": {
+  "scope": "resource",
+  "type": "array",
+  "default": [],
+  "items": {
+"type": "string"
+  },
+  "description": "The arguments provided to the lldb-dap process."
+},
 "lldb-dap.log-path": {
   "scope": "resource",
   "type": "string",
@@ -156,6 +165,13 @@
 "type": "string",
 "markdownDescription": "The absolute path to the LLDB debug 
adapter executable to use."
   },
+  "debugAdapterArgs": {
+"type": "array",
+"items": {
+  "type": "string"
+},
+"markdownDescription": "The list of arguments used to launch 
the debug adapter executable."
+  },
   "program": {
 "type": "string",
 "description": "Path to the program to debug."
@@ -346,6 +362,13 @@
 "type": "string",
 "markdownDescription": "The absolute path to the LLDB debug 
adapter executable to use."
   },
+  "debugAdapterArgs": {
+"type": "array",
+"items": {
+  "type": "string"
+},
+"markdownDescription": "The list of arguments used to launch 
the debug adapter executable."
+  },
   "program": {
 "type": "string",
 "description": "Path to the program to attach to."
diff --git a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts 
b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
index 36107336ebc4d..ea7b4ce97ac1d 100644
--- a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
+++ b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
@@ -92,6 +92,21 @@ async function getDAPExecutable(
   return undefined;
 }
 
+function getDAPArguments(session: vscode.DebugSession): string[] {
+  // Check the debug configuration for arguments first
+  const debugConfigArgs = session.configuration.debugAdapterArgs;
+  if (
+Array.isArray(debugConfigArgs) &&
+debugConfigArgs.findIndex((entry) => typeof entry !== "string") === -1
+  ) {
+return debugConfigArgs;
+  }
+  // Fall back on the workspace configuration
+  return vscode.workspace
+.getConfiguration("lldb-dap")
+.get("arguments", []);
+}
+
 /**
  * This class defines a factory used to find the lldb-dap binary to use
  * depending on the session configuration.
@@ -101,7 +116,7 @@ export class LLDBDapDescriptorFactory
 {
   async createDebugAdapterDescriptor(
 session: vscode.DebugSession,
-executable: vscode.DebugAdapterExecutable | undefined,
+_executable: vscode.DebugAdapterExecutable | undefined,
   ): Promise {
 const config = vscode.workspace.getConfiguration(
   "lldb-dap",
@@ -116,40 +131,31 @@ export class LLDBDapDescriptorFactory
 const configEnvironment =
   config.get<{ [key: string]: string }>("environment") || {};
 const dapPath = await getDAPExecutable(session);
+const dapArgs = getDAPArguments(session);
 const dbgOptions = {
   env: {
-...executable?.options?.env,
 ...configEnvironment,
 ...env,
   },
 };
-if (dapPath) {
-  if (!(await isExecutable(dapPath))) {
-LLDBDapDescriptorFactory.showLLDBDapNotFoundMessage(dapPath);
-return undefined;
-  }
-  return new vscode.DebugAdapterExecutable(dapPath, [], dbgOptions);
-} else if (executable) {
-  if (!(await isExecutable(executable.command))) {
-
LLDBDapDescriptorFactory.showLLDBDapN

  1   2   >