diff --git a/package.json b/package.json index 4cc080f0e..01569af5f 100644 --- a/package.json +++ b/package.json @@ -1169,6 +1169,12 @@ "default": null, "description": "%configuration.dotnet.server.extensionPaths%" }, + "dotnet.server.crashDumpPath": { + "scope": "machine-overridable", + "type": "string", + "default": null, + "description": "%configuration.dotnet.server.crashDumpPath%" + }, "dotnet.projects.binaryLogPath": { "scope": "machine-overridable", "type": "string", diff --git a/package.nls.json b/package.nls.json index ea482d2b3..ea94d2aef 100644 --- a/package.nls.json +++ b/package.nls.json @@ -6,6 +6,7 @@ "configuration.dotnet.server.waitForDebugger": "Passes the --debug flag when launching the server to allow a debugger to be attached. (Previously `omnisharp.waitForDebugger`)", "configuration.dotnet.server.trace": "Sets the logging level for the language server", "configuration.dotnet.server.extensionPaths": "Override for path to language server --extension arguments", + "configuration.dotnet.server.crashDumpPath": "Sets a folder path where crash dumps are written to if the language server crashes. Must be writeable by the user.", "configuration.dotnet.preferCSharpExtension": "Forces projects to load with the C# extension only. This can be useful when using legacy project types that are not supported by C# Dev Kit. (Requires window reload)", "configuration.dotnet.implementType.insertionBehavior": "The insertion location of properties, events, and methods When implement interface or abstract class.", "configuration.dotnet.implementType.insertionBehavior.withOtherMembersOfTheSameKind": "Place them with other members of the same kind.", diff --git a/src/lsptoolshost/roslynLanguageServer.ts b/src/lsptoolshost/roslynLanguageServer.ts index c676dc921..fe3decc90 100644 --- a/src/lsptoolshost/roslynLanguageServer.ts +++ b/src/lsptoolshost/roslynLanguageServer.ts @@ -452,6 +452,17 @@ export class RoslynLanguageServer { // Save user's DOTNET_ROOT env-var value so server can recover the user setting when needed env.DOTNET_ROOT_USER = process.env.DOTNET_ROOT ?? 'EMPTY'; + if (languageServerOptions.crashDumpPath) { + // Enable dump collection + env.DOTNET_DbgEnableMiniDump = '1'; + // Collect heap dump + env.DOTNET_DbgMiniDumpType = '2'; + // Collect crashreport.json with additional thread and stack frame information. + env.DOTNET_EnableCrashReport = '1'; + // The dump file name format is ..dmp + env.DOTNET_DbgMiniDumpName = path.join(languageServerOptions.crashDumpPath, '%e.%p.dmp'); + } + let args: string[] = []; if (commonOptions.waitForDebugger) { diff --git a/src/shared/options.ts b/src/shared/options.ts index 0e6ef63c9..cb54eb800 100644 --- a/src/shared/options.ts +++ b/src/shared/options.ts @@ -74,6 +74,7 @@ export interface LanguageServerOptions { readonly extensionsPaths: string[] | null; readonly preferCSharpExtension: boolean; readonly startTimeout: number; + readonly crashDumpPath: string | undefined; } export interface RazorOptions { @@ -385,6 +386,9 @@ class LanguageServerOptionsImpl implements LanguageServerOptions { public get startTimeout() { return readOption('dotnet.server.startTimeout', 30000); } + public get crashDumpPath() { + return readOption('dotnet.server.crashDumpPath', undefined); + } } class RazorOptionsImpl implements RazorOptions {