[Lldb-commits] [lldb] [lldb-dap] Implement a MemoryMonitor for macOS & Linux (PR #129332)
@@ -0,0 +1,114 @@ +//===-- MemoryMonitor.cpp -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "MemoryMonitor.h" +#include "llvm/ADT/ScopeExit.h" +#include +#include +#include +#include + +#if defined(__APPLE__) +#include +#endif + +#if defined(__linux__) +#include +#include +#include +#endif + +using namespace lldb_dap; + +#if defined(__APPLE__) +class MemoryMonitorDarwin : public MemoryMonitor { + using MemoryMonitor::MemoryMonitor; + void Start() override { +m_memory_pressure_source = dispatch_source_create( +DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, +0, // system-wide monitoring +DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL, +dispatch_get_main_queue()); + +dispatch_source_set_event_handler(m_memory_pressure_source, ^{ + dispatch_source_memorypressure_flags_t pressureLevel = + dispatch_source_get_data(m_memory_pressure_source); + if (pressureLevel & + (DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL)) { +m_callback(); + } +}); + } + + void Stop() override { dispatch_source_cancel(m_memory_pressure_source); } ashgti wrote: Do we also need to release this? I don't think we have ARC enabled in this target. https://github.com/llvm/llvm-project/pull/129332 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Creating well defined structures for DAP messages. (PR #129155)
@@ -0,0 +1,231 @@ +//===-- Protocol.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "Protocol.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/JSON.h" +#include +#include + +using namespace llvm; + +static bool mapRaw(const json::Value &Params, StringLiteral Prop, + std::optional &V, json::Path P) { + const auto *O = Params.getAsObject(); + if (!O) { +P.report("expected object"); +return false; + } + if (const json::Value *E = O->get(Prop)) +V = std::move(Params); + return true; +} + +namespace lldb_dap { +namespace protocol { + +enum class MessageType { request, response, event }; + +bool fromJSON(const json::Value &Params, MessageType &M, json::Path P) { + auto rawType = Params.getAsString(); + if (!rawType) { +P.report("expected a string"); +return false; + } + std::optional type = + StringSwitch>(*rawType) + .Case("request", MessageType::request) + .Case("response", MessageType::response) + .Case("event", MessageType::event) + .Default(std::nullopt); + if (!type) { +P.report("unexpected value, expected 'request', 'response' or 'event'"); +return false; + } + M = *type; + return true; +} + +json::Value toJSON(const Request &R) { + json::Object Result{ + {"type", "request"}, + {"seq", R.seq}, + {"command", R.command}, + }; + + if (R.rawArguments) +Result.insert({"arguments", R.rawArguments}); + + return std::move(Result); +} + +bool fromJSON(json::Value const &Params, Request &R, json::Path P) { + json::ObjectMapper O(Params, P); + if (!O) +return false; + + MessageType type; + if (!O.map("type", type) || !O.map("command", R.command) || + !O.map("seq", R.seq)) +return false; + + if (type != MessageType::request) { +P.field("type").report("expected to be 'request'"); +return false; + } + + if (R.command.empty()) { +P.field("command").report("expected to not be ''"); +return false; + } + + if (!R.seq) { +P.field("seq").report("expected to not be '0'"); +return false; + } + + return mapRaw(Params, "arguments", R.rawArguments, P); +} + +json::Value toJSON(const Response &R) { + json::Object Result{{"type", "response"}, + {"req", 0}, vogelsgesang wrote: why are we setting `req: 0` here? Afaik, this is not part of the DAP specification? Should this be `seq` instead? (which seems to be inherited from `ProtocolMessage` in `interface Response extends ProtocolMessage` and which must be set according to the JSON schema) Using `seq` instead of `req` would also make `toJSON` consistent with your `fromJSON` below. https://github.com/llvm/llvm-project/pull/129155 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add process picker command to VS Code extension (PR #128943)
@@ -0,0 +1,38 @@ +import { ChildProcessWithoutNullStreams, spawn } from "child_process"; +import { BaseProcessTree, ProcessTreeParser } from "../base-process-tree"; + +export class LinuxProcessTree extends BaseProcessTree { + protected override spawnProcess(): ChildProcessWithoutNullStreams { +return spawn( + "ps", + ["-axo", `pid=PID,lstart=START,comm:128=COMMAND,command=ARGUMENTS`], Da-Viper wrote: we may also want to ignore traced/zombie processes as lldb won't be able to attach to those. https://github.com/llvm/llvm-project/pull/128943 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] Add: show return value on step out (PR #106907)
https://github.com/Da-Viper updated https://github.com/llvm/llvm-project/pull/106907 >From c5dda32e63371b3f265a209fdcd5105a7c6197dc Mon Sep 17 00:00:00 2001 From: Ezike Ebuka Date: Wed, 12 Feb 2025 00:16:46 + Subject: [PATCH 1/5] [lldb-dap] Add Tests: Show children for return values --- .../lldb-dap/variables/TestDAP_variables.py | 57 +++ .../children/TestDAP_variables_children.py| 55 ++ .../lldb-dap/variables/children/main.cpp | 12 .../API/tools/lldb-dap/variables/main.cpp | 9 +++ 4 files changed, 122 insertions(+), 11 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 fde66a28382c7..dba62d11d021e 100644 --- a/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py +++ b/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py @@ -341,9 +341,9 @@ def do_test_scopes_variables_setVariable_evaluate( verify_locals["argc"]["equals"]["value"] = "123" verify_locals["pt"]["children"]["x"]["equals"]["value"] = "111" -verify_locals["x @ main.cpp:17"] = {"equals": {"type": "int", "value": "89"}} -verify_locals["x @ main.cpp:19"] = {"equals": {"type": "int", "value": "42"}} -verify_locals["x @ main.cpp:21"] = {"equals": {"type": "int", "value": "72"}} +verify_locals["x @ main.cpp:19"] = {"equals": {"type": "int", "value": "89"}} +verify_locals["x @ main.cpp:21"] = {"equals": {"type": "int", "value": "42"}} +verify_locals["x @ main.cpp:23"] = {"equals": {"type": "int", "value": "72"}} self.verify_variables(verify_locals, self.dap_server.get_local_variables()) @@ -353,32 +353,32 @@ def do_test_scopes_variables_setVariable_evaluate( self.dap_server.request_setVariable(1, "x @ main.cpp:0", 9)["success"] ) -self.assertTrue( -self.dap_server.request_setVariable(1, "x @ main.cpp:17", 17)["success"] -) self.assertTrue( self.dap_server.request_setVariable(1, "x @ main.cpp:19", 19)["success"] ) self.assertTrue( self.dap_server.request_setVariable(1, "x @ main.cpp:21", 21)["success"] ) +self.assertTrue( +self.dap_server.request_setVariable(1, "x @ main.cpp:23", 23)["success"] +) # The following should have no effect self.assertFalse( -self.dap_server.request_setVariable(1, "x @ main.cpp:21", "invalid")[ +self.dap_server.request_setVariable(1, "x @ main.cpp:23", "invalid")[ "success" ] ) -verify_locals["x @ main.cpp:17"]["equals"]["value"] = "17" verify_locals["x @ main.cpp:19"]["equals"]["value"] = "19" verify_locals["x @ main.cpp:21"]["equals"]["value"] = "21" +verify_locals["x @ main.cpp:23"]["equals"]["value"] = "23" self.verify_variables(verify_locals, self.dap_server.get_local_variables()) # The plain x variable shold refer to the innermost x self.assertTrue(self.dap_server.request_setVariable(1, "x", 22)["success"]) -verify_locals["x @ main.cpp:21"]["equals"]["value"] = "22" +verify_locals["x @ main.cpp:23"]["equals"]["value"] = "22" self.verify_variables(verify_locals, self.dap_server.get_local_variables()) @@ -394,10 +394,10 @@ def do_test_scopes_variables_setVariable_evaluate( locals = self.dap_server.get_local_variables() names = [var["name"] for var in locals] # The first shadowed x shouldn't have a suffix anymore -verify_locals["x"] = {"equals": {"type": "int", "value": "17"}} -self.assertNotIn("x @ main.cpp:17", names) +verify_locals["x"] = {"equals": {"type": "int", "value": "19"}} self.assertNotIn("x @ main.cpp:19", names) self.assertNotIn("x @ main.cpp:21", names) +self.assertNotIn("x @ main.cpp:23", names) self.verify_variables(verify_locals, locals) @@ -663,6 +663,41 @@ def do_test_indexedVariables(self, enableSyntheticChildDebugging: bool): ]["variables"] self.verify_variables(verify_children, children) +def test_return_variables(self): +""" +Test the stepping out of a function with return value show the variable correctly. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) + +verify_locals = { +"(Return Value)": {"equals": {"type": "int", "value": "300"}}, +"argc": {}, +"argv": {}, +"pt": {}, +"x": {}, +"return_result": {"equals": {"type": "int"}}, +} + +function_name = "test_return_variable" +breakpoint_ids = self.set_function_breakpoints([function_name]) + +self.assertEqual(len(breakpoint_ids), 1) +self.continue_to_breakp
[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)
https://github.com/JDevlieghere approved this pull request. Thanks, this LGTM! https://github.com/llvm/llvm-project/pull/129262 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add process picker command to VS Code extension (PR #128943)
@@ -146,6 +146,9 @@ "windows": { "program": "./bin/lldb-dap.exe" }, +"variables": { + "PickProcess": "lldb-dap.pickProcess" Da-Viper wrote: use camelcase https://github.com/llvm/llvm-project/pull/128943 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add process picker command to VS Code extension (PR #128943)
@@ -0,0 +1,16 @@ +import { ChildProcessWithoutNullStreams, spawn } from "child_process"; +import { LinuxProcessTree } from "./linux-process-tree"; + +function fill(prefix: string, suffix: string, length: number): string { Da-Viper wrote: you could use the `padEnd` i.e `"COMMAND".padEnd(256, '-')` see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd) or use the unlimited width for the command name in ps with the `ww` flag. It has to be the last column on freebsd unless it is ignored quote. > -w Use at least 132 columns to display information, instead of the default which is the window size if ps is associated with a terminal. If the -w option is specified more than once, ps will use as many columns as necessary without regard for the window size. Note that this option has no effect if the "command" column is not the last column displayed. [freebsd](https://man.freebsd.org/cgi/man.cgi?ps(1)) [linux](https://man7.org/linux/man-pages/man1/ps.1.html) [mac](https://www.unix.com/man_page/osx/1/ps/) https://github.com/llvm/llvm-project/pull/128943 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add process picker command to VS Code extension (PR #128943)
@@ -0,0 +1,52 @@ +import * as path from "path"; +import { BaseProcessTree, ProcessTreeParser } from "../base-process-tree"; +import { ChildProcessWithoutNullStreams, spawn } from "child_process"; + +export class WindowsProcessTree extends BaseProcessTree { + protected override spawnProcess(): ChildProcessWithoutNullStreams { +const wmic = path.join( + process.env["WINDIR"] || "C:\\Windows", + "System32", + "wbem", + "WMIC.exe", Da-Viper wrote: Is seems that the WMIC is program is disabled on windows 11 as it was deprecated in windows 10 see [here](https://techcommunity.microsoft.com/blog/windows-itpro-blog/wmi-command-line-wmic-utility-deprecation-next-steps/4039242) I am not able to confirm this on a computer as I do not have a windows 11 computer https://github.com/llvm/llvm-project/pull/128943 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add process picker command to VS Code extension (PR #128943)
@@ -517,6 +520,16 @@ "cwd": "^\"\\${workspaceRoot}\"" } }, + { +"label": "LLDB: Attach to Process", +"description": "", +"body": { + "type": "lldb-dap", + "request": "attach", + "name": "${1:Attach}", + "pid": "^\"\\${command:PickProcess}\"" Da-Viper wrote: use camel case for `PickProcess` https://github.com/llvm/llvm-project/pull/128943 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add process picker command to VS Code extension (PR #128943)
Da-Viper wrote: you could also validate the pid input in package.json from https://github.com/llvm/llvm-project/blob/038731c709c665634714275996559c21f36372f2/lldb/tools/lldb-dap/package.json#L359-L364 to ```json "pid": { "anyOf": [ { "type": "number", "description": "System process ID to attach to." }, { "const": "${command:pickProcess}", "description": "Picks a process ID using the process ID picker" } ] }, ``` https://github.com/llvm/llvm-project/pull/128943 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)
@@ -137,53 +157,59 @@ export class LLDBDapDescriptorFactory const dbgOptions = { env: { -...executable?.options?.env, ...configEnvironment, ...env, }, }; -const dbgArgs = executable?.args ?? []; JDevlieghere wrote: I'm not but I'd be curious to find out too. https://github.com/llvm/llvm-project/pull/129262 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] Add: show return value on step out (PR #106907)
Da-Viper wrote: > @Da-Viper Can you rebase and merge this PR by yourself? Or do you need > somebody to merge it on your behalf? I rebased but I do not have the necessary permissions to merge https://github.com/llvm/llvm-project/pull/106907 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 8ec0d60 - [lldb-dap] Add: show return value on step out (#106907)
Author: Da-Viper Date: 2025-03-01T18:21:21-06:00 New Revision: 8ec0d60e28f77149eef9c865515b79bc0a5e8f41 URL: https://github.com/llvm/llvm-project/commit/8ec0d60e28f77149eef9c865515b79bc0a5e8f41 DIFF: https://github.com/llvm/llvm-project/commit/8ec0d60e28f77149eef9c865515b79bc0a5e8f41.diff LOG: [lldb-dap] Add: show return value on step out (#106907) https://github.com/user-attachments/assets/cff48c6f-37ae-4f72-b881-3eff4178fb3c Added: Modified: lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py lldb/test/API/tools/lldb-dap/variables/children/main.cpp lldb/test/API/tools/lldb-dap/variables/main.cpp lldb/tools/lldb-dap/Handler/VariablesRequestHandler.cpp llvm/docs/ReleaseNotes.md Removed: 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 fde66a28382c7..ee5b49de14d98 100644 --- a/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py +++ b/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py @@ -341,9 +341,9 @@ def do_test_scopes_variables_setVariable_evaluate( verify_locals["argc"]["equals"]["value"] = "123" verify_locals["pt"]["children"]["x"]["equals"]["value"] = "111" -verify_locals["x @ main.cpp:17"] = {"equals": {"type": "int", "value": "89"}} -verify_locals["x @ main.cpp:19"] = {"equals": {"type": "int", "value": "42"}} -verify_locals["x @ main.cpp:21"] = {"equals": {"type": "int", "value": "72"}} +verify_locals["x @ main.cpp:19"] = {"equals": {"type": "int", "value": "89"}} +verify_locals["x @ main.cpp:21"] = {"equals": {"type": "int", "value": "42"}} +verify_locals["x @ main.cpp:23"] = {"equals": {"type": "int", "value": "72"}} self.verify_variables(verify_locals, self.dap_server.get_local_variables()) @@ -353,32 +353,32 @@ def do_test_scopes_variables_setVariable_evaluate( self.dap_server.request_setVariable(1, "x @ main.cpp:0", 9)["success"] ) -self.assertTrue( -self.dap_server.request_setVariable(1, "x @ main.cpp:17", 17)["success"] -) self.assertTrue( self.dap_server.request_setVariable(1, "x @ main.cpp:19", 19)["success"] ) self.assertTrue( self.dap_server.request_setVariable(1, "x @ main.cpp:21", 21)["success"] ) +self.assertTrue( +self.dap_server.request_setVariable(1, "x @ main.cpp:23", 23)["success"] +) # The following should have no effect self.assertFalse( -self.dap_server.request_setVariable(1, "x @ main.cpp:21", "invalid")[ +self.dap_server.request_setVariable(1, "x @ main.cpp:23", "invalid")[ "success" ] ) -verify_locals["x @ main.cpp:17"]["equals"]["value"] = "17" verify_locals["x @ main.cpp:19"]["equals"]["value"] = "19" verify_locals["x @ main.cpp:21"]["equals"]["value"] = "21" +verify_locals["x @ main.cpp:23"]["equals"]["value"] = "23" self.verify_variables(verify_locals, self.dap_server.get_local_variables()) # The plain x variable shold refer to the innermost x self.assertTrue(self.dap_server.request_setVariable(1, "x", 22)["success"]) -verify_locals["x @ main.cpp:21"]["equals"]["value"] = "22" +verify_locals["x @ main.cpp:23"]["equals"]["value"] = "22" self.verify_variables(verify_locals, self.dap_server.get_local_variables()) @@ -394,10 +394,10 @@ def do_test_scopes_variables_setVariable_evaluate( locals = self.dap_server.get_local_variables() names = [var["name"] for var in locals] # The first shadowed x shouldn't have a suffix anymore -verify_locals["x"] = {"equals": {"type": "int", "value": "17"}} -self.assertNotIn("x @ main.cpp:17", names) +verify_locals["x"] = {"equals": {"type": "int", "value": "19"}} self.assertNotIn("x @ main.cpp:19", names) self.assertNotIn("x @ main.cpp:21", names) +self.assertNotIn("x @ main.cpp:23", names) self.verify_variables(verify_locals, locals) @@ -663,6 +663,54 @@ def do_test_indexedVariables(self, enableSyntheticChildDebugging: bool): ]["variables"] self.verify_variables(verify_children, children) +def test_return_variables(self): +""" +Test the stepping out of a function with return value show the variable correctly. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) + +return_name = "(Return Value)" +verify_locals = { +return_name: {"equals": {"type": "int", "value": "300"}}, +"argc": {}, +
[Lldb-commits] [lldb] Fix a bug copying the stop hooks from the dummy target. (PR #129340)
https://github.com/JDevlieghere approved this pull request. https://github.com/llvm/llvm-project/pull/129340 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Implement a MemoryMonitor for macOS & Linux (PR #129332)
https://github.com/JDevlieghere edited https://github.com/llvm/llvm-project/pull/129332 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Adding server mode support to lldb-dap VSCode extension. (PR #128957)
@@ -15,13 +13,14 @@ import { DisposableContext } from "./disposable-context"; export class LLDBDapExtension extends DisposableContext { constructor() { super(); +const factory = new LLDBDapDescriptorFactory(); +this.pushSubscription(factory); ashgti wrote: I made the factor itself implement `vscode.Disposable` so if the extension is deactivated it will stop the server, if its running. https://github.com/llvm/llvm-project/pull/128957 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Implement `runInTerminal` for Windows (PR #121269)
https://github.com/SuibianP updated https://github.com/llvm/llvm-project/pull/121269 >From 20fbed5a080a90aabe1d3f8c316af56e91284c1e Mon Sep 17 00:00:00 2001 From: Jialun Hu Date: Mon, 24 Feb 2025 22:10:17 +0800 Subject: [PATCH] [lldb-dap] Implement runInTerminal for Windows Currently, the named pipe is passed by name and a transient ofstream is constructed at each I/O request. This assumes, - Blocking semantics: FIFO I/O waits for the other side to connect. - Buffered semantics: Closing one side does not discard existing data. The former can be replaced by WaitNamedPipe/ConnectNamedPipe on Win32, but the second cannot be easily worked around. It is also impossible to have another "keep-alive" pipe server instance, as server-client pairs are fixed on connection on Win32 and the client may get connected to it instead of the real one. Refactor FifoFile[IO] to use an open file handles rather than file name. --- Win32 provides no way to replace the process image. Under the hood exec* actually creates a new process with a new PID. DebugActiveProcess also cannot get notified of process creations. Create the new process in a suspended state and resume it after attach. --- lldb/packages/Python/lldbsuite/test/dotest.py | 2 +- .../API/tools/lldb-dap/runInTerminal/Makefile | 2 +- .../runInTerminal/TestDAP_runInTerminal.py| 5 +- .../API/tools/lldb-dap/runInTerminal/main.c | 11 -- .../API/tools/lldb-dap/runInTerminal/main.cpp | 13 ++ lldb/tools/lldb-dap/FifoFiles.cpp | 131 +++--- lldb/tools/lldb-dap/FifoFiles.h | 35 +++-- .../tools/lldb-dap/Handler/RequestHandler.cpp | 8 +- lldb/tools/lldb-dap/RunInTerminal.cpp | 45 +++--- lldb/tools/lldb-dap/RunInTerminal.h | 11 +- lldb/tools/lldb-dap/lldb-dap.cpp | 63 +++-- 11 files changed, 243 insertions(+), 83 deletions(-) delete mode 100644 lldb/test/API/tools/lldb-dap/runInTerminal/main.c create mode 100644 lldb/test/API/tools/lldb-dap/runInTerminal/main.cpp diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py index 681ea1638f2d6..538cece8b4913 100644 --- a/lldb/packages/Python/lldbsuite/test/dotest.py +++ b/lldb/packages/Python/lldbsuite/test/dotest.py @@ -545,7 +545,7 @@ def setupSysPath(): lldbDir = os.path.dirname(lldbtest_config.lldbExec) -lldbDAPExec = os.path.join(lldbDir, "lldb-dap") +lldbDAPExec = os.path.join(lldbDir, "lldb-dap.exe" if os.name == "nt" else "lldb-dap") if is_exe(lldbDAPExec): os.environ["LLDBDAP_EXEC"] = lldbDAPExec diff --git a/lldb/test/API/tools/lldb-dap/runInTerminal/Makefile b/lldb/test/API/tools/lldb-dap/runInTerminal/Makefile index 10495940055b6..8b20bcb05 100644 --- a/lldb/test/API/tools/lldb-dap/runInTerminal/Makefile +++ b/lldb/test/API/tools/lldb-dap/runInTerminal/Makefile @@ -1,3 +1,3 @@ -C_SOURCES := main.c +CXX_SOURCES := main.cpp include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py b/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py index 9141565ac1b9b..d31d8d443f7a7 100644 --- a/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py +++ b/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py @@ -43,7 +43,6 @@ def isTestSupported(self): except: return False -@skipIfWindows @skipIf(archs=no_match(["x86_64"])) def test_runInTerminal(self): if not self.isTestSupported(): @@ -53,7 +52,7 @@ def test_runInTerminal(self): launch the inferior with the correct environment variables and arguments. """ program = self.getBuildArtifact("a.out") -source = "main.c" +source = "main.cpp" self.build_and_launch( program, runInTerminal=True, args=["foobar"], env=["FOO=bar"] ) @@ -113,7 +112,6 @@ def test_runInTerminalWithObjectEnv(self): self.assertIn("FOO", request_envs) self.assertEqual("BAR", request_envs["FOO"]) -@skipIfWindows @skipIf(archs=no_match(["x86_64"])) def test_runInTerminalInvalidTarget(self): if not self.isTestSupported(): @@ -132,7 +130,6 @@ def test_runInTerminalInvalidTarget(self): response["message"], ) -@skipIfWindows @skipIf(archs=no_match(["x86_64"])) def test_missingArgInRunInTerminalLauncher(self): if not self.isTestSupported(): diff --git a/lldb/test/API/tools/lldb-dap/runInTerminal/main.c b/lldb/test/API/tools/lldb-dap/runInTerminal/main.c deleted file mode 100644 index 676bd830e657b..0 --- a/lldb/test/API/tools/lldb-dap/runInTerminal/main.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include -#include - -int main(int argc, char *argv[]) { - const char *foo = getenv("FOO"); - for (int counter = 1;; counter++) { -sleep(1); // breakpoint - } - return 0; -} diff --git a/lldb/test/API/tools
[Lldb-commits] [lldb] [lldb-dap] Add process picker command to VS Code extension (PR #128943)
@@ -0,0 +1,15 @@ +import { LinuxProcessTree } from "./linux-process-tree"; + +function fill(prefix: string, suffix: string, length: number): string { + return prefix + suffix.repeat(length - prefix.length); +} + +export class DarwinProcessTree extends LinuxProcessTree { + protected override getCommandArguments(): string[] { +return [ + "-xo", + // The length of comm must be large enough or data will be truncated. + `pid=PID,lstart=START,comm=${fill("COMMAND", "-", 256)},command=ARGUMENTS`, vogelsgesang wrote: could we just use the same, padded `COMMAND` also on Linux, removing the distinction between Darwin and Linux? https://github.com/llvm/llvm-project/pull/128943 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Implement `runInTerminal` for Windows (PR #121269)
@@ -1,11 +1,13 @@ #include #include -#include + +#include SuibianP wrote: Turns out Apple does not yet support C11 `threads.h`. https://github.com/llvm/llvm-project/blob/7e8a06cfa4a2951b8ee77e19e34926e6e535b4d1/clang/lib/Basic/Targets/OSTargets.cpp#L61-L62 Changed test case to use C++11 `thread` which is supported. https://github.com/llvm/llvm-project/pull/121269 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Implement `runInTerminal` for Windows (PR #121269)
https://github.com/SuibianP edited https://github.com/llvm/llvm-project/pull/121269 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Adding server mode support to lldb-dap VSCode extension. (PR #128957)
ashgti wrote: I filed #129283 to track some of the improvements discussed in the comments so they're not lost. https://github.com/llvm/llvm-project/pull/128957 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Creating well defined structures for DAP messages. (PR #129155)
@@ -0,0 +1,231 @@ +//===-- Protocol.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "Protocol.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/JSON.h" +#include +#include + +using namespace llvm; + +static bool mapRaw(const json::Value &Params, StringLiteral Prop, + std::optional &V, json::Path P) { + const auto *O = Params.getAsObject(); + if (!O) { +P.report("expected object"); +return false; + } + if (const json::Value *E = O->get(Prop)) +V = std::move(Params); + return true; +} + +namespace lldb_dap { +namespace protocol { + +enum class MessageType { request, response, event }; + +bool fromJSON(const json::Value &Params, MessageType &M, json::Path P) { + auto rawType = Params.getAsString(); + if (!rawType) { +P.report("expected a string"); +return false; + } + std::optional type = + StringSwitch>(*rawType) + .Case("request", MessageType::request) + .Case("response", MessageType::response) + .Case("event", MessageType::event) + .Default(std::nullopt); + if (!type) { +P.report("unexpected value, expected 'request', 'response' or 'event'"); +return false; + } + M = *type; + return true; +} + +json::Value toJSON(const Request &R) { + json::Object Result{ + {"type", "request"}, + {"seq", R.seq}, + {"command", R.command}, + }; + + if (R.rawArguments) +Result.insert({"arguments", R.rawArguments}); + + return std::move(Result); +} + +bool fromJSON(json::Value const &Params, Request &R, json::Path P) { + json::ObjectMapper O(Params, P); + if (!O) +return false; + + MessageType type; + if (!O.map("type", type) || !O.map("command", R.command) || + !O.map("seq", R.seq)) +return false; + + if (type != MessageType::request) { +P.field("type").report("expected to be 'request'"); +return false; + } + + if (R.command.empty()) { +P.field("command").report("expected to not be ''"); +return false; + } + + if (!R.seq) { +P.field("seq").report("expected to not be '0'"); +return false; + } + + return mapRaw(Params, "arguments", R.rawArguments, P); +} + +json::Value toJSON(const Response &R) { + json::Object Result{{"type", "response"}, + {"req", 0}, + {"command", R.command}, + {"request_seq", R.request_seq}, + {"success", R.success}}; + + if (R.message) +Result.insert({"message", R.message}); + + if (R.rawBody) +Result.insert({"body", R.rawBody}); + + return std::move(Result); +} + +bool fromJSON(json::Value const &Params, Response &R, json::Path P) { + json::ObjectMapper O(Params, P); + if (!O) +return false; + + MessageType type; + int64_t seq; + if (!O.map("type", type) || !O.map("seq", seq) || + !O.map("command", R.command) || !O.map("request_seq", R.request_seq)) +return false; + + if (type != MessageType::response) { +P.field("type").report("expected to be 'response'"); +return false; + } + + if (seq != 0) { +P.field("seq").report("expected to be '0'"); +return false; + } + + if (R.command.empty()) { +P.field("command").report("expected to not be ''"); +return false; + } + + if (R.request_seq == 0) { +P.field("request_seq").report("expected to not be '0'"); +return false; + } + + return O.map("success", R.success) && O.mapOptional("message", R.message) && + mapRaw(Params, "body", R.rawBody, P); +} + +json::Value toJSON(const Event &E) { + json::Object Result{ + {"type", "event"}, + {"seq", 0}, + {"event", E.event}, + }; + + if (E.rawBody) +Result.insert({"body", E.rawBody}); + + if (E.statistics) +Result.insert({"statistics", E.statistics}); vogelsgesang wrote: can we break the current behavior here, and move the statistics into the `body`, e.g. under a `$__lldb_extension_statistics` key? That would allow us to remove this adhoc "statistics" parameter here https://github.com/llvm/llvm-project/pull/129155 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add terminfo dependency for ncurses support (PR #126810)
https://github.com/ajordanr-google milestoned https://github.com/llvm/llvm-project/pull/126810 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix a bug copying the stop hooks from the dummy target. (PR #129340)
https://github.com/jimingham updated https://github.com/llvm/llvm-project/pull/129340 >From 02e908312518e85f1d637529c9f62e3dd9551035 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Fri, 28 Feb 2025 15:55:03 -0800 Subject: [PATCH 1/4] Fix a bug copying the stop hooks from the dummy target. We didn't also copy over the next stop hook id, which meant we would overwrite the stop hooks from the dummy target with stop hooks set after they are copied over. --- lldb/source/Target/Target.cpp | 1 + .../target/stop-hooks/TestStopHooks.py| 24 +-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index db289fe9c4b64..550424720e095 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -211,6 +211,7 @@ Target::~Target() { void Target::PrimeFromDummyTarget(Target &target) { m_stop_hooks = target.m_stop_hooks; + m_stop_hook_next_id = target.m_stop_hook_next_id; for (const auto &breakpoint_sp : target.m_breakpoint_list.Breakpoints()) { if (breakpoint_sp->IsInternal()) diff --git a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py index fe59bd8a5d007..5215ec7258d14 100644 --- a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py +++ b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py @@ -26,10 +26,15 @@ def test_stop_hooks_step_out(self): self.step_out_test() def test_stop_hooks_after_expr(self): -"""Test that a stop hook fires when hitting a breakpoint -that runs an expression""" +"""Test that a stop hook fires when hitting a breakpoint that + runs an expression""" self.after_expr_test() +def test_stop_hooks_before_and_after_creation(self): +"""Test that if we add a stop hook in the dummy target, we can + they don't collide with ones set directly in the target.""" +self.before_and_after_target() + def step_out_test(self): (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( self, "Set a breakpoint here", self.main_source_file @@ -85,3 +90,18 @@ def after_expr_test(self): var = target.FindFirstGlobalVariable("g_var") self.assertTrue(var.IsValid()) self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var") + +def before_and_after_target(self): +interp = self.dbg.GetCommandInterpreter() +result = lldb.SBCommandReturnObject() +interp.HandleCommand("target stop-hook add -o 'expr g_var++'", result) +self.assertTrue(result.Succeeded(), "Set the target stop hook") + +(target, process, thread, first_bkpt) = lldbutil.run_to_source_breakpoint( +self, "Set a breakpoint here", self.main_source_file +) + +interp.HandleCommand("target stop-hook add -o 'thread backtrace'", result) +self.assertTrue(result.Succeeded(), "Set the target stop hook") +self.expect("target stop-hook list", substrs=["expr g_var++", "thread backtrace"]) + >From 72e6f179525f1e13e7a1617ab04853304d116537 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Fri, 28 Feb 2025 16:23:31 -0800 Subject: [PATCH 2/4] uglify --- .../test/API/commands/target/stop-hooks/TestStopHooks.py | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py index 5215ec7258d14..c2cdcf0e2af52 100644 --- a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py +++ b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py @@ -27,12 +27,12 @@ def test_stop_hooks_step_out(self): def test_stop_hooks_after_expr(self): """Test that a stop hook fires when hitting a breakpoint that - runs an expression""" +runs an expression""" self.after_expr_test() def test_stop_hooks_before_and_after_creation(self): """Test that if we add a stop hook in the dummy target, we can - they don't collide with ones set directly in the target.""" +they don't collide with ones set directly in the target.""" self.before_and_after_target() def step_out_test(self): @@ -103,5 +103,6 @@ def before_and_after_target(self): interp.HandleCommand("target stop-hook add -o 'thread backtrace'", result) self.assertTrue(result.Succeeded(), "Set the target stop hook") -self.expect("target stop-hook list", substrs=["expr g_var++", "thread backtrace"]) - +self.expect( +"target stop-hook list", substrs=["expr g_var++", "thread backtrace"] +) >From 1f2d82a0d89c7eef48753840d06d63624b1fb8fd Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Fri, 28 Feb 2025 16:59:54 -0800 Subject: [PATCH 3/4] Better comment on the test. --- lldb/test/API/commands/target/sto
[Lldb-commits] [lldb] [llvm] [lldb-dap] Add: show return value on step out (PR #106907)
https://github.com/vogelsgesang approved this pull request. LGTM! Thank you 🙂 https://github.com/llvm/llvm-project/pull/106907 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] Add: show return value on step out (PR #106907)
vogelsgesang wrote: @Da-Viper Can you rebase and merge this PR by yourself? Or do you need somebody to merge it on your behalf? https://github.com/llvm/llvm-project/pull/106907 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits