[Lldb-commits] [lldb] [lldb-dap] Emit declarations along with variables (PR #74865)

2024-08-12 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

FYI @walter-erquinigo: There is a proposal under discussion to add first-class 
support for `declarationLocation` (and also `valueLocation`) to the debug 
adapter protocol. See 
https://github.com/microsoft/debug-adapter-protocol/issues/343

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-12 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang created 
https://github.com/llvm/llvm-project/pull/102928

`declarationLocation` is about to become part of the upstream debug adapter 
protocol (see microsoft/debug-adapter-protocol#343). This is a draft 
implementation, to be finalized and merged after the corresponding changes were 
merged into DAP.

TODO:

* Adjust comment on `CreateVariable` function with updated jsonschema as soon 
as the upstream changes were merged to DAP.
* Update based on final protocol merged to DAP

>From 5c3b3458eb3426e58ead2d66f0cc9530eb368dd3 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Sat, 10 Aug 2024 23:59:55 +
Subject: [PATCH] [lldb-dap] Provide `declarationLocation` for variables

TODO:

* Adjust comment on `CreateVariable` function with updated jsonschema as
  soon as the upstream changes were merged to DAP.

`declarationLocation` is about to become part of the upstream
debug-adapter-protocol. This is a draft implementation, to be finalized
and merged after the corresponding changes were merged into DAP.
---
 .../lldb-dap/variables/TestDAP_variables.py|  4 
 lldb/tools/lldb-dap/JSONUtils.cpp  | 18 --
 lldb/tools/lldb-dap/JSONUtils.h| 14 --
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py 
b/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
index 3c6901b2fd99a5..7d982e801f741e 100644
--- a/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
+++ b/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
@@ -168,6 +168,10 @@ def do_test_scopes_variables_setVariable_evaluate(
 "type": "int",
 "value": "1",
 },
+"declarationLocation": {
+"equals": {"line": 12, "column": 14},
+"contains": {"path": ["lldb-dap", "variables", 
"main.cpp"]},
+},
 "$__lldb_extensions": {
 "equals": {
 "value": "1",
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index a8b85f55939e17..3e0c1076643260 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -614,9 +614,8 @@ CreateExceptionBreakpointFilter(const ExceptionBreakpoint 
&bp) {
 // }
 //   }
 // }
-llvm::json::Value CreateSource(lldb::SBLineEntry &line_entry) {
+llvm::json::Value CreateSource(const lldb::SBFileSpec &file) {
   llvm::json::Object object;
-  lldb::SBFileSpec file = line_entry.GetFileSpec();
   if (file.IsValid()) {
 const char *name = file.GetFilename();
 if (name)
@@ -630,6 +629,10 @@ llvm::json::Value CreateSource(lldb::SBLineEntry 
&line_entry) {
   return llvm::json::Value(std::move(object));
 }
 
+llvm::json::Value CreateSource(const lldb::SBLineEntry &line_entry) {
+  return CreateSource(line_entry.GetFileSpec());
+}
+
 llvm::json::Value CreateSource(llvm::StringRef source_path) {
   llvm::json::Object source;
   llvm::StringRef name = llvm::sys::path::filename(source_path);
@@ -1253,6 +1256,17 @@ llvm::json::Value CreateVariable(lldb::SBValue v, 
int64_t variablesReference,
   else
 object.try_emplace("variablesReference", (int64_t)0);
 
+  if (lldb::SBDeclaration decl = v.GetDeclaration(); decl.IsValid()) {
+llvm::json::Object decl_obj;
+decl_obj.try_emplace("source", CreateSource(decl.GetFileSpec()));
+if (int line = decl.GetLine())
+  decl_obj.try_emplace("line", line);
+if (int column = decl.GetColumn())
+  decl_obj.try_emplace("column", column);
+
+object.try_emplace("declarationLocation", std::move(decl_obj));
+  }
+
   object.try_emplace("$__lldb_extensions", desc.GetVariableExtensionsJSON());
   return llvm::json::Value(std::move(object));
 }
diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index 1515f5ba2e5f4d..610f920952e77c 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -282,6 +282,16 @@ llvm::json::Value CreateScope(const llvm::StringRef name,
   int64_t variablesReference,
   int64_t namedVariables, bool expensive);
 
+/// Create a "Source" JSON object as described in the debug adaptor definition.
+///
+/// \param[in] file
+/// The SBFileSpec to use when populating out the "Source" object
+///
+/// \return
+/// A "Source" JSON object that follows the formal JSON
+/// definition outlined by Microsoft.
+llvm::json::Value CreateSource(const lldb::SBFileSpec &file);
+
 /// Create a "Source" JSON object as described in the debug adaptor definition.
 ///
 /// \param[in] line_entry
@@ -289,9 +299,9 @@ llvm::json::Value CreateScope(const llvm::StringRef name,
 /// object
 ///
 /// \return
-/// A "Source" JSON object with that follows the formal JSON
+/// A "Source" JSON object that follows the formal JSON
 ///

[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-12 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

@walter-erquinigo I took a first stab at implementing the DAP proposal. Seemed 
rather straightforward. I would love to hear if I missed anything.

Also, I am not sure how to implement `valueLocation`, i.e., a the source 
location referecend by the value. E.g., for a function pointer, this location 
should point to the source location where the corresponding function was 
implemented. If you have any idea on how to do so, I would be interested in 
hearing about it 🙂 

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


[Lldb-commits] [lldb] [lldb-dap] Expose log path in extension settings (PR #103482)

2024-08-13 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang created 
https://github.com/llvm/llvm-project/pull/103482

lldb-dap already supports a log file which can be enabled by setting the 
`LLDBDAP_LOG` environment variable. With this commit, the log location can be 
set directly through the VS-Code extension settings.

Also, this commit bumps the version number, such that the new VS Code extension 
gets published to the Marketplace.


>From 6c9da388efecf0e33acd6678081bfb04aca4939f Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Tue, 13 Aug 2024 00:34:42 +
Subject: [PATCH] [lldb-dap] Expose log path in extension settings

lldb-dap already supports a log file which can be enabled by setting the
`LLDBDAP_LOG` environment variable. With this commit, the log location
can be set directly through the VS-Code extension settings.

Also, this commit bumps the version number, such that the new VS Code
extension gets published to the Marketplace.
---
 lldb/tools/lldb-dap/package-lock.json   |  4 ++--
 lldb/tools/lldb-dap/package.json|  7 ++-
 lldb/tools/lldb-dap/src-ts/extension.ts | 26 -
 3 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/lldb/tools/lldb-dap/package-lock.json 
b/lldb/tools/lldb-dap/package-lock.json
index 8c70cc2d30e144..96570e42dbfdc4 100644
--- a/lldb/tools/lldb-dap/package-lock.json
+++ b/lldb/tools/lldb-dap/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "lldb-dap",
-  "version": "0.2.0",
+  "version": "0.2.4",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
 "": {
   "name": "lldb-dap",
-  "version": "0.2.0",
+  "version": "0.2.4",
   "license": "Apache 2.0 License with LLVM exceptions",
   "devDependencies": {
 "@types/node": "^18.11.18",
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 97e4efe7bac19d..4f4261d1718c01 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -1,7 +1,7 @@
 {
   "name": "lldb-dap",
   "displayName": "LLDB DAP",
-  "version": "0.2.3",
+  "version": "0.2.4",
   "publisher": "llvm-vs-code-extensions",
   "homepage": "https://lldb.llvm.org";,
   "description": "LLDB debugging from VSCode",
@@ -73,6 +73,11 @@
   "scope": "resource",
   "type": "string",
   "description": "The path to the lldb-dap binary."
+},
+"lldb-dap.log-path": {
+  "scope": "resource",
+  "type": "string",
+  "description": "The log path for lldb-dap (if any)"
 }
   }
 },
diff --git a/lldb/tools/lldb-dap/src-ts/extension.ts 
b/lldb/tools/lldb-dap/src-ts/extension.ts
index 791175f7b46224..7df09f7a29dad7 100644
--- a/lldb/tools/lldb-dap/src-ts/extension.ts
+++ b/lldb/tools/lldb-dap/src-ts/extension.ts
@@ -14,13 +14,29 @@ function createDefaultLLDBDapOptions(): LLDBDapOptions {
   session: vscode.DebugSession,
   packageJSONExecutable: vscode.DebugAdapterExecutable | undefined,
 ): Promise {
-  const path = vscode.workspace
-.getConfiguration("lldb-dap", session.workspaceFolder)
-.get("executable-path");
+  const config = vscode.workspace
+.getConfiguration("lldb-dap", session.workspaceFolder);
+  const path = config.get("executable-path");
+  const log_path = config.get("log-path");
+
+  let env : { [key: string]: string } = {};
+  if (log_path) {
+env["LLDBDAP_LOG"] = log_path;
+  }
+
   if (path) {
-return new vscode.DebugAdapterExecutable(path, []);
+return new vscode.DebugAdapterExecutable(path, [], {env});
+  } else if (packageJSONExecutable) {
+return new 
vscode.DebugAdapterExecutable(packageJSONExecutable.command, 
packageJSONExecutable.args, {
+  ...packageJSONExecutable.options,
+  env: {
+...packageJSONExecutable.options?.env,
+...env
+  }
+});
+  } else {
+return undefined;
   }
-  return packageJSONExecutable;
 },
   };
 }

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-14 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

No worries. I will have to rework this commit anyway.

In the meantime, a proposal was merged upstream and also already implemented in 
VS-Code. However, there were still larger changes which will require a complete 
rewrite of this commit

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


[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-14 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang created 
https://github.com/llvm/llvm-project/pull/104317

Adds support for the `readMemory` request which allows VS-Code to inspect 
memory. Also, add `memoryReference` to variablesa and `evaluate` responses, 
such that the binary view can be opened from the variables view and from the 
"watch" pane.

>From e01ea18961bbae0fb747b312670946bd768c5d73 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Wed, 14 Aug 2024 11:52:40 +
Subject: [PATCH] [lldb-dap] Support inspecting memory

Adds support for the `readMemory` request which allows VS-Code to
inspect memory. Also, add `memoryReference` to variablesa and `evaluate`
responses, such that the binary view can be opened from the variables
view and from the "watch" pane.
---
 .../test/tools/lldb-dap/dap_server.py |  15 ++
 lldb/test/API/tools/lldb-dap/memory/Makefile  |   3 +
 .../tools/lldb-dap/memory/TestDAP_memory.py   | 121 
 lldb/test/API/tools/lldb-dap/memory/main.cpp  |  10 +
 lldb/tools/lldb-dap/JSONUtils.cpp |  30 ++-
 lldb/tools/lldb-dap/JSONUtils.h   |   6 +
 lldb/tools/lldb-dap/lldb-dap.cpp  | 172 +-
 7 files changed, 354 insertions(+), 3 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/main.cpp

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..35d792351e6bfc 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -691,6 +691,21 @@ def request_disassemble(
 for inst in instructions:
 self.disassembled_instructions[inst["address"]] = inst
 
+def request_read_memory(
+self, memoryReference, offset, count
+):
+args_dict = {
+"memoryReference": memoryReference,
+"offset": offset,
+"count": count,
+}
+command_dict = {
+"command": "readMemory",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_evaluate(self, expression, frameIndex=0, threadId=None, 
context=None):
 stackFrame = self.get_stackFrame(frameIndex=frameIndex, 
threadId=threadId)
 if stackFrame is None:
diff --git a/lldb/test/API/tools/lldb-dap/memory/Makefile 
b/lldb/test/API/tools/lldb-dap/memory/Makefile
new file mode 100644
index 00..8b20bcb050
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py 
b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
new file mode 100644
index 00..9ff4dbd3138428
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
@@ -0,0 +1,121 @@
+"""
+Test lldb-dap memory support
+"""
+
+
+from base64 import b64decode
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase):
+def test_read_memory(self):
+"""
+Tests the 'read_memory' request
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.cpp"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[
+line_number(source, "// Breakpoint"),
+],
+)
+self.continue_to_next_stop()
+
+locals = {l['name']: l for l in self.dap_server.get_local_variables()}
+rawptr_ref = locals['rawptr']['memoryReference']
+
+# We can read the complete string
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 5)["body"]
+self.assertEqual(mem["unreadableBytes"], 0);
+self.assertEqual(b64decode(mem["data"]), b"dead\0")
+
+# Use an offset
+mem = self.dap_server.request_read_memory(rawptr_ref, 2, 3)["body"]
+self.assertEqual(b64decode(mem["data"]), b"ad\0")
+
+# Use a negative offset
+mem = self.dap_server.request_read_memory(rawptr_ref, -1, 6)["body"]
+self.assertEqual(b64decode(mem["data"])[1:], b"dead\0")
+
+# Reads of size 0 are successful
+# VS-Code sends those in order to check if a `memoryReference` can 
actually be dereferenced.
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 0)
+self.assertEqual(mem["success"], True)
+self.assertEqual(mem["body"]["data"], "")
+
+# Reads at offset 0x0 fail
+mem = self.da

[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-14 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/104317

>From a5b4f6e7e105d36b82f9de588d2705ad3d622953 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Wed, 14 Aug 2024 11:52:40 +
Subject: [PATCH] [lldb-dap] Support inspecting memory

Adds support for the `readMemory` request which allows VS-Code to
inspect memory. Also, add `memoryReference` to variablesa and `evaluate`
responses, such that the binary view can be opened from the variables
view and from the "watch" pane.
---
 .../test/tools/lldb-dap/dap_server.py |  13 ++
 lldb/test/API/tools/lldb-dap/memory/Makefile  |   3 +
 .../tools/lldb-dap/memory/TestDAP_memory.py   | 135 ++
 lldb/test/API/tools/lldb-dap/memory/main.cpp  |  10 +
 lldb/tools/lldb-dap/JSONUtils.cpp |  29 ++-
 lldb/tools/lldb-dap/JSONUtils.h   |   6 +
 lldb/tools/lldb-dap/lldb-dap.cpp  | 172 +-
 7 files changed, 365 insertions(+), 3 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/main.cpp

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..da10e8ab5c57c2 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -691,6 +691,19 @@ def request_disassemble(
 for inst in instructions:
 self.disassembled_instructions[inst["address"]] = inst
 
+def request_read_memory(self, memoryReference, offset, count):
+args_dict = {
+"memoryReference": memoryReference,
+"offset": offset,
+"count": count,
+}
+command_dict = {
+"command": "readMemory",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_evaluate(self, expression, frameIndex=0, threadId=None, 
context=None):
 stackFrame = self.get_stackFrame(frameIndex=frameIndex, 
threadId=threadId)
 if stackFrame is None:
diff --git a/lldb/test/API/tools/lldb-dap/memory/Makefile 
b/lldb/test/API/tools/lldb-dap/memory/Makefile
new file mode 100644
index 00..8b20bcb050
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py 
b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
new file mode 100644
index 00..f950d5eecda671
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
@@ -0,0 +1,135 @@
+"""
+Test lldb-dap memory support
+"""
+
+from base64 import b64decode
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase):
+def test_read_memory(self):
+"""
+Tests the 'read_memory' request
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.cpp"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// Breakpoint")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+rawptr_ref = locals["rawptr"]["memoryReference"]
+
+# We can read the complete string
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 5)["body"]
+self.assertEqual(mem["unreadableBytes"], 0)
+self.assertEqual(b64decode(mem["data"]), b"dead\0")
+
+# Use an offset
+mem = self.dap_server.request_read_memory(rawptr_ref, 2, 3)["body"]
+self.assertEqual(b64decode(mem["data"]), b"ad\0")
+
+# Use a negative offset
+mem = self.dap_server.request_read_memory(rawptr_ref, -1, 6)["body"]
+self.assertEqual(b64decode(mem["data"])[1:], b"dead\0")
+
+# Reads of size 0 are successful
+# VS-Code sends those in order to check if a `memoryReference` can 
actually be dereferenced.
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 0)
+self.assertEqual(mem["success"], True)
+self.assertEqual(mem["body"]["data"], "")
+
+# Reads at offset 0x0 fail
+mem = self.dap_server.request_read_memory("0x0", 0, 6)
+self.assertEqual(mem["success"], False)
+self.assertTrue(mem["message"].startswith("Unable to read memory: "))
+
+def test_memory_refs_variables(self):
+"""
+Tests memory references for evaluate
+"""
+   

[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-14 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:


https://github.com/user-attachments/assets/f1ec37fe-414e-41ee-ad10-a213570d3e5f



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


[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-15 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/104317

>From a5b4f6e7e105d36b82f9de588d2705ad3d622953 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Wed, 14 Aug 2024 11:52:40 +
Subject: [PATCH 1/2] [lldb-dap] Support inspecting memory

Adds support for the `readMemory` request which allows VS-Code to
inspect memory. Also, add `memoryReference` to variablesa and `evaluate`
responses, such that the binary view can be opened from the variables
view and from the "watch" pane.
---
 .../test/tools/lldb-dap/dap_server.py |  13 ++
 lldb/test/API/tools/lldb-dap/memory/Makefile  |   3 +
 .../tools/lldb-dap/memory/TestDAP_memory.py   | 135 ++
 lldb/test/API/tools/lldb-dap/memory/main.cpp  |  10 +
 lldb/tools/lldb-dap/JSONUtils.cpp |  29 ++-
 lldb/tools/lldb-dap/JSONUtils.h   |   6 +
 lldb/tools/lldb-dap/lldb-dap.cpp  | 172 +-
 7 files changed, 365 insertions(+), 3 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/main.cpp

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..da10e8ab5c57c2 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -691,6 +691,19 @@ def request_disassemble(
 for inst in instructions:
 self.disassembled_instructions[inst["address"]] = inst
 
+def request_read_memory(self, memoryReference, offset, count):
+args_dict = {
+"memoryReference": memoryReference,
+"offset": offset,
+"count": count,
+}
+command_dict = {
+"command": "readMemory",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_evaluate(self, expression, frameIndex=0, threadId=None, 
context=None):
 stackFrame = self.get_stackFrame(frameIndex=frameIndex, 
threadId=threadId)
 if stackFrame is None:
diff --git a/lldb/test/API/tools/lldb-dap/memory/Makefile 
b/lldb/test/API/tools/lldb-dap/memory/Makefile
new file mode 100644
index 00..8b20bcb050
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py 
b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
new file mode 100644
index 00..f950d5eecda671
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
@@ -0,0 +1,135 @@
+"""
+Test lldb-dap memory support
+"""
+
+from base64 import b64decode
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase):
+def test_read_memory(self):
+"""
+Tests the 'read_memory' request
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.cpp"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// Breakpoint")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+rawptr_ref = locals["rawptr"]["memoryReference"]
+
+# We can read the complete string
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 5)["body"]
+self.assertEqual(mem["unreadableBytes"], 0)
+self.assertEqual(b64decode(mem["data"]), b"dead\0")
+
+# Use an offset
+mem = self.dap_server.request_read_memory(rawptr_ref, 2, 3)["body"]
+self.assertEqual(b64decode(mem["data"]), b"ad\0")
+
+# Use a negative offset
+mem = self.dap_server.request_read_memory(rawptr_ref, -1, 6)["body"]
+self.assertEqual(b64decode(mem["data"])[1:], b"dead\0")
+
+# Reads of size 0 are successful
+# VS-Code sends those in order to check if a `memoryReference` can 
actually be dereferenced.
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 0)
+self.assertEqual(mem["success"], True)
+self.assertEqual(mem["body"]["data"], "")
+
+# Reads at offset 0x0 fail
+mem = self.dap_server.request_read_memory("0x0", 0, 6)
+self.assertEqual(mem["success"], False)
+self.assertTrue(mem["message"].startswith("Unable to read memory: "))
+
+def test_memory_refs_variables(self):
+"""
+Tests memory references for evaluate
+"""
+   

[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-15 Thread Adrian Vogelsgesang via lldb-commits


@@ -4028,6 +4049,154 @@ void request_disassemble(const llvm::json::Object 
&request) {
   response.try_emplace("body", std::move(body));
   g_dap.SendJSON(llvm::json::Value(std::move(response)));
 }
+
+// "ReadMemoryRequest": {
+//   "allOf": [ { "$ref": "#/definitions/Request" }, {
+// "type": "object",
+// "description": "Reads bytes from memory at the provided location. 
Clients
+// should only call this request if the corresponding
+// capability `supportsReadMemoryRequest` is true.",
+// "properties": {
+//   "command": {
+// "type": "string",
+// "enum": [ "readMemory" ]
+//   },
+//   "arguments": {
+// "$ref": "#/definitions/ReadMemoryArguments"
+//   }
+// },
+// "required": [ "command", "arguments" ]
+//   }]
+// },
+// "ReadMemoryArguments": {
+//   "type": "object",
+//   "description": "Arguments for `readMemory` request.",
+//   "properties": {
+// "memoryReference": {
+//   "type": "string",
+//   "description": "Memory reference to the base location from which data
+//   should be read."
+// },
+// "offset": {
+//   "type": "integer",
+//   "description": "Offset (in bytes) to be applied to the reference
+//   location before reading data. Can be negative."
+// },
+// "count": {
+//   "type": "integer",
+//   "description": "Number of bytes to read at the specified location and
+//   offset."
+// }
+//   },
+//   "required": [ "memoryReference", "count" ]
+// },
+// "ReadMemoryResponse": {
+//   "allOf": [ { "$ref": "#/definitions/Response" }, {
+// "type": "object",
+// "description": "Response to `readMemory` request.",
+// "properties": {
+//   "body": {
+// "type": "object",
+// "properties": {
+//   "address": {
+// "type": "string",
+// "description": "The address of the first byte of data returned.
+// Treated as a hex value if prefixed with `0x`, or
+// as a decimal value otherwise."
+//   },
+//   "unreadableBytes": {
+// "type": "integer",
+// "description": "The number of unreadable bytes encountered after
+// the last successfully read byte.\nThis can be
+// used to determine the number of bytes that 
should
+// be skipped before a subsequent
+// `readMemory` request succeeds."
+//   },
+//   "data": {
+// "type": "string",
+// "description": "The bytes read from memory, encoded using 
base64.
+// If the decoded length of `data` is less than the
+// requested `count` in the original `readMemory`
+// request, and `unreadableBytes` is zero or
+// omitted, then the client should assume it's
+// reached the end of readable memory."
+//   }
+// },
+// "required": [ "address" ]
+//   }
+// }
+//   }]
+// },
+void request_readMemory(const llvm::json::Object &request) {
+  llvm::json::Object response;
+  FillResponse(request, response);
+  auto arguments = request.getObject("arguments");
+
+  lldb::SBProcess process = g_dap.target.GetProcess();
+  if (!process.IsValid()) {
+response["success"] = false;
+response["message"] = "No process running";
+g_dap.SendJSON(llvm::json::Value(std::move(response)));
+return;
+  }
+
+  auto memoryReference = GetString(arguments, "memoryReference");
+  lldb::addr_t addr;
+  if (memoryReference.consumeInteger(0, addr)) {

vogelsgesang wrote:

To my understanding, `GetUnsigned` works for JSON request similar to 
`{"memoryReference": 1234 }`. However, memory references are string-typed and 
not integer-typed. The request we are receiving has the form 
`{"memoryReference": "0x1234"}`

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


[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-15 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-15 Thread Adrian Vogelsgesang via lldb-commits


@@ -4028,6 +4049,154 @@ void request_disassemble(const llvm::json::Object 
&request) {
   response.try_emplace("body", std::move(body));
   g_dap.SendJSON(llvm::json::Value(std::move(response)));
 }
+
+// "ReadMemoryRequest": {
+//   "allOf": [ { "$ref": "#/definitions/Request" }, {
+// "type": "object",
+// "description": "Reads bytes from memory at the provided location. 
Clients
+// should only call this request if the corresponding
+// capability `supportsReadMemoryRequest` is true.",
+// "properties": {
+//   "command": {
+// "type": "string",
+// "enum": [ "readMemory" ]
+//   },
+//   "arguments": {
+// "$ref": "#/definitions/ReadMemoryArguments"
+//   }
+// },
+// "required": [ "command", "arguments" ]
+//   }]
+// },
+// "ReadMemoryArguments": {
+//   "type": "object",
+//   "description": "Arguments for `readMemory` request.",
+//   "properties": {
+// "memoryReference": {
+//   "type": "string",
+//   "description": "Memory reference to the base location from which data
+//   should be read."
+// },
+// "offset": {
+//   "type": "integer",
+//   "description": "Offset (in bytes) to be applied to the reference
+//   location before reading data. Can be negative."
+// },
+// "count": {
+//   "type": "integer",
+//   "description": "Number of bytes to read at the specified location and
+//   offset."
+// }
+//   },
+//   "required": [ "memoryReference", "count" ]
+// },
+// "ReadMemoryResponse": {
+//   "allOf": [ { "$ref": "#/definitions/Response" }, {
+// "type": "object",
+// "description": "Response to `readMemory` request.",
+// "properties": {
+//   "body": {
+// "type": "object",
+// "properties": {
+//   "address": {
+// "type": "string",
+// "description": "The address of the first byte of data returned.
+// Treated as a hex value if prefixed with `0x`, or
+// as a decimal value otherwise."
+//   },
+//   "unreadableBytes": {
+// "type": "integer",
+// "description": "The number of unreadable bytes encountered after
+// the last successfully read byte.\nThis can be
+// used to determine the number of bytes that 
should
+// be skipped before a subsequent
+// `readMemory` request succeeds."
+//   },
+//   "data": {
+// "type": "string",
+// "description": "The bytes read from memory, encoded using 
base64.
+// If the decoded length of `data` is less than the
+// requested `count` in the original `readMemory`
+// request, and `unreadableBytes` is zero or
+// omitted, then the client should assume it's
+// reached the end of readable memory."
+//   }
+// },
+// "required": [ "address" ]
+//   }
+// }
+//   }]
+// },
+void request_readMemory(const llvm::json::Object &request) {
+  llvm::json::Object response;
+  FillResponse(request, response);
+  auto arguments = request.getObject("arguments");
+
+  lldb::SBProcess process = g_dap.target.GetProcess();
+  if (!process.IsValid()) {
+response["success"] = false;
+response["message"] = "No process running";
+g_dap.SendJSON(llvm::json::Value(std::move(response)));
+return;
+  }
+
+  auto memoryReference = GetString(arguments, "memoryReference");
+  lldb::addr_t addr;
+  if (memoryReference.consumeInteger(0, addr)) {

vogelsgesang wrote:

FWIW, I copied used `request_disassemble` as inspiration here

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


[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-15 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/104317

>From a5b4f6e7e105d36b82f9de588d2705ad3d622953 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Wed, 14 Aug 2024 11:52:40 +
Subject: [PATCH 1/4] [lldb-dap] Support inspecting memory

Adds support for the `readMemory` request which allows VS-Code to
inspect memory. Also, add `memoryReference` to variablesa and `evaluate`
responses, such that the binary view can be opened from the variables
view and from the "watch" pane.
---
 .../test/tools/lldb-dap/dap_server.py |  13 ++
 lldb/test/API/tools/lldb-dap/memory/Makefile  |   3 +
 .../tools/lldb-dap/memory/TestDAP_memory.py   | 135 ++
 lldb/test/API/tools/lldb-dap/memory/main.cpp  |  10 +
 lldb/tools/lldb-dap/JSONUtils.cpp |  29 ++-
 lldb/tools/lldb-dap/JSONUtils.h   |   6 +
 lldb/tools/lldb-dap/lldb-dap.cpp  | 172 +-
 7 files changed, 365 insertions(+), 3 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/main.cpp

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..da10e8ab5c57c2 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -691,6 +691,19 @@ def request_disassemble(
 for inst in instructions:
 self.disassembled_instructions[inst["address"]] = inst
 
+def request_read_memory(self, memoryReference, offset, count):
+args_dict = {
+"memoryReference": memoryReference,
+"offset": offset,
+"count": count,
+}
+command_dict = {
+"command": "readMemory",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_evaluate(self, expression, frameIndex=0, threadId=None, 
context=None):
 stackFrame = self.get_stackFrame(frameIndex=frameIndex, 
threadId=threadId)
 if stackFrame is None:
diff --git a/lldb/test/API/tools/lldb-dap/memory/Makefile 
b/lldb/test/API/tools/lldb-dap/memory/Makefile
new file mode 100644
index 00..8b20bcb050
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py 
b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
new file mode 100644
index 00..f950d5eecda671
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
@@ -0,0 +1,135 @@
+"""
+Test lldb-dap memory support
+"""
+
+from base64 import b64decode
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase):
+def test_read_memory(self):
+"""
+Tests the 'read_memory' request
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.cpp"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// Breakpoint")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+rawptr_ref = locals["rawptr"]["memoryReference"]
+
+# We can read the complete string
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 5)["body"]
+self.assertEqual(mem["unreadableBytes"], 0)
+self.assertEqual(b64decode(mem["data"]), b"dead\0")
+
+# Use an offset
+mem = self.dap_server.request_read_memory(rawptr_ref, 2, 3)["body"]
+self.assertEqual(b64decode(mem["data"]), b"ad\0")
+
+# Use a negative offset
+mem = self.dap_server.request_read_memory(rawptr_ref, -1, 6)["body"]
+self.assertEqual(b64decode(mem["data"])[1:], b"dead\0")
+
+# Reads of size 0 are successful
+# VS-Code sends those in order to check if a `memoryReference` can 
actually be dereferenced.
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 0)
+self.assertEqual(mem["success"], True)
+self.assertEqual(mem["body"]["data"], "")
+
+# Reads at offset 0x0 fail
+mem = self.dap_server.request_read_memory("0x0", 0, 6)
+self.assertEqual(mem["success"], False)
+self.assertTrue(mem["message"].startswith("Unable to read memory: "))
+
+def test_memory_refs_variables(self):
+"""
+Tests memory references for evaluate
+"""
+   

[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-15 Thread Adrian Vogelsgesang via lldb-commits


@@ -4028,6 +4049,154 @@ void request_disassemble(const llvm::json::Object 
&request) {
   response.try_emplace("body", std::move(body));
   g_dap.SendJSON(llvm::json::Value(std::move(response)));
 }
+
+// "ReadMemoryRequest": {
+//   "allOf": [ { "$ref": "#/definitions/Request" }, {
+// "type": "object",
+// "description": "Reads bytes from memory at the provided location. 
Clients
+// should only call this request if the corresponding
+// capability `supportsReadMemoryRequest` is true.",
+// "properties": {
+//   "command": {
+// "type": "string",
+// "enum": [ "readMemory" ]
+//   },
+//   "arguments": {
+// "$ref": "#/definitions/ReadMemoryArguments"
+//   }
+// },
+// "required": [ "command", "arguments" ]
+//   }]
+// },
+// "ReadMemoryArguments": {
+//   "type": "object",
+//   "description": "Arguments for `readMemory` request.",
+//   "properties": {
+// "memoryReference": {
+//   "type": "string",
+//   "description": "Memory reference to the base location from which data
+//   should be read."
+// },
+// "offset": {
+//   "type": "integer",
+//   "description": "Offset (in bytes) to be applied to the reference
+//   location before reading data. Can be negative."
+// },
+// "count": {
+//   "type": "integer",
+//   "description": "Number of bytes to read at the specified location and
+//   offset."
+// }
+//   },
+//   "required": [ "memoryReference", "count" ]
+// },
+// "ReadMemoryResponse": {
+//   "allOf": [ { "$ref": "#/definitions/Response" }, {
+// "type": "object",
+// "description": "Response to `readMemory` request.",
+// "properties": {
+//   "body": {
+// "type": "object",
+// "properties": {
+//   "address": {
+// "type": "string",
+// "description": "The address of the first byte of data returned.
+// Treated as a hex value if prefixed with `0x`, or
+// as a decimal value otherwise."
+//   },
+//   "unreadableBytes": {
+// "type": "integer",
+// "description": "The number of unreadable bytes encountered after
+// the last successfully read byte.\nThis can be
+// used to determine the number of bytes that 
should
+// be skipped before a subsequent
+// `readMemory` request succeeds."
+//   },
+//   "data": {
+// "type": "string",
+// "description": "The bytes read from memory, encoded using 
base64.
+// If the decoded length of `data` is less than the
+// requested `count` in the original `readMemory`
+// request, and `unreadableBytes` is zero or
+// omitted, then the client should assume it's
+// reached the end of readable memory."
+//   }
+// },
+// "required": [ "address" ]
+//   }
+// }
+//   }]
+// },
+void request_readMemory(const llvm::json::Object &request) {
+  llvm::json::Object response;
+  FillResponse(request, response);
+  auto arguments = request.getObject("arguments");
+
+  lldb::SBProcess process = g_dap.target.GetProcess();
+  if (!process.IsValid()) {
+response["success"] = false;
+response["message"] = "No process running";
+g_dap.SendJSON(llvm::json::Value(std::move(response)));
+return;
+  }
+
+  auto memoryReference = GetString(arguments, "memoryReference");
+  lldb::addr_t addr;
+  if (memoryReference.consumeInteger(0, addr)) {
+response["success"] = false;
+response["message"] =
+"Malformed memory reference: " + memoryReference.str();
+g_dap.SendJSON(llvm::json::Value(std::move(response)));
+return;
+  }
+
+  addr += GetSigned(arguments, "offset", 0);
+  const auto requested_count = GetUnsigned(arguments, "count", 0);
+  lldb::SBMemoryRegionInfo region_info;
+  lldb::SBError memRegError = process.GetMemoryRegionInfo(addr, region_info);
+  if (memRegError.Fail()) {
+response["success"] = false;
+EmplaceSafeString(response, "message",
+  "Unable to find memory region: " +
+  std::string(memRegError.GetCString()));
+g_dap.SendJSON(llvm::json::Value(std::move(response)));
+return;
+  }
+  const auto available_count =
+  std::min(requested_count, region_info.GetRegionEnd() - addr);
+  const auto unavailable_count = requested_count - available_count;
+
+  std::vector buf;
+  buf.resize(available_count);
+  if (available_count > 0) {
+lldb::SBError memReadError;
+auto bytes_read =
+process.ReadMemory(addr, buf.data(), available_count, memReadError);
+if (memReadEr

[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-15 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/104317

>From a5b4f6e7e105d36b82f9de588d2705ad3d622953 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Wed, 14 Aug 2024 11:52:40 +
Subject: [PATCH 1/5] [lldb-dap] Support inspecting memory

Adds support for the `readMemory` request which allows VS-Code to
inspect memory. Also, add `memoryReference` to variablesa and `evaluate`
responses, such that the binary view can be opened from the variables
view and from the "watch" pane.
---
 .../test/tools/lldb-dap/dap_server.py |  13 ++
 lldb/test/API/tools/lldb-dap/memory/Makefile  |   3 +
 .../tools/lldb-dap/memory/TestDAP_memory.py   | 135 ++
 lldb/test/API/tools/lldb-dap/memory/main.cpp  |  10 +
 lldb/tools/lldb-dap/JSONUtils.cpp |  29 ++-
 lldb/tools/lldb-dap/JSONUtils.h   |   6 +
 lldb/tools/lldb-dap/lldb-dap.cpp  | 172 +-
 7 files changed, 365 insertions(+), 3 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/main.cpp

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..da10e8ab5c57c2 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -691,6 +691,19 @@ def request_disassemble(
 for inst in instructions:
 self.disassembled_instructions[inst["address"]] = inst
 
+def request_read_memory(self, memoryReference, offset, count):
+args_dict = {
+"memoryReference": memoryReference,
+"offset": offset,
+"count": count,
+}
+command_dict = {
+"command": "readMemory",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_evaluate(self, expression, frameIndex=0, threadId=None, 
context=None):
 stackFrame = self.get_stackFrame(frameIndex=frameIndex, 
threadId=threadId)
 if stackFrame is None:
diff --git a/lldb/test/API/tools/lldb-dap/memory/Makefile 
b/lldb/test/API/tools/lldb-dap/memory/Makefile
new file mode 100644
index 00..8b20bcb050
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py 
b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
new file mode 100644
index 00..f950d5eecda671
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
@@ -0,0 +1,135 @@
+"""
+Test lldb-dap memory support
+"""
+
+from base64 import b64decode
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase):
+def test_read_memory(self):
+"""
+Tests the 'read_memory' request
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.cpp"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// Breakpoint")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+rawptr_ref = locals["rawptr"]["memoryReference"]
+
+# We can read the complete string
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 5)["body"]
+self.assertEqual(mem["unreadableBytes"], 0)
+self.assertEqual(b64decode(mem["data"]), b"dead\0")
+
+# Use an offset
+mem = self.dap_server.request_read_memory(rawptr_ref, 2, 3)["body"]
+self.assertEqual(b64decode(mem["data"]), b"ad\0")
+
+# Use a negative offset
+mem = self.dap_server.request_read_memory(rawptr_ref, -1, 6)["body"]
+self.assertEqual(b64decode(mem["data"])[1:], b"dead\0")
+
+# Reads of size 0 are successful
+# VS-Code sends those in order to check if a `memoryReference` can 
actually be dereferenced.
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 0)
+self.assertEqual(mem["success"], True)
+self.assertEqual(mem["body"]["data"], "")
+
+# Reads at offset 0x0 fail
+mem = self.dap_server.request_read_memory("0x0", 0, 6)
+self.assertEqual(mem["success"], False)
+self.assertTrue(mem["message"].startswith("Unable to read memory: "))
+
+def test_memory_refs_variables(self):
+"""
+Tests memory references for evaluate
+"""
+   

[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-15 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/104317

>From a5b4f6e7e105d36b82f9de588d2705ad3d622953 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Wed, 14 Aug 2024 11:52:40 +
Subject: [PATCH 1/5] [lldb-dap] Support inspecting memory

Adds support for the `readMemory` request which allows VS-Code to
inspect memory. Also, add `memoryReference` to variablesa and `evaluate`
responses, such that the binary view can be opened from the variables
view and from the "watch" pane.
---
 .../test/tools/lldb-dap/dap_server.py |  13 ++
 lldb/test/API/tools/lldb-dap/memory/Makefile  |   3 +
 .../tools/lldb-dap/memory/TestDAP_memory.py   | 135 ++
 lldb/test/API/tools/lldb-dap/memory/main.cpp  |  10 +
 lldb/tools/lldb-dap/JSONUtils.cpp |  29 ++-
 lldb/tools/lldb-dap/JSONUtils.h   |   6 +
 lldb/tools/lldb-dap/lldb-dap.cpp  | 172 +-
 7 files changed, 365 insertions(+), 3 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/main.cpp

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..da10e8ab5c57c2 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -691,6 +691,19 @@ def request_disassemble(
 for inst in instructions:
 self.disassembled_instructions[inst["address"]] = inst
 
+def request_read_memory(self, memoryReference, offset, count):
+args_dict = {
+"memoryReference": memoryReference,
+"offset": offset,
+"count": count,
+}
+command_dict = {
+"command": "readMemory",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_evaluate(self, expression, frameIndex=0, threadId=None, 
context=None):
 stackFrame = self.get_stackFrame(frameIndex=frameIndex, 
threadId=threadId)
 if stackFrame is None:
diff --git a/lldb/test/API/tools/lldb-dap/memory/Makefile 
b/lldb/test/API/tools/lldb-dap/memory/Makefile
new file mode 100644
index 00..8b20bcb050
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py 
b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
new file mode 100644
index 00..f950d5eecda671
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
@@ -0,0 +1,135 @@
+"""
+Test lldb-dap memory support
+"""
+
+from base64 import b64decode
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase):
+def test_read_memory(self):
+"""
+Tests the 'read_memory' request
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.cpp"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// Breakpoint")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+rawptr_ref = locals["rawptr"]["memoryReference"]
+
+# We can read the complete string
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 5)["body"]
+self.assertEqual(mem["unreadableBytes"], 0)
+self.assertEqual(b64decode(mem["data"]), b"dead\0")
+
+# Use an offset
+mem = self.dap_server.request_read_memory(rawptr_ref, 2, 3)["body"]
+self.assertEqual(b64decode(mem["data"]), b"ad\0")
+
+# Use a negative offset
+mem = self.dap_server.request_read_memory(rawptr_ref, -1, 6)["body"]
+self.assertEqual(b64decode(mem["data"])[1:], b"dead\0")
+
+# Reads of size 0 are successful
+# VS-Code sends those in order to check if a `memoryReference` can 
actually be dereferenced.
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 0)
+self.assertEqual(mem["success"], True)
+self.assertEqual(mem["body"]["data"], "")
+
+# Reads at offset 0x0 fail
+mem = self.dap_server.request_read_memory("0x0", 0, 6)
+self.assertEqual(mem["success"], False)
+self.assertTrue(mem["message"].startswith("Unable to read memory: "))
+
+def test_memory_refs_variables(self):
+"""
+Tests memory references for evaluate
+"""
+   

[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-15 Thread Adrian Vogelsgesang via lldb-commits


@@ -1085,6 +1085,19 @@ std::string 
VariableDescription::GetResult(llvm::StringRef context) {
   return description.trim().str();
 }
 
+lldb::addr_t GetMemoryReference(lldb::SBValue v) {
+  if (!v.GetType().IsPointerType() && !v.GetType().IsArrayType()) {
+return LLDB_INVALID_ADDRESS;
+  }
+
+  lldb::SBValue deref = v.Dereference();
+  if (!deref.IsValid()) {
+return LLDB_INVALID_ADDRESS;
+  }
+
+  return deref.GetLoadAddress();

vogelsgesang wrote:

I addressed the stylistic parts of this comment (`std::optional`, don't check 
if `Derefence()` succeeded, ...).

I am not 100% sure regarding the proposed semantic changes, though, in 
particular about

```
if (v_type.IsPointerType() || v_type.IsReferenceType())
v = v.Dereference();
```

This change would lead to a test case failure in the newly added memory tests. 
The `int not_a_ptr` would now have a memory reference associated. To my 
understanding of the intended debugging semantics of the DAP, it should not 
have an associated memory reference, though, since it is not a pointer or 
pointer-like type

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


[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-15 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

Thanks for the super-fast review, @clayborg! I addressed all the 
straightforward issues and replied to the non-straightforward ones

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


[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-15 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Expose log path in extension settings (PR #103482)

2024-08-15 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/102928

>From a740c6918fd4c0e47b6d266fbb2b217112405a4f Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Sat, 10 Aug 2024 23:59:55 +
Subject: [PATCH] [lldb-dap] Implement declaration locations

This commit implements support for the "declaration location" recently
added by microsoft/debug-adapter-protocol#494 to the debug adapter
protocol.

For the `declarationLocationReference` we need a variable ID similar to
the the `variablesReference`. I decided to simply reuse the
`variablesReference` here and renamed `Variables::expandable_variables`
and friends accordingly. Given that almost all variables have a
declaration location, we now assign those variable ids to all variables.

While `declarationLocationReference` effectively supersedes
`$__lldb_extensions.declaration`, I did not remove this extension, yet,
since I assume that there are some closed-source extensions which rely
on it.

I tested this against VS-Code Insiders. However, VS-Code Insiders
currently only supports `valueLoctionReference` and not
`declarationLocationReference`, yet. Locally, I hence tried to publish
the declaration locations as value locations. However, it seems that
VS-Code still has issues with correctly resolving file paths, as
reported in 
https://github.com/microsoft/vscode/pull/225546#issuecomment-2292428591
---
 .../test/tools/lldb-dap/dap_server.py |  11 ++
 .../API/tools/lldb-dap/locations/Makefile |   3 +
 .../lldb-dap/locations/TestDAP_locations.py   |  38 +
 lldb/test/API/tools/lldb-dap/locations/main.c |   5 +
 lldb/tools/lldb-dap/DAP.cpp   |  18 +--
 lldb/tools/lldb-dap/DAP.h |  10 +-
 lldb/tools/lldb-dap/JSONUtils.cpp | 125 ---
 lldb/tools/lldb-dap/JSONUtils.h   |  31 ++--
 lldb/tools/lldb-dap/lldb-dap.cpp  | 146 +++---
 9 files changed, 285 insertions(+), 102 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..9879a34ed2020c 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -1079,6 +1079,17 @@ def request_setVariable(self, containingVarRef, name, 
value, id=None):
 }
 return self.send_recv(command_dict)
 
+def request_locations(self, locationReference):
+args_dict = {
+"locationReference": locationReference,
+}
+command_dict = {
+"command": "locations",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_testGetTargetBreakpoints(self):
 """A request packet used in the LLDB test suite to get all currently
 set breakpoint infos for all breakpoints currently set in the
diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile 
b/lldb/test/API/tools/lldb-dap/locations/Makefile
new file mode 100644
index 00..10495940055b63
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py 
b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
new file mode 100644
index 00..26feb789db39d6
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
@@ -0,0 +1,38 @@
+"""
+Test lldb-dap locations request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase):
+@skipIfWindows
+def test_locations(self):
+"""
+Tests the 'locations' request.
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.c"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// BREAK HERE")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+
+# var1 has a declarationLocation but no valueLocation
+self.assertIn("declarationLocationReference", locals["var1"].keys())
+self.assertNotIn("valueLocationReference", locals["var1"].keys())
+loc_var1 = 
self.dap_server.request_locations(locals["var1"]["declarationLocationReference"])
+self.assertTrue(loc_var1["su

[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

Ok, this is ready for review now. The upstream protocol changes were merged in 
the meantime.

I did leave in the `$__lldb_extensions.declaration` although it is superseded 
by the `declarationLocationReference`. Let me know in case you prefer me to 
remove it

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/102928

>From a740c6918fd4c0e47b6d266fbb2b217112405a4f Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Sat, 10 Aug 2024 23:59:55 +
Subject: [PATCH 1/2] [lldb-dap] Implement declaration locations

This commit implements support for the "declaration location" recently
added by microsoft/debug-adapter-protocol#494 to the debug adapter
protocol.

For the `declarationLocationReference` we need a variable ID similar to
the the `variablesReference`. I decided to simply reuse the
`variablesReference` here and renamed `Variables::expandable_variables`
and friends accordingly. Given that almost all variables have a
declaration location, we now assign those variable ids to all variables.

While `declarationLocationReference` effectively supersedes
`$__lldb_extensions.declaration`, I did not remove this extension, yet,
since I assume that there are some closed-source extensions which rely
on it.

I tested this against VS-Code Insiders. However, VS-Code Insiders
currently only supports `valueLoctionReference` and not
`declarationLocationReference`, yet. Locally, I hence tried to publish
the declaration locations as value locations. However, it seems that
VS-Code still has issues with correctly resolving file paths, as
reported in 
https://github.com/microsoft/vscode/pull/225546#issuecomment-2292428591
---
 .../test/tools/lldb-dap/dap_server.py |  11 ++
 .../API/tools/lldb-dap/locations/Makefile |   3 +
 .../lldb-dap/locations/TestDAP_locations.py   |  38 +
 lldb/test/API/tools/lldb-dap/locations/main.c |   5 +
 lldb/tools/lldb-dap/DAP.cpp   |  18 +--
 lldb/tools/lldb-dap/DAP.h |  10 +-
 lldb/tools/lldb-dap/JSONUtils.cpp | 125 ---
 lldb/tools/lldb-dap/JSONUtils.h   |  31 ++--
 lldb/tools/lldb-dap/lldb-dap.cpp  | 146 +++---
 9 files changed, 285 insertions(+), 102 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..9879a34ed2020c 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -1079,6 +1079,17 @@ def request_setVariable(self, containingVarRef, name, 
value, id=None):
 }
 return self.send_recv(command_dict)
 
+def request_locations(self, locationReference):
+args_dict = {
+"locationReference": locationReference,
+}
+command_dict = {
+"command": "locations",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_testGetTargetBreakpoints(self):
 """A request packet used in the LLDB test suite to get all currently
 set breakpoint infos for all breakpoints currently set in the
diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile 
b/lldb/test/API/tools/lldb-dap/locations/Makefile
new file mode 100644
index 00..10495940055b63
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py 
b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
new file mode 100644
index 00..26feb789db39d6
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
@@ -0,0 +1,38 @@
+"""
+Test lldb-dap locations request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase):
+@skipIfWindows
+def test_locations(self):
+"""
+Tests the 'locations' request.
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.c"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// BREAK HERE")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+
+# var1 has a declarationLocation but no valueLocation
+self.assertIn("declarationLocationReference", locals["var1"].keys())
+self.assertNotIn("valueLocationReference", locals["var1"].keys())
+loc_var1 = 
self.dap_server.request_locations(locals["var1"]["declarationLocationReference"])
+self.assertTrue(loc_var1

[Lldb-commits] [lldb] [lldb-dap] Expose log path in extension settings (PR #103482)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

@JDevlieghere it seems that the automation for publishing a new VS-Code 
extension to the MarketPlace did not kick off automatically. Could you dispatch 
the "Publish to VSCode Marketplace" flow manually?

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


[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits


@@ -4028,6 +4049,154 @@ void request_disassemble(const llvm::json::Object 
&request) {
   response.try_emplace("body", std::move(body));
   g_dap.SendJSON(llvm::json::Value(std::move(response)));
 }
+
+// "ReadMemoryRequest": {
+//   "allOf": [ { "$ref": "#/definitions/Request" }, {
+// "type": "object",
+// "description": "Reads bytes from memory at the provided location. 
Clients
+// should only call this request if the corresponding
+// capability `supportsReadMemoryRequest` is true.",
+// "properties": {
+//   "command": {
+// "type": "string",
+// "enum": [ "readMemory" ]
+//   },
+//   "arguments": {
+// "$ref": "#/definitions/ReadMemoryArguments"
+//   }
+// },
+// "required": [ "command", "arguments" ]
+//   }]
+// },
+// "ReadMemoryArguments": {
+//   "type": "object",
+//   "description": "Arguments for `readMemory` request.",
+//   "properties": {
+// "memoryReference": {
+//   "type": "string",
+//   "description": "Memory reference to the base location from which data
+//   should be read."
+// },
+// "offset": {
+//   "type": "integer",
+//   "description": "Offset (in bytes) to be applied to the reference
+//   location before reading data. Can be negative."
+// },
+// "count": {
+//   "type": "integer",
+//   "description": "Number of bytes to read at the specified location and
+//   offset."
+// }
+//   },
+//   "required": [ "memoryReference", "count" ]
+// },
+// "ReadMemoryResponse": {
+//   "allOf": [ { "$ref": "#/definitions/Response" }, {
+// "type": "object",
+// "description": "Response to `readMemory` request.",
+// "properties": {
+//   "body": {
+// "type": "object",
+// "properties": {
+//   "address": {
+// "type": "string",
+// "description": "The address of the first byte of data returned.
+// Treated as a hex value if prefixed with `0x`, or
+// as a decimal value otherwise."
+//   },
+//   "unreadableBytes": {
+// "type": "integer",
+// "description": "The number of unreadable bytes encountered after
+// the last successfully read byte.\nThis can be
+// used to determine the number of bytes that 
should
+// be skipped before a subsequent
+// `readMemory` request succeeds."
+//   },
+//   "data": {
+// "type": "string",
+// "description": "The bytes read from memory, encoded using 
base64.
+// If the decoded length of `data` is less than the
+// requested `count` in the original `readMemory`
+// request, and `unreadableBytes` is zero or
+// omitted, then the client should assume it's
+// reached the end of readable memory."
+//   }
+// },
+// "required": [ "address" ]
+//   }
+// }
+//   }]
+// },
+void request_readMemory(const llvm::json::Object &request) {
+  llvm::json::Object response;
+  FillResponse(request, response);
+  auto arguments = request.getObject("arguments");
+
+  lldb::SBProcess process = g_dap.target.GetProcess();
+  if (!process.IsValid()) {
+response["success"] = false;
+response["message"] = "No process running";
+g_dap.SendJSON(llvm::json::Value(std::move(response)));
+return;
+  }
+
+  auto memoryReference = GetString(arguments, "memoryReference");
+  lldb::addr_t addr;
+  if (memoryReference.consumeInteger(0, addr)) {

vogelsgesang wrote:

> Gotcha, that is interesting. I guess they let you encode and decode a 
> memoryReference how ever you want then right?

Correct. The memory reference is actually also displayed to the user, 
highlighted in red in the following screenshot.

![memref](https://github.com/user-attachments/assets/3a5697a3-b668-40ea-879f-b1a27080ddaf)

Also for single-address-space architectures, I could imagine that it would be 
useful to have memory references like `.rodata + 0x1234` based on the section 
names or `my_function + 0x1234` based on symbol names. Those memory references 
would convey more information to the user, and would also be stable across 
restarts where ASLR might shuffle the sections around. But that's an idea for 
another day / another commit

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


[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/104317

>From a5b4f6e7e105d36b82f9de588d2705ad3d622953 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Wed, 14 Aug 2024 11:52:40 +
Subject: [PATCH 1/6] [lldb-dap] Support inspecting memory

Adds support for the `readMemory` request which allows VS-Code to
inspect memory. Also, add `memoryReference` to variablesa and `evaluate`
responses, such that the binary view can be opened from the variables
view and from the "watch" pane.
---
 .../test/tools/lldb-dap/dap_server.py |  13 ++
 lldb/test/API/tools/lldb-dap/memory/Makefile  |   3 +
 .../tools/lldb-dap/memory/TestDAP_memory.py   | 135 ++
 lldb/test/API/tools/lldb-dap/memory/main.cpp  |  10 +
 lldb/tools/lldb-dap/JSONUtils.cpp |  29 ++-
 lldb/tools/lldb-dap/JSONUtils.h   |   6 +
 lldb/tools/lldb-dap/lldb-dap.cpp  | 172 +-
 7 files changed, 365 insertions(+), 3 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/main.cpp

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..da10e8ab5c57c2 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -691,6 +691,19 @@ def request_disassemble(
 for inst in instructions:
 self.disassembled_instructions[inst["address"]] = inst
 
+def request_read_memory(self, memoryReference, offset, count):
+args_dict = {
+"memoryReference": memoryReference,
+"offset": offset,
+"count": count,
+}
+command_dict = {
+"command": "readMemory",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_evaluate(self, expression, frameIndex=0, threadId=None, 
context=None):
 stackFrame = self.get_stackFrame(frameIndex=frameIndex, 
threadId=threadId)
 if stackFrame is None:
diff --git a/lldb/test/API/tools/lldb-dap/memory/Makefile 
b/lldb/test/API/tools/lldb-dap/memory/Makefile
new file mode 100644
index 00..8b20bcb050
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py 
b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
new file mode 100644
index 00..f950d5eecda671
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
@@ -0,0 +1,135 @@
+"""
+Test lldb-dap memory support
+"""
+
+from base64 import b64decode
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase):
+def test_read_memory(self):
+"""
+Tests the 'read_memory' request
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.cpp"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// Breakpoint")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+rawptr_ref = locals["rawptr"]["memoryReference"]
+
+# We can read the complete string
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 5)["body"]
+self.assertEqual(mem["unreadableBytes"], 0)
+self.assertEqual(b64decode(mem["data"]), b"dead\0")
+
+# Use an offset
+mem = self.dap_server.request_read_memory(rawptr_ref, 2, 3)["body"]
+self.assertEqual(b64decode(mem["data"]), b"ad\0")
+
+# Use a negative offset
+mem = self.dap_server.request_read_memory(rawptr_ref, -1, 6)["body"]
+self.assertEqual(b64decode(mem["data"])[1:], b"dead\0")
+
+# Reads of size 0 are successful
+# VS-Code sends those in order to check if a `memoryReference` can 
actually be dereferenced.
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 0)
+self.assertEqual(mem["success"], True)
+self.assertEqual(mem["body"]["data"], "")
+
+# Reads at offset 0x0 fail
+mem = self.dap_server.request_read_memory("0x0", 0, 6)
+self.assertEqual(mem["success"], False)
+self.assertTrue(mem["message"].startswith("Unable to read memory: "))
+
+def test_memory_refs_variables(self):
+"""
+Tests memory references for evaluate
+"""
+   

[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits


@@ -4028,6 +4049,154 @@ void request_disassemble(const llvm::json::Object 
&request) {
   response.try_emplace("body", std::move(body));
   g_dap.SendJSON(llvm::json::Value(std::move(response)));
 }
+
+// "ReadMemoryRequest": {
+//   "allOf": [ { "$ref": "#/definitions/Request" }, {
+// "type": "object",
+// "description": "Reads bytes from memory at the provided location. 
Clients
+// should only call this request if the corresponding
+// capability `supportsReadMemoryRequest` is true.",
+// "properties": {
+//   "command": {
+// "type": "string",
+// "enum": [ "readMemory" ]
+//   },
+//   "arguments": {
+// "$ref": "#/definitions/ReadMemoryArguments"
+//   }
+// },
+// "required": [ "command", "arguments" ]
+//   }]
+// },
+// "ReadMemoryArguments": {
+//   "type": "object",
+//   "description": "Arguments for `readMemory` request.",
+//   "properties": {
+// "memoryReference": {
+//   "type": "string",
+//   "description": "Memory reference to the base location from which data
+//   should be read."
+// },
+// "offset": {
+//   "type": "integer",
+//   "description": "Offset (in bytes) to be applied to the reference
+//   location before reading data. Can be negative."
+// },
+// "count": {
+//   "type": "integer",
+//   "description": "Number of bytes to read at the specified location and
+//   offset."
+// }
+//   },
+//   "required": [ "memoryReference", "count" ]
+// },
+// "ReadMemoryResponse": {
+//   "allOf": [ { "$ref": "#/definitions/Response" }, {
+// "type": "object",
+// "description": "Response to `readMemory` request.",
+// "properties": {
+//   "body": {
+// "type": "object",
+// "properties": {
+//   "address": {
+// "type": "string",
+// "description": "The address of the first byte of data returned.
+// Treated as a hex value if prefixed with `0x`, or
+// as a decimal value otherwise."
+//   },
+//   "unreadableBytes": {
+// "type": "integer",
+// "description": "The number of unreadable bytes encountered after
+// the last successfully read byte.\nThis can be
+// used to determine the number of bytes that 
should
+// be skipped before a subsequent
+// `readMemory` request succeeds."
+//   },
+//   "data": {
+// "type": "string",
+// "description": "The bytes read from memory, encoded using 
base64.
+// If the decoded length of `data` is less than the
+// requested `count` in the original `readMemory`
+// request, and `unreadableBytes` is zero or
+// omitted, then the client should assume it's
+// reached the end of readable memory."
+//   }
+// },
+// "required": [ "address" ]
+//   }
+// }
+//   }]
+// },
+void request_readMemory(const llvm::json::Object &request) {
+  llvm::json::Object response;
+  FillResponse(request, response);
+  auto arguments = request.getObject("arguments");
+
+  lldb::SBProcess process = g_dap.target.GetProcess();
+  if (!process.IsValid()) {
+response["success"] = false;
+response["message"] = "No process running";
+g_dap.SendJSON(llvm::json::Value(std::move(response)));
+return;
+  }
+
+  auto memoryReference = GetString(arguments, "memoryReference");
+  lldb::addr_t addr;
+  if (memoryReference.consumeInteger(0, addr)) {

vogelsgesang wrote:

> we probably want two functions to encode and decode memoryReferences to/fromt 
> strings in JSONUtils

done

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


[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits


@@ -1085,6 +1085,19 @@ std::string 
VariableDescription::GetResult(llvm::StringRef context) {
   return description.trim().str();
 }
 
+lldb::addr_t GetMemoryReference(lldb::SBValue v) {
+  if (!v.GetType().IsPointerType() && !v.GetType().IsArrayType()) {
+return LLDB_INVALID_ADDRESS;
+  }
+
+  lldb::SBValue deref = v.Dereference();
+  if (!deref.IsValid()) {
+return LLDB_INVALID_ADDRESS;
+  }
+
+  return deref.GetLoadAddress();

vogelsgesang wrote:

Continued in 
https://github.com/llvm/llvm-project/pull/104317#discussion_r1719180273

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


[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits


@@ -1085,6 +1084,17 @@ std::string 
VariableDescription::GetResult(llvm::StringRef context) {
   return description.trim().str();
 }
 
+std::optional GetMemoryReference(lldb::SBValue v) {
+  if (!v.GetType().IsPointerType() && !v.GetType().IsArrayType())
+return std::nullopt;
+

vogelsgesang wrote:

The proposed code would led to `my_value` and `my_ptr` having the same 
`memoryReference` in the following code snippet:

```
   int my_value;
   int* my_ptr = &my_value;
```

Also, when entering `my_value` and `&my_value` into the debug console, I would 
get the same memory references back. As a user, I would find this very 
confusing.

As such, I do prefer the current semantics, where `my_value` does not have a 
memory reference. If users want to get to that memory location, they can use 
`&my_value`

(Also, I noticed that the current code did not work for arrays. Hence, I 
removed the `IsArrayType`)

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


[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/104317

>From a5b4f6e7e105d36b82f9de588d2705ad3d622953 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Wed, 14 Aug 2024 11:52:40 +
Subject: [PATCH 1/7] [lldb-dap] Support inspecting memory

Adds support for the `readMemory` request which allows VS-Code to
inspect memory. Also, add `memoryReference` to variablesa and `evaluate`
responses, such that the binary view can be opened from the variables
view and from the "watch" pane.
---
 .../test/tools/lldb-dap/dap_server.py |  13 ++
 lldb/test/API/tools/lldb-dap/memory/Makefile  |   3 +
 .../tools/lldb-dap/memory/TestDAP_memory.py   | 135 ++
 lldb/test/API/tools/lldb-dap/memory/main.cpp  |  10 +
 lldb/tools/lldb-dap/JSONUtils.cpp |  29 ++-
 lldb/tools/lldb-dap/JSONUtils.h   |   6 +
 lldb/tools/lldb-dap/lldb-dap.cpp  | 172 +-
 7 files changed, 365 insertions(+), 3 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
 create mode 100644 lldb/test/API/tools/lldb-dap/memory/main.cpp

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..da10e8ab5c57c2 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -691,6 +691,19 @@ def request_disassemble(
 for inst in instructions:
 self.disassembled_instructions[inst["address"]] = inst
 
+def request_read_memory(self, memoryReference, offset, count):
+args_dict = {
+"memoryReference": memoryReference,
+"offset": offset,
+"count": count,
+}
+command_dict = {
+"command": "readMemory",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_evaluate(self, expression, frameIndex=0, threadId=None, 
context=None):
 stackFrame = self.get_stackFrame(frameIndex=frameIndex, 
threadId=threadId)
 if stackFrame is None:
diff --git a/lldb/test/API/tools/lldb-dap/memory/Makefile 
b/lldb/test/API/tools/lldb-dap/memory/Makefile
new file mode 100644
index 00..8b20bcb050
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py 
b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
new file mode 100644
index 00..f950d5eecda671
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py
@@ -0,0 +1,135 @@
+"""
+Test lldb-dap memory support
+"""
+
+from base64 import b64decode
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase):
+def test_read_memory(self):
+"""
+Tests the 'read_memory' request
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.cpp"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// Breakpoint")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+rawptr_ref = locals["rawptr"]["memoryReference"]
+
+# We can read the complete string
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 5)["body"]
+self.assertEqual(mem["unreadableBytes"], 0)
+self.assertEqual(b64decode(mem["data"]), b"dead\0")
+
+# Use an offset
+mem = self.dap_server.request_read_memory(rawptr_ref, 2, 3)["body"]
+self.assertEqual(b64decode(mem["data"]), b"ad\0")
+
+# Use a negative offset
+mem = self.dap_server.request_read_memory(rawptr_ref, -1, 6)["body"]
+self.assertEqual(b64decode(mem["data"])[1:], b"dead\0")
+
+# Reads of size 0 are successful
+# VS-Code sends those in order to check if a `memoryReference` can 
actually be dereferenced.
+mem = self.dap_server.request_read_memory(rawptr_ref, 0, 0)
+self.assertEqual(mem["success"], True)
+self.assertEqual(mem["body"]["data"], "")
+
+# Reads at offset 0x0 fail
+mem = self.dap_server.request_read_memory("0x0", 0, 6)
+self.assertEqual(mem["success"], False)
+self.assertTrue(mem["message"].startswith("Unable to read memory: "))
+
+def test_memory_refs_variables(self):
+"""
+Tests memory references for evaluate
+"""
+   

[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/102928

>From fcc6b56e27eb1bb564ccf04a328fecc5c02cf78e Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Sat, 10 Aug 2024 23:59:55 +
Subject: [PATCH] [lldb-dap] Implement declaration locations

This commit implements support for the "declaration location" recently
added by microsoft/debug-adapter-protocol#494 to the debug adapter
protocol.

For the `declarationLocationReference` we need a variable ID similar to
the the `variablesReference`. I decided to simply reuse the
`variablesReference` here and renamed `Variables::expandable_variables`
and friends accordingly. Given that almost all variables have a
declaration location, we now assign those variable ids to all variables.

While `declarationLocationReference` effectively supersedes
`$__lldb_extensions.declaration`, I did not remove this extension, yet,
since I assume that there are some closed-source extensions which rely
on it.

I tested this against VS-Code Insiders. However, VS-Code Insiders
currently only supports `valueLoctionReference` and not
`declarationLocationReference`, yet. Locally, I hence tried to publish
the declaration locations as value locations. However, it seems that
VS-Code still has issues with correctly resolving file paths, as
reported in 
https://github.com/microsoft/vscode/pull/225546#issuecomment-2292428591
---
 .../test/tools/lldb-dap/dap_server.py |  11 ++
 .../API/tools/lldb-dap/locations/Makefile |   3 +
 .../lldb-dap/locations/TestDAP_locations.py   |  40 +
 lldb/test/API/tools/lldb-dap/locations/main.c |   5 +
 lldb/tools/lldb-dap/DAP.cpp   |  17 +-
 lldb/tools/lldb-dap/DAP.h |  10 +-
 lldb/tools/lldb-dap/JSONUtils.cpp | 125 ---
 lldb/tools/lldb-dap/JSONUtils.h   |  31 ++--
 lldb/tools/lldb-dap/lldb-dap.cpp  | 146 +++---
 9 files changed, 286 insertions(+), 102 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..9879a34ed2020c 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -1079,6 +1079,17 @@ def request_setVariable(self, containingVarRef, name, 
value, id=None):
 }
 return self.send_recv(command_dict)
 
+def request_locations(self, locationReference):
+args_dict = {
+"locationReference": locationReference,
+}
+command_dict = {
+"command": "locations",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_testGetTargetBreakpoints(self):
 """A request packet used in the LLDB test suite to get all currently
 set breakpoint infos for all breakpoints currently set in the
diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile 
b/lldb/test/API/tools/lldb-dap/locations/Makefile
new file mode 100644
index 00..10495940055b63
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py 
b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
new file mode 100644
index 00..76d938d3908492
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
@@ -0,0 +1,40 @@
+"""
+Test lldb-dap locations request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase):
+@skipIfWindows
+def test_locations(self):
+"""
+Tests the 'locations' request.
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.c"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// BREAK HERE")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+
+# var1 has a declarationLocation but no valueLocation
+self.assertIn("declarationLocationReference", locals["var1"].keys())
+self.assertNotIn("valueLocationReference", locals["var1"].keys())
+loc_var1 = self.dap_server.request_locations(
+locals["var1"]["declarationLocationReference"]
+)
+self.a

[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/102928

>From 079def868f0216f31b78469f63034db5b350e250 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Sat, 10 Aug 2024 23:59:55 +
Subject: [PATCH] [lldb-dap] Implement declaration locations

This commit implements support for the "declaration location" recently
added by microsoft/debug-adapter-protocol#494 to the debug adapter
protocol.

For the `declarationLocationReference` we need a variable ID similar to
the the `variablesReference`. I decided to simply reuse the
`variablesReference` here and renamed `Variables::expandable_variables`
and friends accordingly. Given that almost all variables have a
declaration location, we now assign those variable ids to all variables.

While `declarationLocationReference` effectively supersedes
`$__lldb_extensions.declaration`, I did not remove this extension, yet,
since I assume that there are some closed-source extensions which rely
on it.

I tested this against VS-Code Insiders. However, VS-Code Insiders
currently only supports `valueLoctionReference` and not
`declarationLocationReference`, yet. Locally, I hence tried to publish
the declaration locations as value locations. However, it seems that
VS-Code still has issues with correctly resolving file paths, as
reported in 
https://github.com/microsoft/vscode/pull/225546#issuecomment-2292428591
---
 .../test/tools/lldb-dap/dap_server.py |  11 ++
 .../API/tools/lldb-dap/locations/Makefile |   3 +
 .../lldb-dap/locations/TestDAP_locations.py   |  40 +
 lldb/test/API/tools/lldb-dap/locations/main.c |   5 +
 lldb/tools/lldb-dap/DAP.cpp   |  17 +-
 lldb/tools/lldb-dap/DAP.h |  10 +-
 lldb/tools/lldb-dap/JSONUtils.cpp | 125 ---
 lldb/tools/lldb-dap/JSONUtils.h   |  31 ++--
 lldb/tools/lldb-dap/lldb-dap.cpp  | 146 +++---
 9 files changed, 286 insertions(+), 102 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..9879a34ed2020c 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -1079,6 +1079,17 @@ def request_setVariable(self, containingVarRef, name, 
value, id=None):
 }
 return self.send_recv(command_dict)
 
+def request_locations(self, locationReference):
+args_dict = {
+"locationReference": locationReference,
+}
+command_dict = {
+"command": "locations",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_testGetTargetBreakpoints(self):
 """A request packet used in the LLDB test suite to get all currently
 set breakpoint infos for all breakpoints currently set in the
diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile 
b/lldb/test/API/tools/lldb-dap/locations/Makefile
new file mode 100644
index 00..10495940055b63
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py 
b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
new file mode 100644
index 00..76d938d3908492
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
@@ -0,0 +1,40 @@
+"""
+Test lldb-dap locations request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase):
+@skipIfWindows
+def test_locations(self):
+"""
+Tests the 'locations' request.
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.c"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// BREAK HERE")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+
+# var1 has a declarationLocation but no valueLocation
+self.assertIn("declarationLocationReference", locals["var1"].keys())
+self.assertNotIn("valueLocationReference", locals["var1"].keys())
+loc_var1 = self.dap_server.request_locations(
+locals["var1"]["declarationLocationReference"]
+)
+self.a

[Lldb-commits] [lldb] [lldb-dap] Implement value locations for function pointers (PR #104589)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang created 
https://github.com/llvm/llvm-project/pull/104589

Note to reviewers: This commit builds on top of the not-yet-merged PR #102928. 
When reviewing, ignore the first commit, it is part of the over PR. I will 
rebase and turn this into a non-draft PR after #102928 landed.



This commit adds `valueLocationReference` to function pointers and function 
references. Thereby, users can navigate directly to the pointed-to function 
from within the "variables" pane.

In general, it would be useful to also a add similar location references also 
to member function pointers, `std::source_location`, `std::function`,  and many 
more. Doing so would require extending the formatters to provide such a source 
code location.

There were two RFCs about this a while ago:
https://discourse.llvm.org/t/rfc-extending-formatters-with-a-source-code-reference/68375
https://discourse.llvm.org/t/rfc-sbvalue-metadata-provider/68377/26

However, both RFCs ended without a conclusion. As such, this commit now solve 
the lowest-hanging fruit, i.e. function pointers. If people find it useful, I 
will revive the RFC afterwards.


>From 079def868f0216f31b78469f63034db5b350e250 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Sat, 10 Aug 2024 23:59:55 +
Subject: [PATCH 1/2] [lldb-dap] Implement declaration locations

This commit implements support for the "declaration location" recently
added by microsoft/debug-adapter-protocol#494 to the debug adapter
protocol.

For the `declarationLocationReference` we need a variable ID similar to
the the `variablesReference`. I decided to simply reuse the
`variablesReference` here and renamed `Variables::expandable_variables`
and friends accordingly. Given that almost all variables have a
declaration location, we now assign those variable ids to all variables.

While `declarationLocationReference` effectively supersedes
`$__lldb_extensions.declaration`, I did not remove this extension, yet,
since I assume that there are some closed-source extensions which rely
on it.

I tested this against VS-Code Insiders. However, VS-Code Insiders
currently only supports `valueLoctionReference` and not
`declarationLocationReference`, yet. Locally, I hence tried to publish
the declaration locations as value locations. However, it seems that
VS-Code still has issues with correctly resolving file paths, as
reported in 
https://github.com/microsoft/vscode/pull/225546#issuecomment-2292428591
---
 .../test/tools/lldb-dap/dap_server.py |  11 ++
 .../API/tools/lldb-dap/locations/Makefile |   3 +
 .../lldb-dap/locations/TestDAP_locations.py   |  40 +
 lldb/test/API/tools/lldb-dap/locations/main.c |   5 +
 lldb/tools/lldb-dap/DAP.cpp   |  17 +-
 lldb/tools/lldb-dap/DAP.h |  10 +-
 lldb/tools/lldb-dap/JSONUtils.cpp | 125 ---
 lldb/tools/lldb-dap/JSONUtils.h   |  31 ++--
 lldb/tools/lldb-dap/lldb-dap.cpp  | 146 +++---
 9 files changed, 286 insertions(+), 102 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..9879a34ed2020c 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -1079,6 +1079,17 @@ def request_setVariable(self, containingVarRef, name, 
value, id=None):
 }
 return self.send_recv(command_dict)
 
+def request_locations(self, locationReference):
+args_dict = {
+"locationReference": locationReference,
+}
+command_dict = {
+"command": "locations",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_testGetTargetBreakpoints(self):
 """A request packet used in the LLDB test suite to get all currently
 set breakpoint infos for all breakpoints currently set in the
diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile 
b/lldb/test/API/tools/lldb-dap/locations/Makefile
new file mode 100644
index 00..10495940055b63
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py 
b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
new file mode 100644
index 00..76d938d3908492
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
@@ -0,0 +1,40 @@
+"""
+Test lldb-dap locations request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from

[Lldb-commits] [lldb] [lldb-dap] Implement value locations for function pointers (PR #104589)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/104589

>From 079def868f0216f31b78469f63034db5b350e250 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Sat, 10 Aug 2024 23:59:55 +
Subject: [PATCH 1/2] [lldb-dap] Implement declaration locations

This commit implements support for the "declaration location" recently
added by microsoft/debug-adapter-protocol#494 to the debug adapter
protocol.

For the `declarationLocationReference` we need a variable ID similar to
the the `variablesReference`. I decided to simply reuse the
`variablesReference` here and renamed `Variables::expandable_variables`
and friends accordingly. Given that almost all variables have a
declaration location, we now assign those variable ids to all variables.

While `declarationLocationReference` effectively supersedes
`$__lldb_extensions.declaration`, I did not remove this extension, yet,
since I assume that there are some closed-source extensions which rely
on it.

I tested this against VS-Code Insiders. However, VS-Code Insiders
currently only supports `valueLoctionReference` and not
`declarationLocationReference`, yet. Locally, I hence tried to publish
the declaration locations as value locations. However, it seems that
VS-Code still has issues with correctly resolving file paths, as
reported in 
https://github.com/microsoft/vscode/pull/225546#issuecomment-2292428591
---
 .../test/tools/lldb-dap/dap_server.py |  11 ++
 .../API/tools/lldb-dap/locations/Makefile |   3 +
 .../lldb-dap/locations/TestDAP_locations.py   |  40 +
 lldb/test/API/tools/lldb-dap/locations/main.c |   5 +
 lldb/tools/lldb-dap/DAP.cpp   |  17 +-
 lldb/tools/lldb-dap/DAP.h |  10 +-
 lldb/tools/lldb-dap/JSONUtils.cpp | 125 ---
 lldb/tools/lldb-dap/JSONUtils.h   |  31 ++--
 lldb/tools/lldb-dap/lldb-dap.cpp  | 146 +++---
 9 files changed, 286 insertions(+), 102 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..9879a34ed2020c 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -1079,6 +1079,17 @@ def request_setVariable(self, containingVarRef, name, 
value, id=None):
 }
 return self.send_recv(command_dict)
 
+def request_locations(self, locationReference):
+args_dict = {
+"locationReference": locationReference,
+}
+command_dict = {
+"command": "locations",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_testGetTargetBreakpoints(self):
 """A request packet used in the LLDB test suite to get all currently
 set breakpoint infos for all breakpoints currently set in the
diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile 
b/lldb/test/API/tools/lldb-dap/locations/Makefile
new file mode 100644
index 00..10495940055b63
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py 
b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
new file mode 100644
index 00..76d938d3908492
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
@@ -0,0 +1,40 @@
+"""
+Test lldb-dap locations request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase):
+@skipIfWindows
+def test_locations(self):
+"""
+Tests the 'locations' request.
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.c"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// BREAK HERE")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+
+# var1 has a declarationLocation but no valueLocation
+self.assertIn("declarationLocationReference", locals["var1"].keys())
+self.assertNotIn("valueLocationReference", locals["var1"].keys())
+loc_var1 = self.dap_server.request_locations(
+locals["var1"]["declarationLocationReference"]
+)
+se

[Lldb-commits] [lldb] [lldb] Extend frame recognizers to hide frames from backtraces (PR #104523)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

Should hidden frames also be skipped by `StepOut`?

https://github.com/llvm/llvm-project/pull/104523
___
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 value locations for function pointers (PR #104589)

2024-08-16 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

In the below screen recording, you can see:
* The function pointers are shown in the variables view as usual
* The corresponding values are linked, as indicated by the underline when 
hovering the value
* When Cmd+Clicking on the value, the link is followed
* Currently, this still leads to an error message. Afaict, this is due to a bug 
in VS-Code Insiders. I suspect that it does not correctly resolve the file path 
provided by the debug adapter. Probably this fails because I am using a remote, 
SSH-based editing session here.
* However, from the DAP logs (visible towards the bottom of the screen), we can 
see that the debug adapter returns the correct file name and also the correct 
line

https://github.com/user-attachments/assets/6d7ff263-16e9-4194-b732-a79952ebed89



https://github.com/llvm/llvm-project/pull/104589
___
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 value locations for function pointers (PR #104589)

2024-08-19 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

Here the screen recording of a fully functional, non-remote session:

https://github.com/user-attachments/assets/64b36078-a57b-440a-85f8-0e73f88c5a56



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


[Lldb-commits] [lldb] [lldb-dap] show dialog when executable is not found (PR #104711)

2024-08-19 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang commented:

Thanks for looking into this! The patch already looks very good!

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


[Lldb-commits] [lldb] [lldb-dap] show dialog when executable is not found (PR #104711)

2024-08-19 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] show dialog when executable is not found (PR #104711)

2024-08-19 Thread Adrian Vogelsgesang via lldb-commits




vogelsgesang wrote:

please rebase onto `main`. This unfortunately has a merge conflict with another 
change which I recently merged

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


[Lldb-commits] [lldb] [lldb-dap] show dialog when executable is not found (PR #104711)

2024-08-19 Thread Adrian Vogelsgesang via lldb-commits


@@ -17,14 +17,46 @@ function createDefaultLLDBDapOptions(): LLDBDapOptions {
   const path = vscode.workspace
 .getConfiguration("lldb-dap", session.workspaceFolder)
 .get("executable-path");
-  if (path) {
-return new vscode.DebugAdapterExecutable(path, []);
+
+  if (!path) {

vogelsgesang wrote:

even if the path is not set, we should check if the `packageJSONExecutable` 
actually exists
By default, the `path` is not set. As such, new users would not get this error 
message, although those are the ones which are most likely to run into issues

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


[Lldb-commits] [lldb] [lldb-dap] show dialog when executable is not found (PR #104711)

2024-08-19 Thread Adrian Vogelsgesang via lldb-commits


@@ -17,14 +17,46 @@ function createDefaultLLDBDapOptions(): LLDBDapOptions {
   const path = vscode.workspace
 .getConfiguration("lldb-dap", session.workspaceFolder)
 .get("executable-path");
-  if (path) {
-return new vscode.DebugAdapterExecutable(path, []);
+
+  if (!path) {
+return packageJSONExecutable;
   }
-  return packageJSONExecutable;
+
+  vscode.workspace.fs.stat(vscode.Uri.file(path)).then(
+(fileStats) => {

vogelsgesang wrote:

in addition to checking the presence of the file on launch, we could also check 
for it in the `onDidChangeConfiguration` event if the `executable-path` gets 
changed.

(100% optional; feel free to just ignore this comment 🙂)

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


[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)

2024-08-20 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Fix disassembled ranges for `disassemble` request (PR #105446)

2024-08-20 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang created 
https://github.com/llvm/llvm-project/pull/105446

This is a first draft PR which fixes #103021

The main issue was that the `instructionOffset` was handled as a byte offset 
and not as an instruction offset.

This commit also incorporates previous feedback from 
https://reviews.llvm.org/D140358: With this change, we are using symbols and 
DWARF debug information to find function boundaries and correctly start 
disassembling at this address.

TODO:
* Update test case
* Check if we can also support disassembling across functions



>From b809f570dd8055e5b899c337ec9ff5110ab94c6e Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Mon, 19 Aug 2024 15:15:22 +
Subject: [PATCH] [lldb-dap] Fix disassembled ranges for `disassemble` request

TODO:
* Update test case
* Check if we can also support disassembling across functions

Incorporated feedback from https://reviews.llvm.org/D140358
---
 .../test/tools/lldb-dap/dap_server.py |  4 +-
 .../disassemble/TestDAP_disassemble.py|  8 +++
 lldb/tools/lldb-dap/lldb-dap.cpp  | 68 +--
 3 files changed, 71 insertions(+), 9 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..75731ebfde6723 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -674,11 +674,11 @@ def request_disconnect(self, terminateDebuggee=None):
 return self.send_recv(command_dict)
 
 def request_disassemble(
-self, memoryReference, offset=-50, instructionCount=200, 
resolveSymbols=True
+self, memoryReference, instructionOffset=0, instructionCount=10, 
resolveSymbols=True
 ):
 args_dict = {
 "memoryReference": memoryReference,
-"offset": offset,
+"instructionOffset": instructionOffset,
 "instructionCount": instructionCount,
 "resolveSymbols": resolveSymbols,
 }
diff --git a/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py 
b/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py
index 9e8ef5b289f2e8..ab72eb2d13d729 100644
--- a/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py
+++ b/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py
@@ -29,6 +29,14 @@ def test_disassemble(self):
 )
 self.continue_to_next_stop()
 
+stackFrames = self.get_stackFrames(
+threadId=threadId, startFrame=frameIndex, levels=1
+)
+self.assertIsNotNone(stackFrames)
+
+# XXX finish updating test case
+memoryReference = stackFrames[0]["instructionPointerReference"]
+
 pc_assembly = self.disassemble(frameIndex=0)
 self.assertIn("location", pc_assembly, "Source location missing.")
 self.assertIn("instruction", pc_assembly, "Assembly instruction 
missing.")
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index ea84f31aec3a6c..5d9d28b59ea805 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -3910,8 +3910,8 @@ void request_disassemble(const llvm::json::Object 
&request) {
 return;
   }
 
-  addr_ptr += GetSigned(arguments, "instructionOffset", 0);
-  lldb::SBAddress addr(addr_ptr, g_dap.target);
+  addr_ptr += GetSigned(arguments, "offset", 0);
+  lldb::SBAddress addr = g_dap.target.ResolveLoadAddress(addr_ptr);
   if (!addr.IsValid()) {
 response["success"] = false;
 response["message"] = "Memory reference not found in the current binary.";
@@ -3919,9 +3919,27 @@ void request_disassemble(const llvm::json::Object 
&request) {
 return;
   }
 
-  const auto inst_count = GetUnsigned(arguments, "instructionCount", 0);
-  lldb::SBInstructionList insts =
-  g_dap.target.ReadInstructions(addr, inst_count);
+  int64_t inst_offset = GetSigned(arguments, "instructionOffset", 0);
+  const int64_t inst_count = GetSigned(arguments, "instructionCount", 0);
+  if (inst_count < 0) {
+response["success"] = false;
+response["message"] = "Negative instruction count.";
+g_dap.SendJSON(llvm::json::Value(std::move(response)));
+return;
+  }
+
+  lldb::SBInstructionList insts;
+  if (lldb::SBFunction func = addr.GetFunction()) {
+// First try to identify the function boundaries through debug information
+insts = func.GetInstructions(g_dap.target);
+  } else if (lldb::SBSymbol sym = addr.GetSymbol()) {
+// Try to identify the function boundaries through the symbol table
+insts = sym.GetInstructions(g_dap.target);
+  } else {
+// We could not identify the function. Just disassemble starting from the
+// provided address.
+insts = g_dap.target.ReadInstructions(addr, inst_offset + inst_count);
+  }
 
   if (!insts.IsValid()) {
 response["success"] = false;
@@ -3930,10

[Lldb-commits] [lldb] [lldb-dap] Fix disassembled ranges for `disassemble` request (PR #105446)

2024-08-20 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

@clayborg I would be interested in your guidance for this PR, given that you 
previously reviewed a similar change in https://reviews.llvm.org/D140358

I did use `SBFunction` / `SBSymbol` as suggested by you in [this 
comment](https://reviews.llvm.org/D140358#4027551). 

I did not know how to address the part

```
// then we need to repeat the search for the next function or symbol. 
// note there may be bytes between functions or symbols which we can 
disassemble
// by calling _get_instructions_from_memory(...) but we must find the next
// symbol or function boundary and get back on track
```

from your comment, though. Is there some API to find the next symbol? Or some 
API to get a list of symbols, sorted by their start address?

I could of course use a brute-force approach, similar to

```
SBAddress addr;
while (!addr.GetFunction() && !addr.GetSymbol())
   addr = addr.OffsetAddress(1);
```

but that seems a bit wasteful

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


[Lldb-commits] [lldb] [lldb-dap] Mark hidden frames as "subtle" (PR #105457)

2024-08-20 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] When sending a DAP Output Event break each message into separate lines. (PR #105456)

2024-08-20 Thread Adrian Vogelsgesang via lldb-commits


@@ -311,10 +309,22 @@ void DAP::SendOutput(OutputType o, const llvm::StringRef 
output) {
 category = "telemetry";
 break;
   }
-  body.try_emplace("category", category);
-  EmplaceSafeString(body, "output", output.str());
-  event.try_emplace("body", std::move(body));
-  SendJSON(llvm::json::Value(std::move(event)));
+
+  // Send each line of output as an individual event, including the newline if
+  // present.
+  ::size_t idx = 0;
+  do {
+::size_t end = output.find('\n', idx);
+if (end == llvm::StringRef::npos)
+  end = output.size() - 1;
+llvm::json::Object event(CreateEventObject("output"));
+llvm::json::Object body;
+body.try_emplace("category", category);
+EmplaceSafeString(body, "output", output.slice(idx, end + 1).str());
+event.try_emplace("body", std::move(body));
+SendJSON(llvm::json::Value(std::move(event)));
+idx = end + 1;
+  } while (idx < output.size());

vogelsgesang wrote:

afaict, we still send partial lines without a `\n` in the end as individual 
output events. Should we instead only send full lines as output events?

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


[Lldb-commits] [lldb] [lldb-dap] Mark hidden frames as "subtle" (PR #105457)

2024-08-20 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

> This looks like a nice improvement! Can we add a test for this?

Added. Is this the type of test case you had in mind? Also, do I need to do 
anything in addition? E.g., disable the test case for libstdc++, because the 
stack frame recognizer only works for libc++? How would I do so?

(Not sure yet, if the test case is actually correct. Still waiting for my local 
build to finish)

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


[Lldb-commits] [lldb] [lldb-dap] Mark hidden frames as "subtle" (PR #105457)

2024-08-20 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/105457

>From bdd78f79c8eb1a439472c1aa5a1bb25e83494a79 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Wed, 21 Aug 2024 00:12:39 +
Subject: [PATCH] [lldb-dap] Show hidden frames as "subtle"

This commit takes advantage of the recently introduced
`SBFrame::IsHidden` to show those hidden frames as "subtle" frames in
the UI. E.g., VS Code renders such frames grayed out in the stack trace
---
 .../lldb-dap/stackTrace/subtleFrames/Makefile |  3 ++
 .../subtleFrames/TestDAP_subtleFrames.py  | 29 +++
 .../lldb-dap/stackTrace/subtleFrames/main.cpp | 13 +
 lldb/tools/lldb-dap/JSONUtils.cpp |  3 ++
 4 files changed, 48 insertions(+)
 create mode 100644 
lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile
 create mode 100644 
lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py
 create mode 100644 
lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp

diff --git a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile 
b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile
new file mode 100644
index 00..a6ae713cf424ff
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.c
+
+include Makefile.rules
diff --git 
a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py 
b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py
new file mode 100644
index 00..d4b28c35d08df2
--- /dev/null
+++ 
b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py
@@ -0,0 +1,29 @@
+"""
+Test lldb-dap stack trace response
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+import os
+
+import lldbdap_testcase
+from lldbsuite.test import lldbtest, lldbutil
+
+
+class TestDAP_subtleFrames(lldbdap_testcase.DAPTestCaseBase):
+def test_subtleFrames(self):
+"""
+Test that internal stack frames (such as the ones used by 
`std::function`)
+are marked as "subtle".
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.cpp"
+self.set_source_breakpoints(source, [line_number(source, "BREAK 
HERE")])
+self.continue_to_next_stop()
+
+backtrace = self.get_stackFrames()[0]
+for f in backtrace:
+if "__function" in f["name"]:
+self.assertEqual(f["presentationHint"], "subtle")
diff --git a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp 
b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp
new file mode 100644
index 00..71944528441e38
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp
@@ -0,0 +1,13 @@
+#include 
+#include 
+
+void greet() {
+  // BREAK HERE
+  std::cout << "Hello\n";
+}
+
+int main() {
+  std::function func{greet};
+  func();
+  return 0;
+}
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index a8b85f55939e17..c080fd395b7288 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -763,6 +763,9 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame) {
 object.try_emplace("instructionPointerReference", formatted_addr);
   }
 
+  if (frame.IsArtificial() || frame.IsHidden())
+object.try_emplace("presentationHint", "subtle");
+
   return llvm::json::Value(std::move(object));
 }
 

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


[Lldb-commits] [lldb] [lldb-dap] Mark hidden frames as "subtle" (PR #105457)

2024-08-20 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/105457

>From 36fd54d51e8310d4d03b40019bd96e564f8d1171 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Wed, 21 Aug 2024 00:12:39 +
Subject: [PATCH] [lldb-dap] Show hidden frames as "subtle"

This commit takes advantage of the recently introduced
`SBFrame::IsHidden` to show those hidden frames as "subtle" frames in
the UI. E.g., VS Code renders such frames grayed out in the stack trace
---
 .../lldb-dap/stackTrace/subtleFrames/Makefile |  3 ++
 .../subtleFrames/TestDAP_subtleFrames.py  | 29 +++
 .../lldb-dap/stackTrace/subtleFrames/main.cpp | 13 +
 lldb/tools/lldb-dap/JSONUtils.cpp |  3 ++
 4 files changed, 48 insertions(+)
 create mode 100644 
lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile
 create mode 100644 
lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py
 create mode 100644 
lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp

diff --git a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile 
b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile
new file mode 100644
index 00..8b20bcb050
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git 
a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py 
b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py
new file mode 100644
index 00..1e41e841e39bc8
--- /dev/null
+++ 
b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py
@@ -0,0 +1,29 @@
+"""
+Test lldb-dap stack trace response
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+
+import lldbdap_testcase
+from lldbsuite.test.lldbtest import *
+
+
+class TestDAP_subtleFrames(lldbdap_testcase.DAPTestCaseBase):
+@add_test_categories(["libc++"])
+def test_subtleFrames(self):
+"""
+Internal stack frames (such as the ones used by `std::function`) are 
marked as "subtle".
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.cpp"
+self.set_source_breakpoints(source, [line_number(source, "BREAK 
HERE")])
+self.continue_to_next_stop()
+
+frames = self.get_stackFrames()
+for f in frames:
+if "__function" in f["name"]:
+self.assertEqual(f["presentationHint"], "subtle")
+self.assertTrue(any(f.get("presentationHint") == "subtle" for f in 
frames))
diff --git a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp 
b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp
new file mode 100644
index 00..71944528441e38
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp
@@ -0,0 +1,13 @@
+#include 
+#include 
+
+void greet() {
+  // BREAK HERE
+  std::cout << "Hello\n";
+}
+
+int main() {
+  std::function func{greet};
+  func();
+  return 0;
+}
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index a8b85f55939e17..c080fd395b7288 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -763,6 +763,9 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame) {
 object.try_emplace("instructionPointerReference", formatted_addr);
   }
 
+  if (frame.IsArtificial() || frame.IsHidden())
+object.try_emplace("presentationHint", "subtle");
+
   return llvm::json::Value(std::move(object));
 }
 

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


[Lldb-commits] [lldb] [lldb-dap] Mark hidden frames as "subtle" (PR #105457)

2024-08-20 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

The included test case should be fine now, afaict

https://github.com/llvm/llvm-project/pull/105457
___
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 `StepGranularity` for "next" and "step-in" (PR #105464)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits


@@ -3193,7 +3213,11 @@ void request_stackTrace(const llvm::json::Object 
&request) {
 // "targetId": {
 //   "type": "integer",
 //   "description": "Optional id of the target to step into."
-// }
+// },
+// "granularity": {
+//   "$ref": "#/definitions/SteppingGranularity",
+//   "description": "Stepping granularity. If no granularity is specified, 
a
+//   granularity of `statement` is assumed."
 //   },

vogelsgesang wrote:

missing closing `}`

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


[Lldb-commits] [lldb] [lldb-dap] When sending a DAP Output Event break each message into separate lines. (PR #105456)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits


@@ -311,10 +309,22 @@ void DAP::SendOutput(OutputType o, const llvm::StringRef 
output) {
 category = "telemetry";
 break;
   }
-  body.try_emplace("category", category);
-  EmplaceSafeString(body, "output", output.str());
-  event.try_emplace("body", std::move(body));
-  SendJSON(llvm::json::Value(std::move(event)));
+
+  // Send each line of output as an individual event, including the newline if
+  // present.
+  ::size_t idx = 0;
+  do {
+::size_t end = output.find('\n', idx);
+if (end == llvm::StringRef::npos)
+  end = output.size() - 1;
+llvm::json::Object event(CreateEventObject("output"));
+llvm::json::Object body;
+body.try_emplace("category", category);
+EmplaceSafeString(body, "output", output.slice(idx, end + 1).str());
+event.try_emplace("body", std::move(body));
+SendJSON(llvm::json::Value(std::move(event)));
+idx = end + 1;
+  } while (idx < output.size());

vogelsgesang wrote:

Thanks for clarifying!

https://github.com/llvm/llvm-project/pull/105456
___
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 `StepGranularity` for "next" and "step-in" (PR #105464)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/105464

>From c4178df5541103388e26343f62e96f8e2a65be86 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Mon, 12 Aug 2024 23:00:45 +
Subject: [PATCH 1/3] [lldb-dap] Implement `StepGranularity` for "next" and
 "step-in"

VS Code requests a `granularity` of `instruction` if the assembly view
is currently focused. By implementing `StepGranularity`, we can hence
properly through assembly code single-step through assembly code.
---
 .../test/tools/lldb-dap/dap_server.py |  8 ++---
 .../test/tools/lldb-dap/lldbdap_testcase.py   |  8 ++---
 .../API/tools/lldb-dap/step/TestDAP_step.py   |  9 ++
 lldb/tools/lldb-dap/lldb-dap.cpp  | 31 +--
 4 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index a324af57b61df3..87ebc674f61df6 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -816,17 +816,17 @@ def request_launch(
 self.wait_for_event(filter=["process", "initialized"])
 return response
 
-def request_next(self, threadId):
+def request_next(self, threadId, granularity="statement"):
 if self.exit_status is not None:
 raise ValueError("request_continue called after process exited")
-args_dict = {"threadId": threadId}
+args_dict = {"threadId": threadId, "granularity": granularity}
 command_dict = {"command": "next", "type": "request", "arguments": 
args_dict}
 return self.send_recv(command_dict)
 
-def request_stepIn(self, threadId, targetId):
+def request_stepIn(self, threadId, targetId, granularity="statement"):
 if self.exit_status is not None:
 raise ValueError("request_stepIn called after process exited")
-args_dict = {"threadId": threadId, "targetId": targetId}
+args_dict = {"threadId": threadId, "targetId": targetId, 
"granularity": granularity}
 command_dict = {"command": "stepIn", "type": "request", "arguments": 
args_dict}
 return self.send_recv(command_dict)
 
diff --git 
a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index a312a88ebd7e58..3257bd14b16fed 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -222,14 +222,14 @@ def set_global(self, name, value, id=None):
 """Set a top level global variable only."""
 return self.dap_server.request_setVariable(2, name, str(value), id=id)
 
-def stepIn(self, threadId=None, targetId=None, waitForStop=True):
-self.dap_server.request_stepIn(threadId=threadId, targetId=targetId)
+def stepIn(self, threadId=None, targetId=None, waitForStop=True, 
granularity="statement"):
+self.dap_server.request_stepIn(threadId=threadId, targetId=targetId, 
granularity=granularity)
 if waitForStop:
 return self.dap_server.wait_for_stopped()
 return None
 
-def stepOver(self, threadId=None, waitForStop=True):
-self.dap_server.request_next(threadId=threadId)
+def stepOver(self, threadId=None, waitForStop=True, 
granularity="statement"):
+self.dap_server.request_next(threadId=threadId, 
granularity=granularity)
 if waitForStop:
 return self.dap_server.wait_for_stopped()
 return None
diff --git a/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py 
b/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py
index 8a1bb76340be73..9c8e226827611e 100644
--- a/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py
+++ b/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py
@@ -68,5 +68,14 @@ def test_step(self):
 self.assertEqual(x4, x3, "verify step over variable")
 self.assertGreater(line4, line3, "verify step over line")
 self.assertEqual(src1, src4, "verify step over source")
+
+# Step a single assembly instruction.
+# Unfortunately, there is no portable way to verify the 
correct
+# stepping behavior here, because the generated assembly 
code
+# depends highly on the compiler, its version, the 
operating
+# system, and many more factors.
+self.stepOver(threadId=tid, waitForStop=True, 
granularity="instruction")
+self.stepIn(threadId=tid, waitForStop=True, 
granularity="instruction")
+
 # only step one thread that is at the breakpoint and stop
 break
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
inde

[Lldb-commits] [lldb] [lldb-dap] Implement `StepGranularity` for "next" and "step-in" (PR #105464)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/102928

>From 5bdcb821527bf67eead6c42825ea6e559ec749c3 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Sat, 10 Aug 2024 23:59:55 +
Subject: [PATCH] [lldb-dap] Implement declaration locations

This commit implements support for the "declaration location" recently
added by microsoft/debug-adapter-protocol#494 to the debug adapter
protocol.

For the `declarationLocationReference` we need a variable ID similar to
the the `variablesReference`. I decided to simply reuse the
`variablesReference` here and renamed `Variables::expandable_variables`
and friends accordingly. Given that almost all variables have a
declaration location, we now assign those variable ids to all variables.

While `declarationLocationReference` effectively supersedes
`$__lldb_extensions.declaration`, I did not remove this extension, yet,
since I assume that there are some closed-source extensions which rely
on it.

I tested this against VS-Code Insiders. However, VS-Code Insiders
currently only supports `valueLoctionReference` and not
`declarationLocationReference`, yet. Locally, I hence published
the declaration locations as value locations, and VS Code Insiders
navigated to the expected places. Looking forward to proper VS Code
support for `declarationLocationReference`.
---
 .../test/tools/lldb-dap/dap_server.py |  11 ++
 .../API/tools/lldb-dap/locations/Makefile |   3 +
 .../lldb-dap/locations/TestDAP_locations.py   |  40 +
 lldb/test/API/tools/lldb-dap/locations/main.c |   5 +
 lldb/tools/lldb-dap/DAP.cpp   |  17 +-
 lldb/tools/lldb-dap/DAP.h |  10 +-
 lldb/tools/lldb-dap/JSONUtils.cpp | 125 ---
 lldb/tools/lldb-dap/JSONUtils.h   |  31 ++--
 lldb/tools/lldb-dap/lldb-dap.cpp  | 146 +++---
 9 files changed, 286 insertions(+), 102 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 874383a13e2bb6..01ff79ee430902 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -1083,6 +1083,17 @@ def request_setVariable(self, containingVarRef, name, 
value, id=None):
 }
 return self.send_recv(command_dict)
 
+def request_locations(self, locationReference):
+args_dict = {
+"locationReference": locationReference,
+}
+command_dict = {
+"command": "locations",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_testGetTargetBreakpoints(self):
 """A request packet used in the LLDB test suite to get all currently
 set breakpoint infos for all breakpoints currently set in the
diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile 
b/lldb/test/API/tools/lldb-dap/locations/Makefile
new file mode 100644
index 00..10495940055b63
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py 
b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
new file mode 100644
index 00..76d938d3908492
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
@@ -0,0 +1,40 @@
+"""
+Test lldb-dap locations request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase):
+@skipIfWindows
+def test_locations(self):
+"""
+Tests the 'locations' request.
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.c"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// BREAK HERE")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+
+# var1 has a declarationLocation but no valueLocation
+self.assertIn("declarationLocationReference", locals["var1"].keys())
+self.assertNotIn("valueLocationReference", locals["var1"].keys())
+loc_var1 = self.dap_server.request_locations(
+locals["var1"]["declarationLocationReference"]
+)
+self.assertTrue(loc_var1["success"])
+self.as

[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/102928
___
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 value locations for function pointers (PR #104589)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/104589

>From 5bdcb821527bf67eead6c42825ea6e559ec749c3 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Sat, 10 Aug 2024 23:59:55 +
Subject: [PATCH 1/2] [lldb-dap] Implement declaration locations

This commit implements support for the "declaration location" recently
added by microsoft/debug-adapter-protocol#494 to the debug adapter
protocol.

For the `declarationLocationReference` we need a variable ID similar to
the the `variablesReference`. I decided to simply reuse the
`variablesReference` here and renamed `Variables::expandable_variables`
and friends accordingly. Given that almost all variables have a
declaration location, we now assign those variable ids to all variables.

While `declarationLocationReference` effectively supersedes
`$__lldb_extensions.declaration`, I did not remove this extension, yet,
since I assume that there are some closed-source extensions which rely
on it.

I tested this against VS-Code Insiders. However, VS-Code Insiders
currently only supports `valueLoctionReference` and not
`declarationLocationReference`, yet. Locally, I hence published
the declaration locations as value locations, and VS Code Insiders
navigated to the expected places. Looking forward to proper VS Code
support for `declarationLocationReference`.
---
 .../test/tools/lldb-dap/dap_server.py |  11 ++
 .../API/tools/lldb-dap/locations/Makefile |   3 +
 .../lldb-dap/locations/TestDAP_locations.py   |  40 +
 lldb/test/API/tools/lldb-dap/locations/main.c |   5 +
 lldb/tools/lldb-dap/DAP.cpp   |  17 +-
 lldb/tools/lldb-dap/DAP.h |  10 +-
 lldb/tools/lldb-dap/JSONUtils.cpp | 125 ---
 lldb/tools/lldb-dap/JSONUtils.h   |  31 ++--
 lldb/tools/lldb-dap/lldb-dap.cpp  | 146 +++---
 9 files changed, 286 insertions(+), 102 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 874383a13e2bb6..01ff79ee430902 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -1083,6 +1083,17 @@ def request_setVariable(self, containingVarRef, name, 
value, id=None):
 }
 return self.send_recv(command_dict)
 
+def request_locations(self, locationReference):
+args_dict = {
+"locationReference": locationReference,
+}
+command_dict = {
+"command": "locations",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_testGetTargetBreakpoints(self):
 """A request packet used in the LLDB test suite to get all currently
 set breakpoint infos for all breakpoints currently set in the
diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile 
b/lldb/test/API/tools/lldb-dap/locations/Makefile
new file mode 100644
index 00..10495940055b63
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py 
b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
new file mode 100644
index 00..76d938d3908492
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
@@ -0,0 +1,40 @@
+"""
+Test lldb-dap locations request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase):
+@skipIfWindows
+def test_locations(self):
+"""
+Tests the 'locations' request.
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.c"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// BREAK HERE")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+
+# var1 has a declarationLocation but no valueLocation
+self.assertIn("declarationLocationReference", locals["var1"].keys())
+self.assertNotIn("valueLocationReference", locals["var1"].keys())
+loc_var1 = self.dap_server.request_locations(
+locals["var1"]["declarationLocationReference"]
+)
+self.assertTrue(loc_var1["success"])
+sel

[Lldb-commits] [lldb] [lldb-dap] Mark hidden frames as "subtle" (PR #105457)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

@petrhosek this commit builds on top of #104523 and relies on the frame 
recognizer introduced as part of it.

As soon as [your proposed 
solutions](https://github.com/llvm/llvm-project/pull/104523#issuecomment-2303287484)
 was addressed, the `subtleFrames` test case should also be passing. In case 
this turns out to be not the case, please ping me again

https://github.com/llvm/llvm-project/pull/105457
___
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 value locations for function pointers (PR #104589)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits


@@ -0,0 +1,81 @@
+"""
+Test lldb-dap locations request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase):
+@skipIfWindows

vogelsgesang wrote:

this was a copy-paste mistake :/

https://github.com/llvm/llvm-project/pull/104589
___
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 value locations for function pointers (PR #104589)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Enabling instruction breakpoint support to lldb-dap. (PR #105278)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits


@@ -4046,6 +4048,181 @@ void request__testGetTargetBreakpoints(const 
llvm::json::Object &request) {
   g_dap.SendJSON(llvm::json::Value(std::move(response)));
 }
 
+// SetInstructionBreakpoints request; value of command field is
+// 'setInstructionBreakpoints'. Replaces all existing instruction breakpoints.
+// Typically, instruction breakpoints would be set from a disassembly window. 
To
+// clear all instruction breakpoints, specify an empty array. When an
+// instruction breakpoint is hit, a `stopped` event (with reason `instruction
+// breakpoint`) is generated. Clients should only call this request if the
+// corresponding capability `supportsInstructionBreakpoints` is true. interface
+// SetInstructionBreakpointsRequest extends Request {
+//   command: 'setInstructionBreakpoints';
+//   arguments: SetInstructionBreakpointsArguments;
+// }
+// interface SetInstructionBreakpointsArguments {
+//   The instruction references of the breakpoints
+//   breakpoints: InstructionBreakpoint[];
+// }
+// "InstructionBreakpoint ": {
+//   "type": "object",
+//   "description": "Properties of a breakpoint passed to the
+//   setInstructionBreakpoints request.", "properties": {
+// "instructionReference": {
+//   "type": "string",
+//   "description": "The instruction reference of the breakpoint.
+//   This should be a memory or instruction pointer reference from an
+//   EvaluateResponse, Variable, StackFrame, GotoTarget, or Breakpoint."
+// },
+// "offset": {
+//   "type": "number",
+//   "description": "The offset from the instruction reference.
+//   This can be negative."
+// },
+// "condition": {
+//   "type": "string",
+//   "description": "An expression for conditional breakpoints.
+//   It is only honored by a debug adapter if the corresponding capability
+//   supportsConditionalBreakpoints` is true."
+// },
+// "hitCondition": {
+//   "type": "string",
+//   "description": "An expression that controls how many hits of the
+//   breakpoint are ignored. The debug adapter is expected to interpret the
+//   expression as needed. The attribute is only honored by a debug adapter
+//   if the corresponding capability `supportsHitConditionalBreakpoints` is
+//   true."
+// },
+// }
+// interface SetInstructionBreakpointsResponse extends Response {
+//   body: {
+// Information about the breakpoints. The array elements correspond to the
+// elements of the `breakpoints` array.
+// breakpoints: Breakpoint[];
+//   };
+// }

vogelsgesang wrote:

we usually copy the JSON schema documentation into the comments, not the 
TypeScript interface.

See 
https://github.com/microsoft/debug-adapter-protocol/blob/main/debugAdapterProtocol.json

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


[Lldb-commits] [lldb] [lldb-dap] Enabling instruction breakpoint support to lldb-dap. (PR #105278)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits


@@ -4078,6 +4255,9 @@ void RegisterRequestCallbacks() {
   g_dap.RegisterRequestCallback("threads", request_threads);
   g_dap.RegisterRequestCallback("variables", request_variables);
   g_dap.RegisterRequestCallback("disassemble", request_disassemble);
+  // Instruction breapoint request

vogelsgesang wrote:

we also need to update the stopped event to use `reason: instruction 
breakpoint` instead of `reason: breakpoint` in case we hit one of those 
breakpoints

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits


@@ -0,0 +1,40 @@
+"""
+Test lldb-dap locations request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase):
+@skipIfWindows

vogelsgesang wrote:

copy-paste error :/

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/102928

>From 5bdcb821527bf67eead6c42825ea6e559ec749c3 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Sat, 10 Aug 2024 23:59:55 +
Subject: [PATCH 1/2] [lldb-dap] Implement declaration locations

This commit implements support for the "declaration location" recently
added by microsoft/debug-adapter-protocol#494 to the debug adapter
protocol.

For the `declarationLocationReference` we need a variable ID similar to
the the `variablesReference`. I decided to simply reuse the
`variablesReference` here and renamed `Variables::expandable_variables`
and friends accordingly. Given that almost all variables have a
declaration location, we now assign those variable ids to all variables.

While `declarationLocationReference` effectively supersedes
`$__lldb_extensions.declaration`, I did not remove this extension, yet,
since I assume that there are some closed-source extensions which rely
on it.

I tested this against VS-Code Insiders. However, VS-Code Insiders
currently only supports `valueLoctionReference` and not
`declarationLocationReference`, yet. Locally, I hence published
the declaration locations as value locations, and VS Code Insiders
navigated to the expected places. Looking forward to proper VS Code
support for `declarationLocationReference`.
---
 .../test/tools/lldb-dap/dap_server.py |  11 ++
 .../API/tools/lldb-dap/locations/Makefile |   3 +
 .../lldb-dap/locations/TestDAP_locations.py   |  40 +
 lldb/test/API/tools/lldb-dap/locations/main.c |   5 +
 lldb/tools/lldb-dap/DAP.cpp   |  17 +-
 lldb/tools/lldb-dap/DAP.h |  10 +-
 lldb/tools/lldb-dap/JSONUtils.cpp | 125 ---
 lldb/tools/lldb-dap/JSONUtils.h   |  31 ++--
 lldb/tools/lldb-dap/lldb-dap.cpp  | 146 +++---
 9 files changed, 286 insertions(+), 102 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 874383a13e2bb6..01ff79ee430902 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -1083,6 +1083,17 @@ def request_setVariable(self, containingVarRef, name, 
value, id=None):
 }
 return self.send_recv(command_dict)
 
+def request_locations(self, locationReference):
+args_dict = {
+"locationReference": locationReference,
+}
+command_dict = {
+"command": "locations",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_testGetTargetBreakpoints(self):
 """A request packet used in the LLDB test suite to get all currently
 set breakpoint infos for all breakpoints currently set in the
diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile 
b/lldb/test/API/tools/lldb-dap/locations/Makefile
new file mode 100644
index 00..10495940055b63
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py 
b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
new file mode 100644
index 00..76d938d3908492
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
@@ -0,0 +1,40 @@
+"""
+Test lldb-dap locations request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase):
+@skipIfWindows
+def test_locations(self):
+"""
+Tests the 'locations' request.
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.c"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// BREAK HERE")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+
+# var1 has a declarationLocation but no valueLocation
+self.assertIn("declarationLocationReference", locals["var1"].keys())
+self.assertNotIn("valueLocationReference", locals["var1"].keys())
+loc_var1 = self.dap_server.request_locations(
+locals["var1"]["declarationLocationReference"]
+)
+self.assertTrue(loc_var1["success"])
+sel

[Lldb-commits] [lldb] [lldb-dap] show dialog when executable is not found (PR #104711)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

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

Looks good to me!
Thanks for this amazing usability improvement!
If this would have existed the first time I tried this extension, it would have 
saved me a lot of time

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


[Lldb-commits] [lldb] [lldb-dap] show dialog when executable is not found (PR #104711)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] show dialog when executable is not found (PR #104711)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits


@@ -14,10 +14,52 @@ export class LLDBDapDescriptorFactory
 this.lldbDapOptions = lldbDapOptions;
   }
 
+  public static async validateDebugAdapterPath(pathUri: vscode.Uri) {
+try {
+  const fileStats = await vscode.workspace.fs.stat(pathUri);
+  if (!(fileStats.type & vscode.FileType.File)) {
+this.showErrorMessage(pathUri.path);
+  }
+} catch (err) {
+  this.showErrorMessage(pathUri.path);
+}
+  }
+
   async createDebugAdapterDescriptor(
 session: vscode.DebugSession,
 executable: vscode.DebugAdapterExecutable | undefined,
   ): Promise {
+const config = vscode.workspace.getConfiguration(
+  "lldb-dap",
+  session.workspaceFolder,
+);
+const customPath = config.get("executable-path");
+const path: string = customPath ? customPath : executable!!.command;
+
+await LLDBDapDescriptorFactory.validateDebugAdapterPath(
+  vscode.Uri.file(path),
+);
 return this.lldbDapOptions.createDapExecutableCommand(session, executable);
   }
+
+  /**
+   * Shows a message box when the debug adapter's path is not found
+   */
+  private static showErrorMessage(path: string) {
+const openSettingsAction = "Open Settings";
+vscode.window
+  .showErrorMessage(
+`Debug adapter path: ${path} is not a valid file`,
+{ modal: false },
+openSettingsAction,
+  )
+  .then((callBackValue) => {
+if (openSettingsAction === callBackValue) {
+  vscode.commands.executeCommand(
+"workbench.action.openSettings",
+"lldb-dap.executable-path",
+  );
+}
+  });
+  }

vogelsgesang wrote:

instead of `.then()` we should be able to use an `async` function here

```suggestion
  private static async showErrorMessage(path: string) {
const openSettingsAction = "Open Settings";
const selection = await vscode.window
  .showErrorMessage(
`Debug adapter path: ${path} is not a valid file`,
{ modal: false },
openSettingsAction,
  );
if (openSettingsAction === callBackValue) {
  vscode.commands.executeCommand(
"workbench.action.openSettings",
"lldb-dap.executable-path",
  );
}
  }
```

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


[Lldb-commits] [lldb] [lldb-dap] show dialog when executable is not found (PR #104711)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits


@@ -14,10 +14,52 @@ export class LLDBDapDescriptorFactory
 this.lldbDapOptions = lldbDapOptions;
   }
 
+  public static async validateDebugAdapterPath(pathUri: vscode.Uri) {
+try {
+  const fileStats = await vscode.workspace.fs.stat(pathUri);
+  if (!(fileStats.type & vscode.FileType.File)) {
+this.showErrorMessage(pathUri.path);
+  }
+} catch (err) {
+  this.showErrorMessage(pathUri.path);
+}
+  }
+
   async createDebugAdapterDescriptor(
 session: vscode.DebugSession,
 executable: vscode.DebugAdapterExecutable | undefined,
   ): Promise {
+const config = vscode.workspace.getConfiguration(
+  "lldb-dap",
+  session.workspaceFolder,
+);
+const customPath = config.get("executable-path");
+const path: string = customPath ? customPath : executable!!.command;
+
+await LLDBDapDescriptorFactory.validateDebugAdapterPath(
+  vscode.Uri.file(path),
+);
 return this.lldbDapOptions.createDapExecutableCommand(session, executable);
   }
+
+  /**
+   * Shows a message box when the debug adapter's path is not found
+   */
+  private static showErrorMessage(path: string) {
+const openSettingsAction = "Open Settings";
+vscode.window
+  .showErrorMessage(
+`Debug adapter path: ${path} is not a valid file`,
+{ modal: false },

vogelsgesang wrote:

Afaik, non-modal is the default anyway?

```suggestion
```

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


[Lldb-commits] [lldb] [lldb-dap] show dialog when executable is not found (PR #104711)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits


@@ -14,10 +14,52 @@ export class LLDBDapDescriptorFactory
 this.lldbDapOptions = lldbDapOptions;
   }
 
+  public static async validateDebugAdapterPath(pathUri: vscode.Uri) {
+try {
+  const fileStats = await vscode.workspace.fs.stat(pathUri);
+  if (!(fileStats.type & vscode.FileType.File)) {
+this.showErrorMessage(pathUri.path);
+  }
+} catch (err) {
+  this.showErrorMessage(pathUri.path);
+}
+  }
+
   async createDebugAdapterDescriptor(
 session: vscode.DebugSession,
 executable: vscode.DebugAdapterExecutable | undefined,
   ): Promise {
+const config = vscode.workspace.getConfiguration(
+  "lldb-dap",
+  session.workspaceFolder,
+);
+const customPath = config.get("executable-path");
+const path: string = customPath ? customPath : executable!!.command;
+
+await LLDBDapDescriptorFactory.validateDebugAdapterPath(
+  vscode.Uri.file(path),
+);
 return this.lldbDapOptions.createDapExecutableCommand(session, executable);
   }
+
+  /**
+   * Shows a message box when the debug adapter's path is not found
+   */
+  private static showErrorMessage(path: string) {

vogelsgesang wrote:

```suggestion
  private static showLLdbDapNotFoundMessage(path: string) {
```

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


[Lldb-commits] [lldb] [lldb-dap] show dialog when executable is not found (PR #104711)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits


@@ -14,10 +14,52 @@ export class LLDBDapDescriptorFactory
 this.lldbDapOptions = lldbDapOptions;
   }
 
+  public static async validateDebugAdapterPath(pathUri: vscode.Uri) {
+try {
+  const fileStats = await vscode.workspace.fs.stat(pathUri);
+  if (!(fileStats.type & vscode.FileType.File)) {
+this.showErrorMessage(pathUri.path);
+  }
+} catch (err) {
+  this.showErrorMessage(pathUri.path);
+}
+  }
+
   async createDebugAdapterDescriptor(
 session: vscode.DebugSession,
 executable: vscode.DebugAdapterExecutable | undefined,
   ): Promise {
+const config = vscode.workspace.getConfiguration(
+  "lldb-dap",
+  session.workspaceFolder,
+);
+const customPath = config.get("executable-path");
+const path: string = customPath ? customPath : executable!!.command;
+
+await LLDBDapDescriptorFactory.validateDebugAdapterPath(
+  vscode.Uri.file(path),
+);
 return this.lldbDapOptions.createDapExecutableCommand(session, executable);
   }
+
+  /**
+   * Shows a message box when the debug adapter's path is not found
+   */
+  private static showErrorMessage(path: string) {
+const openSettingsAction = "Open Settings";
+vscode.window
+  .showErrorMessage(
+`Debug adapter path: ${path} is not a valid file`,
+{ modal: false },

vogelsgesang wrote:

we aren't using modals in the current code. I am just proposing to be less 
epxlicit here. And not set "modal: false" as this is the default in the VS Code 
API, anyway

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

> @vogelsgesang , the $__lldb_extensions.declaration is used by the Mojo 
> extension. Once this change gets it, I'll update the Mojo extension to use 
> the new declaration info and remove $__lldb_extensions.declaration.

Is that extension's source code available? I wonder how you are currently using 
the declarationLocation in your frontend, and if your extension is based on 
`lldb-dap`. If so, would it make sense to upstream your UI integration to 
`lldb-dap`? Or maybe even to VS-Code itself?

https://github.com/llvm/llvm-project/pull/102928
___
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 value locations for function pointers (PR #104589)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/104589

>From 5bdcb821527bf67eead6c42825ea6e559ec749c3 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Sat, 10 Aug 2024 23:59:55 +
Subject: [PATCH 1/3] [lldb-dap] Implement declaration locations

This commit implements support for the "declaration location" recently
added by microsoft/debug-adapter-protocol#494 to the debug adapter
protocol.

For the `declarationLocationReference` we need a variable ID similar to
the the `variablesReference`. I decided to simply reuse the
`variablesReference` here and renamed `Variables::expandable_variables`
and friends accordingly. Given that almost all variables have a
declaration location, we now assign those variable ids to all variables.

While `declarationLocationReference` effectively supersedes
`$__lldb_extensions.declaration`, I did not remove this extension, yet,
since I assume that there are some closed-source extensions which rely
on it.

I tested this against VS-Code Insiders. However, VS-Code Insiders
currently only supports `valueLoctionReference` and not
`declarationLocationReference`, yet. Locally, I hence published
the declaration locations as value locations, and VS Code Insiders
navigated to the expected places. Looking forward to proper VS Code
support for `declarationLocationReference`.
---
 .../test/tools/lldb-dap/dap_server.py |  11 ++
 .../API/tools/lldb-dap/locations/Makefile |   3 +
 .../lldb-dap/locations/TestDAP_locations.py   |  40 +
 lldb/test/API/tools/lldb-dap/locations/main.c |   5 +
 lldb/tools/lldb-dap/DAP.cpp   |  17 +-
 lldb/tools/lldb-dap/DAP.h |  10 +-
 lldb/tools/lldb-dap/JSONUtils.cpp | 125 ---
 lldb/tools/lldb-dap/JSONUtils.h   |  31 ++--
 lldb/tools/lldb-dap/lldb-dap.cpp  | 146 +++---
 9 files changed, 286 insertions(+), 102 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
 create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 874383a13e2bb6..01ff79ee430902 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -1083,6 +1083,17 @@ def request_setVariable(self, containingVarRef, name, 
value, id=None):
 }
 return self.send_recv(command_dict)
 
+def request_locations(self, locationReference):
+args_dict = {
+"locationReference": locationReference,
+}
+command_dict = {
+"command": "locations",
+"type": "request",
+"arguments": args_dict,
+}
+return self.send_recv(command_dict)
+
 def request_testGetTargetBreakpoints(self):
 """A request packet used in the LLDB test suite to get all currently
 set breakpoint infos for all breakpoints currently set in the
diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile 
b/lldb/test/API/tools/lldb-dap/locations/Makefile
new file mode 100644
index 00..10495940055b63
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py 
b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
new file mode 100644
index 00..76d938d3908492
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py
@@ -0,0 +1,40 @@
+"""
+Test lldb-dap locations request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase):
+@skipIfWindows
+def test_locations(self):
+"""
+Tests the 'locations' request.
+"""
+program = self.getBuildArtifact("a.out")
+self.build_and_launch(program)
+source = "main.c"
+self.source_path = os.path.join(os.getcwd(), source)
+self.set_source_breakpoints(
+source,
+[line_number(source, "// BREAK HERE")],
+)
+self.continue_to_next_stop()
+
+locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
+
+# var1 has a declarationLocation but no valueLocation
+self.assertIn("declarationLocationReference", locals["var1"].keys())
+self.assertNotIn("valueLocationReference", locals["var1"].keys())
+loc_var1 = self.dap_server.request_locations(
+locals["var1"]["declarationLocationReference"]
+)
+self.assertTrue(loc_var1["success"])
+sel

[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

> @vogelsgesang , can you show a screenshot of the variables pane after this 
> change? I want to make sure that simple types, like ints, are not displayed 
> as having children.

**With this commit (and also with the changes from #104589)**

https://github.com/user-attachments/assets/862b301c-6321-47dc-9243-bb27447b093b";>

Current `main`

https://github.com/user-attachments/assets/a6102469-a41a-4b0d-873a-ce8a1fee5b74";>

As you can see, there are no differences re the absence / presence of the 
"expandable chevron" next to the variables.

That being said, I do find it a bit surprising that function pointers 
apparently return `true` for `MightHaveChildren`

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

> I'll explain what I do [...]

Thanks for that context! I don't currently have a LSP in mind. Let's see which 
UI VS-Code will be providing for this (if any). I hope it will not conflict 
with your existing UI

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-21 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

> This LGTM considering that the screenshot looks right and this passes all the 
> tests.

Thanks! I assume you still want me to wait for @clayborg's review before 
merging?

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


[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)

2024-08-22 Thread Adrian Vogelsgesang via lldb-commits


@@ -0,0 +1,40 @@
+"""
+Test lldb-dap locations request
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+import os
+
+
+class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase):
+@skipIfWindows

vogelsgesang wrote:

@walter-erquinigo based on https://github.com/llvm/llvm-project/pull/105604, it 
seems that all DAP tests are in fact disabled for Windows. Should I reintroduce 
the `SkipIfWindows`?

https://github.com/llvm/llvm-project/pull/102928
___
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 frame recognizers for libc++ `std::invoke` (PR #105695)

2024-08-22 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang created 
https://github.com/llvm/llvm-project/pull/105695

With this commit, we also hide the implementation details of `std::invoke`. To 
do so, the `LibCXXFrameRecognizer` got a couple more regular expressions.

The regular expression passed into the `AddRecognizer` became problematic, as 
it was evaluated on the demangled name. Those names also included result types 
for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, 
making the regular expresison really hard to write.

Instead, I added support for `AddRecognizer` to match on the demangled names 
without result type and argument types.

By hiding the implementation details of `invoke`, also the back traces for 
`std::function` become even nicer, because `std::function` is using `__invoke` 
internally.

>From 18365311d0cee76bced3ba26d1ed08d9f5c6cb28 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Thu, 22 Aug 2024 10:50:13 +
Subject: [PATCH] [lldb-dap] Add frame recognizers for libc++ `std::invoke`

With this commit, we also hide the implementation details of
`std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more
regular expressions.

The regular expression passed into the `AddRecognizer` became
problematic, as it was evaluated on the demangled name. Those names also
included result types for C++ symbols. For `std::__invoke` the return
type is a huge `decltype(...)`, making the regular expresison really
hard to write.

Instead, I added support for `AddRecognizer` to match on the demangled
names without result type and argument types.

By hiding the implementation details of `invoke`, also the back traces
for `std::function` become even nicer, because `std::function` is using
`__invoke` internally.
---
 .../lldb/Target/StackFrameRecognizer.h|  9 +++-
 lldb/source/Commands/Options.td   |  2 +-
 .../CPlusPlus/CPPLanguageRuntime.cpp  | 48 ++-
 lldb/source/Target/StackFrameRecognizer.cpp   | 41 ++--
 .../TestStdFunctionRecognizer.py  | 21 +++-
 .../lang/cpp/std-invoke-recognizer/Makefile   |  5 ++
 .../TestStdInvokeRecognizer.py| 28 +++
 .../lang/cpp/std-invoke-recognizer/main.cpp   | 40 
 8 files changed, 173 insertions(+), 21 deletions(-)
 create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile
 create mode 100644 
lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py
 create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp

diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h 
b/lldb/include/lldb/Target/StackFrameRecognizer.h
index 8acebc12c4b1dc..585f0b0bb59009 100644
--- a/lldb/include/lldb/Target/StackFrameRecognizer.h
+++ b/lldb/include/lldb/Target/StackFrameRecognizer.h
@@ -107,12 +107,14 @@ class StackFrameRecognizerManager {
 public:
   void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
  ConstString module, llvm::ArrayRef symbols,
- bool first_instruction_only = true);
+ bool first_instruction_only = true,
+ Mangled::NamePreference mangling_preference = 
Mangled::ePreferDemangled);
 
   void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
  lldb::RegularExpressionSP module,
  lldb::RegularExpressionSP symbol,
- bool first_instruction_only = true);
+ bool first_instruction_only = true,
+ Mangled::NamePreference mangling_preference = 
Mangled::ePreferDemangled);
 
   void ForEach(std::function<
void(uint32_t recognizer_id, std::string recognizer_name,
@@ -143,10 +145,13 @@ class StackFrameRecognizerManager {
 std::vector symbols;
 lldb::RegularExpressionSP symbol_regexp;
 bool first_instruction_only;
+Mangled::NamePreference mangling_preference;
   };
 
   std::deque m_recognizers;
   uint16_t m_generation;
+  std::unordered_set m_used_manglings;
+
 };
 
 /// \class ValueObjectRecognizerSynthesizedValue
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 9c4dbed6939ba9..df906e9d7c808f 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in {
   def thread_backtrace_extended : Option<"extended", "e">, Group<1>,
   Arg<"Boolean">, Desc<"Show the extended backtrace, if available">;
   def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>,
-  Desc<"Filter out frames according to installed frame recognizers">;
+  Desc<"Do not filter out frames according to installed frame recognizers">;
 }
 
 let Command = "thread step scope" in {
diff --git 
a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp 
b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index c60200ab186d09..3665e1a4c77e55 100644
--- a/lldb/sourc

[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)

2024-08-22 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap] Enabling instruction breakpoint support to lldb-dap. (PR #105278)

2024-08-22 Thread Adrian Vogelsgesang via lldb-commits


@@ -4078,6 +4255,9 @@ void RegisterRequestCallbacks() {
   g_dap.RegisterRequestCallback("threads", request_threads);
   g_dap.RegisterRequestCallback("variables", request_variables);
   g_dap.RegisterRequestCallback("disassemble", request_disassemble);
+  // Instruction breapoint request

vogelsgesang wrote:

I don't really know about those differences on the gdb protocol. I was only 
reading 
https://microsoft.github.io/debug-adapter-protocol/specification#Requests_SetInstructionBreakpoints

> When an instruction breakpoint is hit, a stopped event (with reason 
> `instruction breakpoint`) is generated.

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


[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)

2024-08-22 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

@mordante @ldionne FYI. Would be interested which other functions come to mind 
that should be hidden.

See https://github.com/llvm/llvm-project/pull/105457#issuecomment-226404 
for screenshots of how this looks from a user's perspective

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


[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)

2024-08-22 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/105695

>From c7cc7e9eed1ef4b95cabec5f662ebe10607b178e Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Thu, 22 Aug 2024 10:50:13 +
Subject: [PATCH] [lldb-dap] Add frame recognizers for libc++ `std::invoke`

With this commit, we also hide the implementation details of
`std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more
regular expressions.

The regular expression passed into the `AddRecognizer` became
problematic, as it was evaluated on the demangled name. Those names also
included result types for C++ symbols. For `std::__invoke` the return
type is a huge `decltype(...)`, making the regular expresison really
hard to write.

Instead, I added support for `AddRecognizer` to match on the demangled
names without result type and argument types.

By hiding the implementation details of `invoke`, also the back traces
for `std::function` become even nicer, because `std::function` is using
`__invoke` internally.
---
 .../lldb/Target/StackFrameRecognizer.h|  9 +++-
 lldb/source/Commands/Options.td   |  2 +-
 .../CPlusPlus/CPPLanguageRuntime.cpp  | 48 ++-
 lldb/source/Target/StackFrameRecognizer.cpp   | 41 ++--
 .../TestStdFunctionRecognizer.py  | 21 +++-
 .../lang/cpp/std-invoke-recognizer/Makefile   |  5 ++
 .../TestStdInvokeRecognizer.py| 31 
 .../lang/cpp/std-invoke-recognizer/main.cpp   | 40 
 8 files changed, 176 insertions(+), 21 deletions(-)
 create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile
 create mode 100644 
lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py
 create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp

diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h 
b/lldb/include/lldb/Target/StackFrameRecognizer.h
index 8acebc12c4b1dc..585f0b0bb59009 100644
--- a/lldb/include/lldb/Target/StackFrameRecognizer.h
+++ b/lldb/include/lldb/Target/StackFrameRecognizer.h
@@ -107,12 +107,14 @@ class StackFrameRecognizerManager {
 public:
   void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
  ConstString module, llvm::ArrayRef symbols,
- bool first_instruction_only = true);
+ bool first_instruction_only = true,
+ Mangled::NamePreference mangling_preference = 
Mangled::ePreferDemangled);
 
   void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
  lldb::RegularExpressionSP module,
  lldb::RegularExpressionSP symbol,
- bool first_instruction_only = true);
+ bool first_instruction_only = true,
+ Mangled::NamePreference mangling_preference = 
Mangled::ePreferDemangled);
 
   void ForEach(std::function<
void(uint32_t recognizer_id, std::string recognizer_name,
@@ -143,10 +145,13 @@ class StackFrameRecognizerManager {
 std::vector symbols;
 lldb::RegularExpressionSP symbol_regexp;
 bool first_instruction_only;
+Mangled::NamePreference mangling_preference;
   };
 
   std::deque m_recognizers;
   uint16_t m_generation;
+  std::unordered_set m_used_manglings;
+
 };
 
 /// \class ValueObjectRecognizerSynthesizedValue
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 9c4dbed6939ba9..df906e9d7c808f 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in {
   def thread_backtrace_extended : Option<"extended", "e">, Group<1>,
   Arg<"Boolean">, Desc<"Show the extended backtrace, if available">;
   def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>,
-  Desc<"Filter out frames according to installed frame recognizers">;
+  Desc<"Do not filter out frames according to installed frame recognizers">;
 }
 
 let Command = "thread step scope" in {
diff --git 
a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp 
b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index c60200ab186d09..3665e1a4c77e55 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 
 #include 
+#include 
 
 #include 
 
@@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0;
 /// A frame recognizer that is installed to hide libc++ implementation
 /// details from the backtrace.
 class LibCXXFrameRecognizer : public StackFrameRecognizer {
-  RegularExpression m_hidden_function_regex;
+  std::array m_hidden_regex;
   RecognizedStackFrameSP m_hidden_frame;
 
   struct LibCXXHiddenFrame : public RecognizedStackFrame {
@@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public StackFram

[Lldb-commits] [lldb] [lldb-dap] show dialog when executable is not found (PR #104711)

2024-08-22 Thread Adrian Vogelsgesang via lldb-commits

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


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


[Lldb-commits] [lldb] [lldb-dap] show dialog when executable is not found (PR #104711)

2024-08-22 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

Looks good to me! Thanks again for fixing this!

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


[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)

2024-08-22 Thread Adrian Vogelsgesang via lldb-commits


@@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public StackFrameRecognizer {
 
 public:
   LibCXXFrameRecognizer()
-  : m_hidden_function_regex(
-R"(^std::__1::(__function.*::operator\(\)|__invoke))"
-R"((\[.*\])?)"// ABI tag.
-R"(( const)?$)"), // const.
+  : m_hidden_regex{
+// internal implementation details of std::function
+//std::__1::__function::__alloc_func, void ()>::operator()[abi:ne20]
+//std::__1::__function::__func, void ()>::operator()
+//std::__1::__function::__value_func::operator()[abi:ne20]() const
+RegularExpression{""
+  R"(^std::__[0-9]*::)" // Namespace.
+  R"(__function::.*::operator\(\))"
+  R"((\[.*\])?)"// ABI tag.
+  R"(( const)?$)"}, // const.
+// internal implementation details of std::invoke
+//   std::__1::__invoke[abi:ne20]
+RegularExpression{
+  R"(^std::__[0-9]*::)" // Namespace.
+  R"(__invoke)"

vogelsgesang wrote:

I wonder if we should simply hide everything starting with 
`^std::__[0-9]*::__.*`. Or are there any `__` functions in libc++ which are not 
implementation details and should be shown in stacktraces by default?

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


[Lldb-commits] [lldb] [lldb] Support frame recognizer regexp on mangled names. (PR #105756)

2024-08-22 Thread Adrian Vogelsgesang via lldb-commits


@@ -92,11 +95,13 @@ void StackFrameRecognizerManager::ForEach(
 symbol_name = entry.symbol_regexp->GetText().str();
 
   callback(entry.recognizer_id, entry.recognizer->GetName(), module_name,
-   llvm::ArrayRef(ConstString(symbol_name)), true);
+   llvm::ArrayRef(ConstString(symbol_name)), entry.symbol_mangling,
+   true);
 
 } else {
   callback(entry.recognizer_id, entry.recognizer->GetName(),
-   entry.module.GetCString(), entry.symbols, false);
+   entry.module.GetCString(), entry.symbols, entry.symbol_mangling,
+   false);
 }
   }
 }

vogelsgesang wrote:

afaict, this code is incomplete. The matching in `GetRecognizerForFrame` also 
needs to be adjusted.

In https://github.com/llvm/llvm-project/pull/105695, you can find an 
implementation of pretty much the same idea. However, I implemented only 
`GetRecognizerForFrame` and skipped, e.g., `ForEach`

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


[Lldb-commits] [lldb] [lldb] Support frame recognizer regexp on mangled names. (PR #105756)

2024-08-22 Thread Adrian Vogelsgesang via lldb-commits


@@ -92,11 +95,13 @@ void StackFrameRecognizerManager::ForEach(
 symbol_name = entry.symbol_regexp->GetText().str();
 
   callback(entry.recognizer_id, entry.recognizer->GetName(), module_name,
-   llvm::ArrayRef(ConstString(symbol_name)), true);
+   llvm::ArrayRef(ConstString(symbol_name)), entry.symbol_mangling,
+   true);
 
 } else {
   callback(entry.recognizer_id, entry.recognizer->GetName(),
-   entry.module.GetCString(), entry.symbols, false);
+   entry.module.GetCString(), entry.symbols, entry.symbol_mangling,
+   false);
 }
   }
 }

vogelsgesang wrote:

Feel free to copy-paste / adjust whichever code from #105695 which you might 
find useful. I will rebase that commit later on, after your changes landed. (I 
cannot land #105695 before #104523 gets re-applied, anyway)

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


[Lldb-commits] [lldb] [lldb] Support frame recognizer regexp on mangled names. (PR #105756)

2024-08-22 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Support frame recognizer regexp on mangled names. (PR #105756)

2024-08-22 Thread Adrian Vogelsgesang via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)

2024-08-23 Thread Adrian Vogelsgesang via lldb-commits


@@ -145,6 +167,17 @@ 
StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) {
   if (!entry.module_regexp->Execute(module_name.GetStringRef()))
 continue;
 
+ConstString function_name = [&]() {
+  switch (entry.mangling_preference) {
+  case Mangled::ePreferMangled:
+return function_name_mangled;
+  case Mangled::ePreferDemangled:
+return function_name_demangled;
+  case Mangled::ePreferDemangledWithoutArguments:
+return function_name_noargs;
+  }
+}();

vogelsgesang wrote:

I wasn't sure about performance here. The code previously computed the demanded 
name only once and then checked against all frame recognizers. I am not sure 
how expensive it is to demangle a name

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


[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)

2024-08-23 Thread Adrian Vogelsgesang via lldb-commits


@@ -145,6 +167,17 @@ 
StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) {
   if (!entry.module_regexp->Execute(module_name.GetStringRef()))
 continue;
 
+ConstString function_name = [&]() {
+  switch (entry.mangling_preference) {
+  case Mangled::ePreferMangled:
+return function_name_mangled;
+  case Mangled::ePreferDemangled:
+return function_name_demangled;
+  case Mangled::ePreferDemangledWithoutArguments:
+return function_name_noargs;
+  }
+}();

vogelsgesang wrote:

By the way: I don't think I will be merging this part of my commit in the end. 
https://github.com/llvm/llvm-project/pull/105756 is very similar, and I think I 
will just rebase on it, after it got merged

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


[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)

2024-08-25 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/105695

>From 19b4370c240cfcf4a57a5c38a64c8ba933d8102c Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Thu, 22 Aug 2024 10:50:13 +
Subject: [PATCH 1/3] [lldb-dap] Add frame recognizers for libc++ `std::invoke`

With this commit, we also hide the implementation details of
`std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more
regular expressions.

The regular expression passed into the `AddRecognizer` became
problematic, as it was evaluated on the demangled name. Those names also
included result types for C++ symbols. For `std::__invoke` the return
type is a huge `decltype(...)`, making the regular expresison really
hard to write.

Instead, I added support for `AddRecognizer` to match on the demangled
names without result type and argument types.

By hiding the implementation details of `invoke`, also the back traces
for `std::function` become even nicer, because `std::function` is using
`__invoke` internally.
---
 .../lldb/Target/StackFrameRecognizer.h|  8 +++-
 lldb/source/Commands/Options.td   |  2 +-
 .../CPlusPlus/CPPLanguageRuntime.cpp  | 48 ++-
 lldb/source/Target/StackFrameRecognizer.cpp   | 41 ++--
 .../TestStdFunctionRecognizer.py  | 21 +++-
 .../lang/cpp/std-invoke-recognizer/Makefile   |  5 ++
 .../TestStdInvokeRecognizer.py| 31 
 .../lang/cpp/std-invoke-recognizer/main.cpp   | 40 
 8 files changed, 175 insertions(+), 21 deletions(-)
 create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile
 create mode 100644 
lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py
 create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp

diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h 
b/lldb/include/lldb/Target/StackFrameRecognizer.h
index 2f5c5caa6a4561..fe25dbbde745d1 100644
--- a/lldb/include/lldb/Target/StackFrameRecognizer.h
+++ b/lldb/include/lldb/Target/StackFrameRecognizer.h
@@ -107,12 +107,14 @@ class StackFrameRecognizerManager {
 public:
   void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
  ConstString module, llvm::ArrayRef symbols,
- bool first_instruction_only = true);
+ bool first_instruction_only = true,
+ Mangled::NamePreference mangling_preference = 
Mangled::ePreferDemangled);
 
   void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
  lldb::RegularExpressionSP module,
  lldb::RegularExpressionSP symbol,
- bool first_instruction_only = true);
+ bool first_instruction_only = true,
+ Mangled::NamePreference mangling_preference = 
Mangled::ePreferDemangled);
 
   void ForEach(std::function<
void(uint32_t recognizer_id, std::string recognizer_name,
@@ -143,10 +145,12 @@ class StackFrameRecognizerManager {
 std::vector symbols;
 lldb::RegularExpressionSP symbol_regexp;
 bool first_instruction_only;
+Mangled::NamePreference mangling_preference;
   };
 
   std::deque m_recognizers;
   uint16_t m_generation = 0;
+  std::unordered_set m_used_manglings;
 };
 
 /// \class ValueObjectRecognizerSynthesizedValue
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 9c4dbed6939ba9..df906e9d7c808f 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in {
   def thread_backtrace_extended : Option<"extended", "e">, Group<1>,
   Arg<"Boolean">, Desc<"Show the extended backtrace, if available">;
   def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>,
-  Desc<"Filter out frames according to installed frame recognizers">;
+  Desc<"Do not filter out frames according to installed frame recognizers">;
 }
 
 let Command = "thread step scope" in {
diff --git 
a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp 
b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index c60200ab186d09..3665e1a4c77e55 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 
 #include 
+#include 
 
 #include 
 
@@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0;
 /// A frame recognizer that is installed to hide libc++ implementation
 /// details from the backtrace.
 class LibCXXFrameRecognizer : public StackFrameRecognizer {
-  RegularExpression m_hidden_function_regex;
+  std::array m_hidden_regex;
   RecognizedStackFrameSP m_hidden_frame;
 
   struct LibCXXHiddenFrame : public RecognizedStackFrame {
@@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta

[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)

2024-08-25 Thread Adrian Vogelsgesang via lldb-commits


@@ -145,6 +167,17 @@ 
StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) {
   if (!entry.module_regexp->Execute(module_name.GetStringRef()))
 continue;
 
+ConstString function_name = [&]() {
+  switch (entry.mangling_preference) {
+  case Mangled::ePreferMangled:
+return function_name_mangled;
+  case Mangled::ePreferDemangled:
+return function_name_demangled;
+  case Mangled::ePreferDemangledWithoutArguments:
+return function_name_noargs;
+  }
+}();

vogelsgesang wrote:

> The demangling gets chached anyway (in the Mangled class). So wouldn't worry 
> about it

ah, great! I didn't know this. I removed the additional caching from 
`StackFrameRecognizer` again

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


[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)

2024-08-25 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/105695

>From 19b4370c240cfcf4a57a5c38a64c8ba933d8102c Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Thu, 22 Aug 2024 10:50:13 +
Subject: [PATCH 1/4] [lldb-dap] Add frame recognizers for libc++ `std::invoke`

With this commit, we also hide the implementation details of
`std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more
regular expressions.

The regular expression passed into the `AddRecognizer` became
problematic, as it was evaluated on the demangled name. Those names also
included result types for C++ symbols. For `std::__invoke` the return
type is a huge `decltype(...)`, making the regular expresison really
hard to write.

Instead, I added support for `AddRecognizer` to match on the demangled
names without result type and argument types.

By hiding the implementation details of `invoke`, also the back traces
for `std::function` become even nicer, because `std::function` is using
`__invoke` internally.
---
 .../lldb/Target/StackFrameRecognizer.h|  8 +++-
 lldb/source/Commands/Options.td   |  2 +-
 .../CPlusPlus/CPPLanguageRuntime.cpp  | 48 ++-
 lldb/source/Target/StackFrameRecognizer.cpp   | 41 ++--
 .../TestStdFunctionRecognizer.py  | 21 +++-
 .../lang/cpp/std-invoke-recognizer/Makefile   |  5 ++
 .../TestStdInvokeRecognizer.py| 31 
 .../lang/cpp/std-invoke-recognizer/main.cpp   | 40 
 8 files changed, 175 insertions(+), 21 deletions(-)
 create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile
 create mode 100644 
lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py
 create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp

diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h 
b/lldb/include/lldb/Target/StackFrameRecognizer.h
index 2f5c5caa6a4561..fe25dbbde745d1 100644
--- a/lldb/include/lldb/Target/StackFrameRecognizer.h
+++ b/lldb/include/lldb/Target/StackFrameRecognizer.h
@@ -107,12 +107,14 @@ class StackFrameRecognizerManager {
 public:
   void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
  ConstString module, llvm::ArrayRef symbols,
- bool first_instruction_only = true);
+ bool first_instruction_only = true,
+ Mangled::NamePreference mangling_preference = 
Mangled::ePreferDemangled);
 
   void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
  lldb::RegularExpressionSP module,
  lldb::RegularExpressionSP symbol,
- bool first_instruction_only = true);
+ bool first_instruction_only = true,
+ Mangled::NamePreference mangling_preference = 
Mangled::ePreferDemangled);
 
   void ForEach(std::function<
void(uint32_t recognizer_id, std::string recognizer_name,
@@ -143,10 +145,12 @@ class StackFrameRecognizerManager {
 std::vector symbols;
 lldb::RegularExpressionSP symbol_regexp;
 bool first_instruction_only;
+Mangled::NamePreference mangling_preference;
   };
 
   std::deque m_recognizers;
   uint16_t m_generation = 0;
+  std::unordered_set m_used_manglings;
 };
 
 /// \class ValueObjectRecognizerSynthesizedValue
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 9c4dbed6939ba9..df906e9d7c808f 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in {
   def thread_backtrace_extended : Option<"extended", "e">, Group<1>,
   Arg<"Boolean">, Desc<"Show the extended backtrace, if available">;
   def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>,
-  Desc<"Filter out frames according to installed frame recognizers">;
+  Desc<"Do not filter out frames according to installed frame recognizers">;
 }
 
 let Command = "thread step scope" in {
diff --git 
a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp 
b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index c60200ab186d09..3665e1a4c77e55 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 
 #include 
+#include 
 
 #include 
 
@@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0;
 /// A frame recognizer that is installed to hide libc++ implementation
 /// details from the backtrace.
 class LibCXXFrameRecognizer : public StackFrameRecognizer {
-  RegularExpression m_hidden_function_regex;
+  std::array m_hidden_regex;
   RecognizedStackFrameSP m_hidden_frame;
 
   struct LibCXXHiddenFrame : public RecognizedStackFrame {
@@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta

[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)

2024-08-25 Thread Adrian Vogelsgesang via lldb-commits


@@ -145,6 +167,17 @@ 
StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) {
   if (!entry.module_regexp->Execute(module_name.GetStringRef()))
 continue;
 
+ConstString function_name = [&]() {
+  switch (entry.mangling_preference) {
+  case Mangled::ePreferMangled:
+return function_name_mangled;
+  case Mangled::ePreferDemangled:
+return function_name_demangled;
+  case Mangled::ePreferDemangledWithoutArguments:
+return function_name_noargs;
+  }
+}();

vogelsgesang wrote:

> @vogelsgesang I closed my PR, feel free to copy&paste what you find useful.

I did copy over:
* the improved comments in `StackFrameRecognizer.h`
* the printing improvements to `frame recognizer list` (but I am using a 
slightly different format)

However, I did not change the `VerboseTrapFrameRecognizer` and 
`AssertFrameRecognizer` to use the mangled names. I will leave this for a 
follow-up commit.

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


[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)

2024-08-25 Thread Adrian Vogelsgesang via lldb-commits


@@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in {
   def thread_backtrace_extended : Option<"extended", "e">, Group<1>,
   Arg<"Boolean">, Desc<"Show the extended backtrace, if available">;
   def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>,
-  Desc<"Filter out frames according to installed frame recognizers">;
+  Desc<"Do not filter out frames according to installed frame recognizers">;

vogelsgesang wrote:

I don't have direct push-access and piggy-backing it in this PR is less effort 
for me

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


  1   2   3   4   5   6   >