llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Roy Shi (royitaqi) <details> <summary>Changes</summary> This helps lldb-dap (the binary) development. For example, after rebuilding the lldb-dap binary, one probably wants to restart the server so that it will use the newly built binary instead of a stale one. With this patch, the modification time will be appended to the internal "spawn info" variable, which is displayed when prompting the user about restarting the server. See screenshot below. <img width="520" height="372" alt="screenshot" src="https://github.com/user-attachments/assets/79da55c8-28d3-4f17-b228-3ee22733a3a0" /> --- Full diff: https://github.com/llvm/llvm-project/pull/159481.diff 4 Files Affected: - (modified) lldb/tools/lldb-dap/.vscode/launch.json (+5-5) - (modified) lldb/tools/lldb-dap/package-lock.json (+66) - (modified) lldb/tools/lldb-dap/package.json (+4) - (modified) lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts (+22-9) ``````````diff diff --git a/lldb/tools/lldb-dap/.vscode/launch.json b/lldb/tools/lldb-dap/.vscode/launch.json index 8241a5aca0354..524fc2dd5ce7b 100644 --- a/lldb/tools/lldb-dap/.vscode/launch.json +++ b/lldb/tools/lldb-dap/.vscode/launch.json @@ -14,11 +14,11 @@ ], "outFiles": [ "${workspaceFolder}/out/**/*.js" - ], - "preLaunchTask": { - "type": "npm", - "script": "watch" - } + ] + // "preLaunchTask": { + // "type": "npm", + // "script": "watch" + // } } ] } diff --git a/lldb/tools/lldb-dap/package-lock.json b/lldb/tools/lldb-dap/package-lock.json index 26db1ce6df2fd..92143f7f37268 100644 --- a/lldb/tools/lldb-dap/package-lock.json +++ b/lldb/tools/lldb-dap/package-lock.json @@ -8,7 +8,11 @@ "name": "lldb-dap", "version": "0.2.16", "license": "Apache 2.0 License with LLVM exceptions", + "dependencies": { + "fs-extra": "^11.3.2" + }, "devDependencies": { + "@types/fs-extra": "^11.0.4", "@types/node": "^18.19.41", "@types/tabulator-tables": "^6.2.10", "@types/vscode": "1.75.0", @@ -835,6 +839,27 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@types/fs-extra": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", + "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/jsonfile": "*", + "@types/node": "*" + } + }, + "node_modules/@types/jsonfile": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { "version": "18.19.75", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.75.tgz", @@ -1748,6 +1773,20 @@ "dev": true, "optional": true }, + "node_modules/fs-extra": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -1877,6 +1916,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -2094,6 +2139,18 @@ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "dev": true }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/jsonwebtoken": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", @@ -3182,6 +3239,15 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/url-join": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json index 6566ba3bdee13..3633e292a6264 100644 --- a/lldb/tools/lldb-dap/package.json +++ b/lldb/tools/lldb-dap/package.json @@ -27,7 +27,11 @@ "categories": [ "Debuggers" ], + "dependencies": { + "fs-extra": "^11.0.4" + }, "devDependencies": { + "@types/fs-extra": "^11.0.4", "@types/node": "^18.19.41", "@types/tabulator-tables": "^6.2.10", "@types/vscode": "1.75.0", diff --git a/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts b/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts index 774be50053a17..59dd8a7a6b250 100644 --- a/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts +++ b/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts @@ -1,3 +1,4 @@ +import * as fs from 'fs-extra'; import * as child_process from "node:child_process"; import { isDeepStrictEqual } from "util"; import * as vscode from "vscode"; @@ -54,7 +55,7 @@ export class LLDBDapServer implements vscode.Disposable { return this.serverInfo; } - this.serverInfo = new Promise((resolve, reject) => { + this.serverInfo = new Promise(async (resolve, reject) => { const process = child_process.spawn(dapPath, dapArgs, options); process.on("error", (error) => { reject(error); @@ -82,7 +83,7 @@ export class LLDBDapServer implements vscode.Disposable { } }); this.serverProcess = process; - this.serverSpawnInfo = this.getSpawnInfo(dapPath, dapArgs, options?.env); + this.serverSpawnInfo = await this.getSpawnInfo(dapPath, dapArgs, options?.env); }); return this.serverInfo; } @@ -104,13 +105,13 @@ export class LLDBDapServer implements vscode.Disposable { return true; } - const newSpawnInfo = this.getSpawnInfo(dapPath, args, env); + const newSpawnInfo = await this.getSpawnInfo(dapPath, args, env); if (isDeepStrictEqual(this.serverSpawnInfo, newSpawnInfo)) { return true; } const userInput = await vscode.window.showInformationMessage( - "The arguments to lldb-dap have changed. Would you like to restart the server?", + "The lldb-dap binary and/or the arguments to it have changed. Would you like to restart the server?", { modal: true, detail: `An existing lldb-dap server (${this.serverProcess.pid}) is running with different arguments. @@ -131,8 +132,7 @@ Restarting the server will interrupt any existing debug sessions and start a new switch (userInput) { case "Restart": this.serverProcess.kill(); - this.serverProcess = undefined; - this.serverInfo = undefined; + this.cleanUp(this.serverProcess); return true; case "Use Existing": return true; @@ -149,27 +149,40 @@ Restarting the server will interrupt any existing debug sessions and start a new this.cleanUp(this.serverProcess); } - cleanUp(process: child_process.ChildProcessWithoutNullStreams) { + private cleanUp(process: child_process.ChildProcessWithoutNullStreams) { // If the following don't equal, then the fields have already been updated // (either a new process has started, or the fields were already cleaned // up), and so the cleanup should be skipped. if (this.serverProcess === process) { this.serverProcess = undefined; this.serverInfo = undefined; + this.serverSpawnInfo = undefined; } } - getSpawnInfo( + private async getSpawnInfo( path: string, args: string[], env: NodeJS.ProcessEnv | { [key: string]: string } | undefined, - ): string[] { + ): Promise<string[]> { return [ path, ...args, ...Object.entries(env ?? {}).map( (entry) => String(entry[0]) + "=" + String(entry[1]), ), + `(${await this.getFileModifiedTimestamp(path)})`, ]; } + + private async getFileModifiedTimestamp(file: string): Promise<string | null> { + try { + if (!(await fs.pathExists(file))) { + return null; + } + return (await fs.promises.stat(file)).mtime.toLocaleString(); + } catch (error) { + return null; + } + } } `````````` </details> https://github.com/llvm/llvm-project/pull/159481 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits