Skip to content

Commit f4f3d8c

Browse files
committed
Add more state info to cpptools crash logging. (#13888)
* Add more state info to cpptools crash logging.
1 parent 303b838 commit f4f3d8c

File tree

2 files changed

+79
-51
lines changed

2 files changed

+79
-51
lines changed

Extension/src/LanguageServer/client.ts

Lines changed: 76 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ import { CopilotCompletionContextFeatures, CopilotCompletionContextProvider } fr
5959
import { CustomConfigurationProvider1, getCustomConfigProviders, isSameProviderExtensionId } from './customProviders';
6060
import { DataBinding } from './dataBinding';
6161
import { cachedEditorConfigSettings, getEditorConfigSettings } from './editorConfig';
62-
import { CppSourceStr, clients, configPrefix, initializeIntervalTimer, updateLanguageConfigurations, usesCrashHandler, watchForCrashes } from './extension';
62+
import { CppSourceStr, clients, configPrefix, initializeIntervalTimer, isWritingCrashCallStack, updateLanguageConfigurations, usesCrashHandler, watchForCrashes } from './extension';
6363
import { LocalizeStringParams, getLocaleId, getLocalizedString } from './localization';
6464
import { PersistentFolderState, PersistentState, PersistentWorkspaceState } from './persistentState';
6565
import { RequestCancelled, ServerCancelled, createProtocolFilter } from './protocolFilter';
@@ -942,6 +942,8 @@ export class DefaultClient implements Client {
942942
public getShowConfigureIntelliSenseButton(): boolean { return this.showConfigureIntelliSenseButton; }
943943
public setShowConfigureIntelliSenseButton(show: boolean): void { this.showConfigureIntelliSenseButton = show; }
944944

945+
private lastInvokedLspMessage: string = ""; // e.g. cpptools/hover
946+
945947
/**
946948
* don't use this.rootFolder directly since it can be undefined
947949
*/
@@ -1677,7 +1679,6 @@ export class DefaultClient implements Client {
16771679
closed: () => {
16781680
languageClientCrashTimes.push(Date.now());
16791681
languageClientCrashedNeedsRestart = true;
1680-
telemetry.logLanguageServerEvent("languageClientCrash");
16811682
let restart: boolean = true;
16821683
if (languageClientCrashTimes.length < 5) {
16831684
void clients.recreateClients();
@@ -1691,6 +1692,26 @@ export class DefaultClient implements Client {
16911692
void clients.recreateClients();
16921693
}
16931694
}
1695+
1696+
// Wait 1 second to allow time for the file watcher to signal a crash call stack write has occurred.
1697+
setTimeout(() => {
1698+
telemetry.logLanguageServerEvent("languageClientCrash",
1699+
{
1700+
lastInvokedLspMessage: this.lastInvokedLspMessage
1701+
},
1702+
{
1703+
restarting: Number(restart),
1704+
writingCrashCallStack: Number(isWritingCrashCallStack),
1705+
initializingWorkspace: Number(this.model.isInitializingWorkspace.Value),
1706+
indexingWorkspace: Number(this.model.isIndexingWorkspace.Value),
1707+
parsingWorkspace: Number(this.model.isParsingWorkspace.Value),
1708+
parsingFiles: Number(this.model.isParsingFiles.Value),
1709+
updatingIntelliSense: Number(this.model.isUpdatingIntelliSense.Value),
1710+
runningCodeAnalysis: Number(this.model.isRunningCodeAnalysis.Value)
1711+
}
1712+
);
1713+
}, 1000);
1714+
16941715
const message: string = restart ? localize('server.crashed.restart', 'The language server crashed. Restarting...')
16951716
: localize('server.crashed2', 'The language server crashed 5 times in the last 3 minutes. It will not be restarted.');
16961717

@@ -2747,55 +2768,59 @@ export class DefaultClient implements Client {
27472768
const message: string = notificationBody.status;
27482769
util.setProgress(util.getProgressExecutableSuccess());
27492770
const testHook: TestHook = getTestHook();
2750-
if (message.endsWith("Idle")) {
2751-
const status: IntelliSenseStatus = { status: Status.Idle };
2752-
testHook.updateStatus(status);
2753-
} else if (message.endsWith("Parsing")) {
2754-
this.model.isParsingWorkspace.Value = true;
2755-
this.model.isInitializingWorkspace.Value = false;
2756-
this.model.isIndexingWorkspace.Value = false;
2757-
const status: IntelliSenseStatus = { status: Status.TagParsingBegun };
2758-
testHook.updateStatus(status);
2759-
} else if (message.endsWith("Initializing")) {
2760-
this.model.isInitializingWorkspace.Value = true;
2761-
this.model.isIndexingWorkspace.Value = false;
2762-
this.model.isParsingWorkspace.Value = false;
2763-
} else if (message.endsWith("Indexing")) {
2764-
this.model.isIndexingWorkspace.Value = true;
2765-
this.model.isInitializingWorkspace.Value = false;
2766-
this.model.isParsingWorkspace.Value = false;
2767-
} else if (message.endsWith("files")) {
2768-
this.model.isParsingFiles.Value = true;
2769-
} else if (message.endsWith("IntelliSense")) {
2770-
timeStamp = Date.now();
2771-
this.model.isUpdatingIntelliSense.Value = true;
2772-
const status: IntelliSenseStatus = { status: Status.IntelliSenseCompiling };
2773-
testHook.updateStatus(status);
2774-
} else if (message.endsWith("IntelliSense done")) {
2775-
getOutputChannelLogger().appendLineAtLevel(6, localize("update.intellisense.time", "Update IntelliSense time (sec): {0}", (Date.now() - timeStamp) / 1000));
2776-
this.model.isUpdatingIntelliSense.Value = false;
2777-
const status: IntelliSenseStatus = { status: Status.IntelliSenseReady };
2778-
testHook.updateStatus(status);
2779-
} else if (message.endsWith("Parsing done")) { // Tag Parser Ready
2780-
this.model.isParsingWorkspace.Value = false;
2781-
const status: IntelliSenseStatus = { status: Status.TagParsingDone };
2782-
testHook.updateStatus(status);
2783-
util.setProgress(util.getProgressParseRootSuccess());
2784-
} else if (message.endsWith("files done")) {
2785-
this.model.isParsingFiles.Value = false;
2786-
} else if (message.endsWith("Analysis")) {
2787-
this.model.isRunningCodeAnalysis.Value = true;
2788-
this.model.codeAnalysisTotal.Value = 1;
2789-
this.model.codeAnalysisProcessed.Value = 0;
2790-
} else if (message.endsWith("Analysis done")) {
2791-
this.model.isRunningCodeAnalysis.Value = false;
2792-
} else if (message.includes("Squiggles Finished - File name:")) {
2793-
const index: number = message.lastIndexOf(":");
2794-
const name: string = message.substring(index + 2);
2795-
const status: IntelliSenseStatus = { status: Status.IntelliSenseReady, filename: name };
2796-
testHook.updateStatus(status);
2797-
} else if (message.endsWith("No Squiggles")) {
2798-
util.setIntelliSenseProgress(util.getProgressIntelliSenseNoSquiggles());
2771+
if (message.startsWith("C_Cpp: ")) {
2772+
if (message.endsWith("Idle")) {
2773+
const status: IntelliSenseStatus = { status: Status.Idle };
2774+
testHook.updateStatus(status);
2775+
} else if (message.endsWith("Parsing")) {
2776+
this.model.isParsingWorkspace.Value = true;
2777+
this.model.isInitializingWorkspace.Value = false;
2778+
this.model.isIndexingWorkspace.Value = false;
2779+
const status: IntelliSenseStatus = { status: Status.TagParsingBegun };
2780+
testHook.updateStatus(status);
2781+
} else if (message.endsWith("Initializing")) {
2782+
this.model.isInitializingWorkspace.Value = true;
2783+
this.model.isIndexingWorkspace.Value = false;
2784+
this.model.isParsingWorkspace.Value = false;
2785+
} else if (message.endsWith("Indexing")) {
2786+
this.model.isIndexingWorkspace.Value = true;
2787+
this.model.isInitializingWorkspace.Value = false;
2788+
this.model.isParsingWorkspace.Value = false;
2789+
} else if (message.endsWith("files")) {
2790+
this.model.isParsingFiles.Value = true;
2791+
} else if (message.endsWith("IntelliSense")) {
2792+
timeStamp = Date.now();
2793+
this.model.isUpdatingIntelliSense.Value = true;
2794+
const status: IntelliSenseStatus = { status: Status.IntelliSenseCompiling };
2795+
testHook.updateStatus(status);
2796+
} else if (message.endsWith("IntelliSense done")) {
2797+
getOutputChannelLogger().appendLineAtLevel(6, localize("update.intellisense.time", "Update IntelliSense time (sec): {0}", (Date.now() - timeStamp) / 1000));
2798+
this.model.isUpdatingIntelliSense.Value = false;
2799+
const status: IntelliSenseStatus = { status: Status.IntelliSenseReady };
2800+
testHook.updateStatus(status);
2801+
} else if (message.endsWith("Parsing done")) { // Tag Parser Ready
2802+
this.model.isParsingWorkspace.Value = false;
2803+
const status: IntelliSenseStatus = { status: Status.TagParsingDone };
2804+
testHook.updateStatus(status);
2805+
util.setProgress(util.getProgressParseRootSuccess());
2806+
} else if (message.endsWith("files done")) {
2807+
this.model.isParsingFiles.Value = false;
2808+
} else if (message.endsWith("Analysis")) {
2809+
this.model.isRunningCodeAnalysis.Value = true;
2810+
this.model.codeAnalysisTotal.Value = 1;
2811+
this.model.codeAnalysisProcessed.Value = 0;
2812+
} else if (message.endsWith("Analysis done")) {
2813+
this.model.isRunningCodeAnalysis.Value = false;
2814+
} else if (message.includes("Squiggles Finished - File name:")) {
2815+
const index: number = message.lastIndexOf(":");
2816+
const name: string = message.substring(index + 2);
2817+
const status: IntelliSenseStatus = { status: Status.IntelliSenseReady, filename: name };
2818+
testHook.updateStatus(status);
2819+
} else if (message.endsWith("No Squiggles")) {
2820+
util.setIntelliSenseProgress(util.getProgressIntelliSenseNoSquiggles());
2821+
}
2822+
} else if (message.includes("/")) {
2823+
this.lastInvokedLspMessage = message;
27992824
}
28002825
}
28012826

Extension/src/LanguageServer/extension.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ let languageConfigurations: vscode.Disposable[] = [];
5555
let intervalTimer: NodeJS.Timeout;
5656
let codeActionProvider: vscode.Disposable;
5757
export const intelliSenseDisabledError: string = "Do not activate the extension when IntelliSense is disabled.";
58+
export let isWritingCrashCallStack: boolean = false;
5859

5960
type VcpkgDatabase = Record<string, string[]>; // Stored as <header file entry> -> [<port name>]
6061
let vcpkgDbPromise: Promise<VcpkgDatabase>;
@@ -1023,9 +1024,11 @@ export function watchForCrashes(crashDirectory: string): void {
10231024
return;
10241025
}
10251026
const crashDate: Date = new Date();
1027+
isWritingCrashCallStack = true;
10261028

10271029
// Wait 5 seconds to allow time for the crash log to finish being written.
10281030
setTimeout(() => {
1031+
isWritingCrashCallStack = false;
10291032
fs.readFile(path.resolve(crashDirectory, filename), 'utf8', (err, data) => {
10301033
void handleCrashFileRead(crashDirectory, filename, crashDate, err, data);
10311034
});

0 commit comments

Comments
 (0)