1+ import * as fs from 'fs-extra' ;
12import * as child_process from "node:child_process" ;
23import { isDeepStrictEqual } from "util" ;
34import * as vscode from "vscode" ;
@@ -54,7 +55,7 @@ export class LLDBDapServer implements vscode.Disposable {
5455 return this . serverInfo ;
5556 }
5657
57- this . serverInfo = new Promise ( ( resolve , reject ) => {
58+ this . serverInfo = new Promise ( async ( resolve , reject ) => {
5859 const process = child_process . spawn ( dapPath , dapArgs , options ) ;
5960 process . on ( "error" , ( error ) => {
6061 reject ( error ) ;
@@ -82,7 +83,7 @@ export class LLDBDapServer implements vscode.Disposable {
8283 }
8384 } ) ;
8485 this . serverProcess = process ;
85- this . serverSpawnInfo = this . getSpawnInfo ( dapPath , dapArgs , options ?. env ) ;
86+ this . serverSpawnInfo = await this . getSpawnInfo ( dapPath , dapArgs , options ?. env ) ;
8687 } ) ;
8788 return this . serverInfo ;
8889 }
@@ -104,13 +105,13 @@ export class LLDBDapServer implements vscode.Disposable {
104105 return true ;
105106 }
106107
107- const newSpawnInfo = this . getSpawnInfo ( dapPath , args , env ) ;
108+ const newSpawnInfo = await this . getSpawnInfo ( dapPath , args , env ) ;
108109 if ( isDeepStrictEqual ( this . serverSpawnInfo , newSpawnInfo ) ) {
109110 return true ;
110111 }
111112
112113 const userInput = await vscode . window . showInformationMessage (
113- "The arguments to lldb-dap have changed. Would you like to restart the server?" ,
114+ "The lldb-dap binary and/or the arguments to it have changed. Would you like to restart the server?" ,
114115 {
115116 modal : true ,
116117 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
131132 switch ( userInput ) {
132133 case "Restart" :
133134 this . serverProcess . kill ( ) ;
134- this . serverProcess = undefined ;
135- this . serverInfo = undefined ;
135+ this . cleanUp ( this . serverProcess ) ;
136136 return true ;
137137 case "Use Existing" :
138138 return true ;
@@ -149,27 +149,40 @@ Restarting the server will interrupt any existing debug sessions and start a new
149149 this . cleanUp ( this . serverProcess ) ;
150150 }
151151
152- cleanUp ( process : child_process . ChildProcessWithoutNullStreams ) {
152+ private cleanUp ( process : child_process . ChildProcessWithoutNullStreams ) {
153153 // If the following don't equal, then the fields have already been updated
154154 // (either a new process has started, or the fields were already cleaned
155155 // up), and so the cleanup should be skipped.
156156 if ( this . serverProcess === process ) {
157157 this . serverProcess = undefined ;
158158 this . serverInfo = undefined ;
159+ this . serverSpawnInfo = undefined ;
159160 }
160161 }
161162
162- getSpawnInfo (
163+ private async getSpawnInfo (
163164 path : string ,
164165 args : string [ ] ,
165166 env : NodeJS . ProcessEnv | { [ key : string ] : string } | undefined ,
166- ) : string [ ] {
167+ ) : Promise < string [ ] > {
167168 return [
168169 path ,
169170 ...args ,
170171 ...Object . entries ( env ?? { } ) . map (
171172 ( entry ) => String ( entry [ 0 ] ) + "=" + String ( entry [ 1 ] ) ,
172173 ) ,
174+ `(${ await this . getFileModifiedTimestamp ( path ) } )` ,
173175 ] ;
174176 }
177+
178+ private async getFileModifiedTimestamp ( file : string ) : Promise < string | null > {
179+ try {
180+ if ( ! ( await fs . pathExists ( file ) ) ) {
181+ return null ;
182+ }
183+ return ( await fs . promises . stat ( file ) ) . mtime . toLocaleString ( ) ;
184+ } catch ( error ) {
185+ return null ;
186+ }
187+ }
175188}
0 commit comments