-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[vscode-lldb] Restart server when the lldb-dap binary's modification time has changed #159481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} | ||
Comment on lines
+177
to
+187
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should use the builtin method for this: that will be more reliable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (The following is probably more for my learning.) I did a Google search and it said this:
It seems it's because the underlying -- FWIW, I have a local implementation using the The code is very simple:
The callback is never executed when I do It seems there is a bunch of reasons where -- What reliability issue did you have in mind about the "modification time" approach? I might have been naive and missed something important. Currently, it appears to me that checking the file modification time is better in terms of simplicity (only depend on the FS supporting modification time), debuggability (user can verify the modification time), and consistency (as long as the modification time changed, it should be detected). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting. I used What I believed so far is that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was wrong. What my extensions were using is https://www.npmjs.com/package/chokidar |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove these changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the good catch. I appreciate it.
These are unintentionally done during debug.