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

>From 756174c282fc7101bfadb29556f39ce046ad0116 Mon Sep 17 00:00:00 2001
From: John Harrison <harj...@google.com>
Date: Wed, 7 May 2025 14:54:29 -0700
Subject: [PATCH 1/2] [lldb-dap] Adding a modules explorer to lldb-dap ext.

This creates a very basic module explorer for tracking and displaying loaded 
modules, reported by lldb-dap for the active debug session.

This includes a basic session tracker that we can use to observe the debug 
session and collect specific information for additional visualizations in the 
lldb-dap ext.
---
 lldb/tools/lldb-dap/package-lock.json         | 12 ++-
 lldb/tools/lldb-dap/package.json              | 15 +++-
 .../src-ts/debug-configuration-provider.ts    |  2 +-
 .../lldb-dap/src-ts/debug-session-tracker.ts  | 87 +++++++++++++++++++
 .../lldb-dap/src-ts/disposable-context.ts     |  4 +-
 lldb/tools/lldb-dap/src-ts/extension.ts       | 18 ++++
 .../src-ts/ui/modules-data-provider.ts        | 58 +++++++++++++
 7 files changed, 189 insertions(+), 7 deletions(-)
 create mode 100644 lldb/tools/lldb-dap/src-ts/debug-session-tracker.ts
 create mode 100644 lldb/tools/lldb-dap/src-ts/ui/modules-data-provider.ts

diff --git a/lldb/tools/lldb-dap/package-lock.json 
b/lldb/tools/lldb-dap/package-lock.json
index ab5c7dc33a8e5..0a2b9e764067e 100644
--- a/lldb/tools/lldb-dap/package-lock.json
+++ b/lldb/tools/lldb-dap/package-lock.json
@@ -1,16 +1,17 @@
 {
   "name": "lldb-dap",
-  "version": "0.2.10",
+  "version": "0.2.13",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "lldb-dap",
-      "version": "0.2.10",
+      "version": "0.2.13",
       "license": "Apache 2.0 License with LLVM exceptions",
       "devDependencies": {
         "@types/node": "^18.19.41",
         "@types/vscode": "1.75.0",
+        "@vscode/debugprotocol": "^1.68.0",
         "@vscode/vsce": "^3.2.2",
         "prettier": "^3.4.2",
         "prettier-plugin-curly": "^0.3.1",
@@ -405,6 +406,13 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/@vscode/debugprotocol": {
+      "version": "1.68.0",
+      "resolved": 
"https://registry.npmjs.org/@vscode/debugprotocol/-/debugprotocol-1.68.0.tgz";,
+      "integrity": 
"sha512-2J27dysaXmvnfuhFGhfeuxfHRXunqNPxtBoR3koiTOA9rdxWNDTa1zIFLCFMSHJ9MPTPKFcBeblsyaCJCIlQxg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/@vscode/vsce": {
       "version": "3.2.2",
       "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.2.2.tgz";,
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index f66badc2a930f..a8dce7cab8a79 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -30,9 +30,10 @@
   "devDependencies": {
     "@types/node": "^18.19.41",
     "@types/vscode": "1.75.0",
+    "@vscode/debugprotocol": "^1.68.0",
     "@vscode/vsce": "^3.2.2",
-    "prettier-plugin-curly": "^0.3.1",
     "prettier": "^3.4.2",
+    "prettier-plugin-curly": "^0.3.1",
     "typescript": "^5.7.3"
   },
   "activationEvents": [
@@ -763,6 +764,16 @@
           }
         ]
       }
-    ]
+    ],
+    "views": {
+      "debug": [
+        {
+          "id": "lldb-dap.modulesExplorer",
+          "name": "LLDB Modules Explorer",
+          "when": "inDebugMode && debugType == 'lldb-dap'",
+          "icon": "$(symbol-module)"
+        }
+      ]
+    }
   }
 }
diff --git a/lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts 
b/lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts
index c91b101f4a9ba..957bc5e1eb956 100644
--- a/lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts
+++ b/lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts
@@ -78,7 +78,7 @@ export class LLDBDapConfigurationProvider
     debugConfiguration: vscode.DebugConfiguration,
     token?: vscode.CancellationToken,
   ): Promise<vscode.DebugConfiguration> {
-    let config = vscode.workspace.getConfiguration("lldb-dap.defaults");
+    let config = vscode.workspace.getConfiguration("lldb-dap");
     for (const [key, cfg] of Object.entries(configurations)) {
       if (Reflect.has(debugConfiguration, key)) {
         continue;
diff --git a/lldb/tools/lldb-dap/src-ts/debug-session-tracker.ts 
b/lldb/tools/lldb-dap/src-ts/debug-session-tracker.ts
new file mode 100644
index 0000000000000..d756e9e743bb0
--- /dev/null
+++ b/lldb/tools/lldb-dap/src-ts/debug-session-tracker.ts
@@ -0,0 +1,87 @@
+import { DebugProtocol } from "@vscode/debugprotocol";
+import * as vscode from "vscode";
+
+interface EventMap {
+  module: DebugProtocol.ModuleEvent;
+}
+
+function isEvent(
+  message: DebugProtocol.ProtocolMessage,
+): message is DebugProtocol.Event;
+function isEvent<K extends keyof EventMap>(
+  message: DebugProtocol.ProtocolMessage,
+  event: K,
+): message is EventMap[K];
+function isEvent(
+  message: DebugProtocol.ProtocolMessage,
+  event?: string,
+): boolean {
+  return (
+    message.type === "event" &&
+    (!event || (message as DebugProtocol.Event).event === event)
+  );
+}
+
+export class DebugSessionTracker
+  implements vscode.DebugAdapterTrackerFactory, vscode.Disposable
+{
+  private modules = new Map<vscode.DebugSession, DebugProtocol.Module[]>();
+  private modulesChanged = new vscode.EventEmitter<void>();
+  onDidChangeModules: vscode.Event<void> = this.modulesChanged.event;
+
+  dispose() {
+    this.modules.clear();
+    this.modulesChanged.dispose();
+  }
+
+  createDebugAdapterTracker(
+    session: vscode.DebugSession,
+  ): vscode.ProviderResult<vscode.DebugAdapterTracker> {
+    return {
+      onDidSendMessage: (message) => this.onDidSendMessage(session, message),
+      onExit: () => this.onExit(session),
+    };
+  }
+
+  debugSessionModules(session: vscode.DebugSession): DebugProtocol.Module[] {
+    return this.modules.get(session) ?? [];
+  }
+
+  private onExit(session: vscode.DebugSession) {
+    this.modules.delete(session);
+  }
+
+  private onDidSendMessage(
+    session: vscode.DebugSession,
+    message: DebugProtocol.ProtocolMessage,
+  ) {
+    if (isEvent(message, "module")) {
+      const { module, reason } = message.body;
+      const modules = this.modules.get(session) ?? [];
+      switch (reason) {
+        case "new":
+        case "changed": {
+          const index = modules.findIndex((m) => m.id === module.id);
+          if (index !== -1) {
+            modules[index] = module;
+          } else {
+            modules.push(module);
+          }
+          break;
+        }
+        case "removed": {
+          const index = modules.findIndex((m) => m.id === module.id);
+          if (index !== -1) {
+            modules.splice(index, 1);
+          }
+          break;
+        }
+        default:
+          console.error("unexpected module event reason");
+          break;
+      }
+      this.modules.set(session, modules);
+      this.modulesChanged.fire();
+    }
+  }
+}
diff --git a/lldb/tools/lldb-dap/src-ts/disposable-context.ts 
b/lldb/tools/lldb-dap/src-ts/disposable-context.ts
index 39d9f18d2d85f..42ece763d247f 100644
--- a/lldb/tools/lldb-dap/src-ts/disposable-context.ts
+++ b/lldb/tools/lldb-dap/src-ts/disposable-context.ts
@@ -21,7 +21,7 @@ export class DisposableContext implements vscode.Disposable {
    *
    * @param disposable The disposable to register.
    */
-  public pushSubscription(disposable: vscode.Disposable) {
-    this._disposables.push(disposable);
+  public pushSubscription(...disposable: vscode.Disposable[]) {
+    this._disposables.push(...disposable);
   }
 }
diff --git a/lldb/tools/lldb-dap/src-ts/extension.ts 
b/lldb/tools/lldb-dap/src-ts/extension.ts
index 0b014f953d5ba..1bca842480809 100644
--- a/lldb/tools/lldb-dap/src-ts/extension.ts
+++ b/lldb/tools/lldb-dap/src-ts/extension.ts
@@ -5,6 +5,8 @@ import { DisposableContext } from "./disposable-context";
 import { LaunchUriHandler } from "./uri-launch-handler";
 import { LLDBDapConfigurationProvider } from "./debug-configuration-provider";
 import { LLDBDapServer } from "./lldb-dap-server";
+import { DebugSessionTracker } from "./debug-session-tracker";
+import { ModuleDataProvider } from "./ui/modules-data-provider";
 
 /**
  * This class represents the extension and manages its life cycle. Other 
extensions
@@ -31,6 +33,22 @@ export class LLDBDapExtension extends DisposableContext {
       ),
     );
 
+    const sessionTracker = new DebugSessionTracker();
+
+    this.pushSubscription(
+      vscode.debug.registerDebugAdapterTrackerFactory(
+        "lldb-dap",
+        sessionTracker,
+      ),
+    );
+
+    this.pushSubscription(
+      vscode.window.registerTreeDataProvider(
+        "lldb-dap.modulesExplorer",
+        new ModuleDataProvider(sessionTracker),
+      ),
+    );
+
     this.pushSubscription(
       vscode.window.registerUriHandler(new LaunchUriHandler()),
     );
diff --git a/lldb/tools/lldb-dap/src-ts/ui/modules-data-provider.ts 
b/lldb/tools/lldb-dap/src-ts/ui/modules-data-provider.ts
new file mode 100644
index 0000000000000..d5cea513d7ef4
--- /dev/null
+++ b/lldb/tools/lldb-dap/src-ts/ui/modules-data-provider.ts
@@ -0,0 +1,58 @@
+import * as vscode from "vscode";
+import { DebugProtocol } from "@vscode/debugprotocol";
+import { DebugSessionTracker } from "../debug-session-tracker";
+
+export class ModuleDataProvider
+  implements vscode.TreeDataProvider<DebugProtocol.Module>
+{
+  private changeTreeData = new vscode.EventEmitter<void>();
+  readonly onDidChangeTreeData = this.changeTreeData.event;
+
+  constructor(private readonly tracker: DebugSessionTracker) {
+    tracker.onDidChangeModules(() => this.changeTreeData.fire());
+    vscode.debug.onDidChangeActiveDebugSession(() =>
+      this.changeTreeData.fire(),
+    );
+  }
+
+  getTreeItem(module: DebugProtocol.Module): vscode.TreeItem {
+    let treeItem = new vscode.TreeItem(/*label=*/ module.name);
+    if (module.path) {
+      treeItem.description = `${module.id} -- ${module.path}`;
+    } else {
+      treeItem.description = `${module.id}`;
+    }
+
+    const tooltip = new vscode.MarkdownString();
+    tooltip.appendMarkdown(`# Module '${module.name}'\n\n`);
+    tooltip.appendMarkdown(`- **id** : ${module.id}\n`);
+    if (module.addressRange) {
+      tooltip.appendMarkdown(`- **load address** : ${module.addressRange}\n`);
+    }
+    if (module.path) {
+      tooltip.appendMarkdown(`- **path** : ${module.path}\n`);
+    }
+    if (module.version) {
+      tooltip.appendMarkdown(`- **version** : ${module.version}\n`);
+    }
+    if (module.symbolStatus) {
+      tooltip.appendMarkdown(`- **symbol status** : ${module.symbolStatus}\n`);
+    }
+    if (module.symbolFilePath) {
+      tooltip.appendMarkdown(
+        `- **symbol file path** : ${module.symbolFilePath}\n`,
+      );
+    }
+
+    treeItem.tooltip = tooltip;
+    return treeItem;
+  }
+
+  getChildren(): DebugProtocol.Module[] {
+    if (!vscode.debug.activeDebugSession) {
+      return [];
+    }
+
+    return this.tracker.debugSessionModules(vscode.debug.activeDebugSession);
+  }
+}

>From da002083736f97692471d661cd31a64b37835205 Mon Sep 17 00:00:00 2001
From: John Harrison <harj...@google.com>
Date: Wed, 7 May 2025 16:16:37 -0700
Subject: [PATCH 2/2] Adjusting the modules tree view name and adding some
 documentation to help explain the code a bit.

---
 lldb/tools/lldb-dap/package.json              |  4 ++--
 .../lldb-dap/src-ts/debug-session-tracker.ts  | 24 ++++++++++++++++++-
 lldb/tools/lldb-dap/src-ts/extension.ts       | 24 +++++--------------
 .../src-ts/ui/modules-data-provider.ts        |  3 ++-
 4 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index a8dce7cab8a79..1149a33719ae5 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -768,8 +768,8 @@
     "views": {
       "debug": [
         {
-          "id": "lldb-dap.modulesExplorer",
-          "name": "LLDB Modules Explorer",
+          "id": "lldb-dap.modules",
+          "name": "Modules",
           "when": "inDebugMode && debugType == 'lldb-dap'",
           "icon": "$(symbol-module)"
         }
diff --git a/lldb/tools/lldb-dap/src-ts/debug-session-tracker.ts 
b/lldb/tools/lldb-dap/src-ts/debug-session-tracker.ts
index d756e9e743bb0..1ce190938d9c7 100644
--- a/lldb/tools/lldb-dap/src-ts/debug-session-tracker.ts
+++ b/lldb/tools/lldb-dap/src-ts/debug-session-tracker.ts
@@ -1,10 +1,13 @@
 import { DebugProtocol } from "@vscode/debugprotocol";
 import * as vscode from "vscode";
 
+/** A helper type for mapping event types to their corresponding data type. */
+// prettier-ignore
 interface EventMap {
-  module: DebugProtocol.ModuleEvent;
+  "module": DebugProtocol.ModuleEvent;
 }
 
+/** A type assertion to check if a ProtocolMessage is an event or if it is a 
specific event. */
 function isEvent(
   message: DebugProtocol.ProtocolMessage,
 ): message is DebugProtocol.Event;
@@ -22,11 +25,23 @@ function isEvent(
   );
 }
 
+/** Tracks lldb-dap sessions for data visualizers. */
 export class DebugSessionTracker
   implements vscode.DebugAdapterTrackerFactory, vscode.Disposable
 {
+  /**
+   * Tracks active modules for each debug sessions.
+   *
+   * The modules are kept in an array to maintain the load order of the 
modules.
+   */
   private modules = new Map<vscode.DebugSession, DebugProtocol.Module[]>();
   private modulesChanged = new vscode.EventEmitter<void>();
+
+  /**
+   * Fired when modules are changed for any active debug session.
+   *
+   * Use `debugSessionModules` to retieve the active modules for a given debug 
session.
+   */
   onDidChangeModules: vscode.Event<void> = this.modulesChanged.event;
 
   dispose() {
@@ -43,12 +58,19 @@ export class DebugSessionTracker
     };
   }
 
+  /**
+   * Retrieves the modules for the given debug session.
+   *
+   * Modules are returned in load order.
+   */
   debugSessionModules(session: vscode.DebugSession): DebugProtocol.Module[] {
     return this.modules.get(session) ?? [];
   }
 
+  /** Clear information from the active session. */
   private onExit(session: vscode.DebugSession) {
     this.modules.delete(session);
+    this.modulesChanged.fire();
   }
 
   private onDidSendMessage(
diff --git a/lldb/tools/lldb-dap/src-ts/extension.ts 
b/lldb/tools/lldb-dap/src-ts/extension.ts
index 1bca842480809..a5c0a09ae60cf 100644
--- a/lldb/tools/lldb-dap/src-ts/extension.ts
+++ b/lldb/tools/lldb-dap/src-ts/extension.ts
@@ -6,7 +6,7 @@ import { LaunchUriHandler } from "./uri-launch-handler";
 import { LLDBDapConfigurationProvider } from "./debug-configuration-provider";
 import { LLDBDapServer } from "./lldb-dap-server";
 import { DebugSessionTracker } from "./debug-session-tracker";
-import { ModuleDataProvider } from "./ui/modules-data-provider";
+import { ModulesDataProvider } from "./ui/modules-data-provider";
 
 /**
  * This class represents the extension and manages its life cycle. Other 
extensions
@@ -17,39 +17,27 @@ export class LLDBDapExtension extends DisposableContext {
     super();
 
     const lldbDapServer = new LLDBDapServer();
-    this.pushSubscription(lldbDapServer);
+    const sessionTracker = new DebugSessionTracker();
 
     this.pushSubscription(
+      lldbDapServer,
+      sessionTracker,
       vscode.debug.registerDebugConfigurationProvider(
         "lldb-dap",
         new LLDBDapConfigurationProvider(lldbDapServer),
       ),
-    );
-
-    this.pushSubscription(
       vscode.debug.registerDebugAdapterDescriptorFactory(
         "lldb-dap",
         new LLDBDapDescriptorFactory(),
       ),
-    );
-
-    const sessionTracker = new DebugSessionTracker();
-
-    this.pushSubscription(
       vscode.debug.registerDebugAdapterTrackerFactory(
         "lldb-dap",
         sessionTracker,
       ),
-    );
-
-    this.pushSubscription(
       vscode.window.registerTreeDataProvider(
-        "lldb-dap.modulesExplorer",
-        new ModuleDataProvider(sessionTracker),
+        "lldb-dap.modules",
+        new ModulesDataProvider(sessionTracker),
       ),
-    );
-
-    this.pushSubscription(
       vscode.window.registerUriHandler(new LaunchUriHandler()),
     );
   }
diff --git a/lldb/tools/lldb-dap/src-ts/ui/modules-data-provider.ts 
b/lldb/tools/lldb-dap/src-ts/ui/modules-data-provider.ts
index d5cea513d7ef4..5af3d52e9870c 100644
--- a/lldb/tools/lldb-dap/src-ts/ui/modules-data-provider.ts
+++ b/lldb/tools/lldb-dap/src-ts/ui/modules-data-provider.ts
@@ -2,7 +2,8 @@ import * as vscode from "vscode";
 import { DebugProtocol } from "@vscode/debugprotocol";
 import { DebugSessionTracker } from "../debug-session-tracker";
 
-export class ModuleDataProvider
+/** A tree data provider for listing loaded modules for the active debug 
session. */
+export class ModulesDataProvider
   implements vscode.TreeDataProvider<DebugProtocol.Module>
 {
   private changeTreeData = new vscode.EventEmitter<void>();

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

Reply via email to