Skip to content

Commit 9f04a5e

Browse files
authored
Add more state info to cpptools crash logging. (#13888)
* Add more state info to cpptools crash logging.
1 parent 6479acd commit 9f04a5e

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';
@@ -953,6 +953,8 @@ export class DefaultClient implements Client {
953953
public getShowConfigureIntelliSenseButton(): boolean { return this.showConfigureIntelliSenseButton; }
954954
public setShowConfigureIntelliSenseButton(show: boolean): void { this.showConfigureIntelliSenseButton = show; }
955955

956+
private lastInvokedLspMessage: string = ""; // e.g. cpptools/hover
957+
956958
/**
957959
* don't use this.rootFolder directly since it can be undefined
958960
*/
@@ -1688,7 +1690,6 @@ export class DefaultClient implements Client {
16881690
closed: () => {
16891691
languageClientCrashTimes.push(Date.now());
16901692
languageClientCrashedNeedsRestart = true;
1691-
telemetry.logLanguageServerEvent("languageClientCrash");
16921693
let restart: boolean = true;
16931694
if (languageClientCrashTimes.length < 5) {
16941695
void clients.recreateClients();
@@ -1702,6 +1703,26 @@ export class DefaultClient implements Client {
17021703
void clients.recreateClients();
17031704
}
17041705
}
1706+
1707+
// Wait 1 second to allow time for the file watcher to signal a crash call stack write has occurred.
1708+
setTimeout(() => {
1709+
telemetry.logLanguageServerEvent("languageClientCrash",
1710+
{
1711+
lastInvokedLspMessage: this.lastInvokedLspMessage
1712+
},
1713+
{
1714+
restarting: Number(restart),
1715+
writingCrashCallStack: Number(isWritingCrashCallStack),
1716+
initializingWorkspace: Number(this.model.isInitializingWorkspace.Value),
1717+
indexingWorkspace: Number(this.model.isIndexingWorkspace.Value),
1718+
parsingWorkspace: Number(this.model.isParsingWorkspace.Value),
1719+
parsingFiles: Number(this.model.isParsingFiles.Value),
1720+
updatingIntelliSense: Number(this.model.isUpdatingIntelliSense.Value),
1721+
runningCodeAnalysis: Number(this.model.isRunningCodeAnalysis.Value)
1722+
}
1723+
);
1724+
}, 1000);
1725+
17051726
const message: string = restart ? localize('server.crashed.restart', 'The language server crashed. Restarting...')
17061727
: localize('server.crashed2', 'The language server crashed 5 times in the last 3 minutes. It will not be restarted.');
17071728

@@ -2768,55 +2789,59 @@ export class DefaultClient implements Client {
27682789
const message: string = notificationBody.status;
27692790
util.setProgress(util.getProgressExecutableSuccess());
27702791
const testHook: TestHook = getTestHook();
2771-
if (message.endsWith("Idle")) {
2772-
const status: IntelliSenseStatus = { status: Status.Idle };
2773-
testHook.updateStatus(status);
2774-
} else if (message.endsWith("Parsing")) {
2775-
this.model.isParsingWorkspace.Value = true;
2776-
this.model.isInitializingWorkspace.Value = false;
2777-
this.model.isIndexingWorkspace.Value = false;
2778-
const status: IntelliSenseStatus = { status: Status.TagParsingBegun };
2779-
testHook.updateStatus(status);
2780-
} else if (message.endsWith("Initializing")) {
2781-
this.model.isInitializingWorkspace.Value = true;
2782-
this.model.isIndexingWorkspace.Value = false;
2783-
this.model.isParsingWorkspace.Value = false;
2784-
} else if (message.endsWith("Indexing")) {
2785-
this.model.isIndexingWorkspace.Value = true;
2786-
this.model.isInitializingWorkspace.Value = false;
2787-
this.model.isParsingWorkspace.Value = false;
2788-
} else if (message.endsWith("files")) {
2789-
this.model.isParsingFiles.Value = true;
2790-
} else if (message.endsWith("IntelliSense")) {
2791-
timeStamp = Date.now();
2792-
this.model.isUpdatingIntelliSense.Value = true;
2793-
const status: IntelliSenseStatus = { status: Status.IntelliSenseCompiling };
2794-
testHook.updateStatus(status);
2795-
} else if (message.endsWith("IntelliSense done")) {
2796-
getOutputChannelLogger().appendLineAtLevel(6, localize("update.intellisense.time", "Update IntelliSense time (sec): {0}", (Date.now() - timeStamp) / 1000));
2797-
this.model.isUpdatingIntelliSense.Value = false;
2798-
const status: IntelliSenseStatus = { status: Status.IntelliSenseReady };
2799-
testHook.updateStatus(status);
2800-
} else if (message.endsWith("Parsing done")) { // Tag Parser Ready
2801-
this.model.isParsingWorkspace.Value = false;
2802-
const status: IntelliSenseStatus = { status: Status.TagParsingDone };
2803-
testHook.updateStatus(status);
2804-
util.setProgress(util.getProgressParseRootSuccess());
2805-
} else if (message.endsWith("files done")) {
2806-
this.model.isParsingFiles.Value = false;
2807-
} else if (message.endsWith("Analysis")) {
2808-
this.model.isRunningCodeAnalysis.Value = true;
2809-
this.model.codeAnalysisTotal.Value = 1;
2810-
this.model.codeAnalysisProcessed.Value = 0;
2811-
} else if (message.endsWith("Analysis done")) {
2812-
this.model.isRunningCodeAnalysis.Value = false;
2813-
} else if (message.includes("Squiggles Finished - File name:")) {
2814-
const index: number = message.lastIndexOf(":");
2815-
const name: string = message.substring(index + 2);
2816-
const status: IntelliSenseStatus = { status: Status.IntelliSenseReady, filename: name };
2817-
testHook.updateStatus(status);
2818-
} else if (message.endsWith("No Squiggles")) {
2819-
util.setIntelliSenseProgress(util.getProgressIntelliSenseNoSquiggles());
2792+
if (message.startsWith("C_Cpp: ")) {
2793+
if (message.endsWith("Idle")) {
2794+
const status: IntelliSenseStatus = { status: Status.Idle };
2795+
testHook.updateStatus(status);
2796+
} else if (message.endsWith("Parsing")) {
2797+
this.model.isParsingWorkspace.Value = true;
2798+
this.model.isInitializingWorkspace.Value = false;
2799+
this.model.isIndexingWorkspace.Value = false;
2800+
const status: IntelliSenseStatus = { status: Status.TagParsingBegun };
2801+
testHook.updateStatus(status);
2802+
} else if (message.endsWith("Initializing")) {
2803+
this.model.isInitializingWorkspace.Value = true;
2804+
this.model.isIndexingWorkspace.Value = false;
2805+
this.model.isParsingWorkspace.Value = false;
2806+
} else if (message.endsWith("Indexing")) {
2807+
this.model.isIndexingWorkspace.Value = true;
2808+
this.model.isInitializingWorkspace.Value = false;
2809+
this.model.isParsingWorkspace.Value = false;
2810+
} else if (message.endsWith("files")) {
2811+
this.model.isParsingFiles.Value = true;
2812+
} else if (message.endsWith("IntelliSense")) {
2813+
timeStamp = Date.now();
2814+
this.model.isUpdatingIntelliSense.Value = true;
2815+
const status: IntelliSenseStatus = { status: Status.IntelliSenseCompiling };
2816+
testHook.updateStatus(status);
2817+
} else if (message.endsWith("IntelliSense done")) {
2818+
getOutputChannelLogger().appendLineAtLevel(6, localize("update.intellisense.time", "Update IntelliSense time (sec): {0}", (Date.now() - timeStamp) / 1000));
2819+
this.model.isUpdatingIntelliSense.Value = false;
2820+
const status: IntelliSenseStatus = { status: Status.IntelliSenseReady };
2821+
testHook.updateStatus(status);
2822+
} else if (message.endsWith("Parsing done")) { // Tag Parser Ready
2823+
this.model.isParsingWorkspace.Value = false;
2824+
const status: IntelliSenseStatus = { status: Status.TagParsingDone };
2825+
testHook.updateStatus(status);
2826+
util.setProgress(util.getProgressParseRootSuccess());
2827+
} else if (message.endsWith("files done")) {
2828+
this.model.isParsingFiles.Value = false;
2829+
} else if (message.endsWith("Analysis")) {
2830+
this.model.isRunningCodeAnalysis.Value = true;
2831+
this.model.codeAnalysisTotal.Value = 1;
2832+
this.model.codeAnalysisProcessed.Value = 0;
2833+
} else if (message.endsWith("Analysis done")) {
2834+
this.model.isRunningCodeAnalysis.Value = false;
2835+
} else if (message.includes("Squiggles Finished - File name:")) {
2836+
const index: number = message.lastIndexOf(":");
2837+
const name: string = message.substring(index + 2);
2838+
const status: IntelliSenseStatus = { status: Status.IntelliSenseReady, filename: name };
2839+
testHook.updateStatus(status);
2840+
} else if (message.endsWith("No Squiggles")) {
2841+
util.setIntelliSenseProgress(util.getProgressIntelliSenseNoSquiggles());
2842+
}
2843+
} else if (message.includes("/")) {
2844+
this.lastInvokedLspMessage = message;
28202845
}
28212846
}
28222847

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)