Skip to content

Commit

Permalink
src/goLanguageServer.ts: include sanitized trace to issue report
Browse files Browse the repository at this point in the history
Many automated gopls crash reports come with empty stack trace
and provides little information. This CL tries to extract
the stack trace from panic or the initialize error message.
The stack trace is from the gopls binary itself so
there is not much confidential except the package file paths.
Remove those file paths and leave only the file base name
parts. The package paths are included in the function name
parts, so we still can locate the corresponding files in the
gopls repository.

If we fail to sanitize, do not include any stack trace
and ask users to include it manually.

Also, includes the language server binary flag, which will
help with identifying crashes caused by incorrect gopls args.
B

Change-Id: I5fcab48b28b7adb0adf369af4227c29ca646b2a3
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/256878
Trust: Hyang-Ah Hana Kim <hyangah@gmail.com>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
  • Loading branch information
hyangah committed Sep 24, 2020
1 parent 9d97bb5 commit 9ebcc1f
Show file tree
Hide file tree
Showing 2 changed files with 402 additions and 5 deletions.
85 changes: 80 additions & 5 deletions src/goLanguageServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1045,21 +1045,31 @@ You will be asked to provide additional information and logs, so PLEASE READ THE
break;
}
const usersGoplsVersion = await getLocalGoplsVersion(latestConfig);
// TODO(hakim): If gopls version is too old, ask users to update it.
const settings = latestConfig.flags.join(' ');
const title = `gopls: automated issue report (${errKind})`;
const sanitizedLog = collectGoplsLog();
const goplsLog = (sanitizedLog) ?
`<pre>${sanitizedLog}</pre>` :
`
Please attach the stack trace from the crash.
A window with the error message should have popped up in the lower half of your screen.
Please copy the stack trace and error messages from that window and paste it in this issue.
<PASTE STACK TRACE HERE>
`;

const body = `
gopls version: ${usersGoplsVersion}
gopls flags: ${settings}
ATTENTION: PLEASE PROVIDE THE DETAILS REQUESTED BELOW.
Describe what you observed.
<ANSWER HERE>
Please attach the stack trace from the crash.
A window with the error message should have popped up in the lower half of your screen.
Please copy the stack trace from that window and paste it in this issue.
<PASTE STACK TRACE HERE>
${goplsLog}
OPTIONAL: If you would like to share more information, you can attach your complete gopls logs.
Expand Down Expand Up @@ -1106,3 +1116,68 @@ function minutesBetween(a: Date, b: Date): number {
function msBetween(a: Date, b: Date): number {
return Math.abs(a.getTime() - b.getTime());
}

function collectGoplsLog(): string {
serverOutputChannel.show();
// Find the logs in the output channel. There is no way to read
// an output channel directly, but we can find the open text
// document, since we just surfaced the output channel to the user.
// See https://github.com/microsoft/vscode/issues/65108.
let logs: string;
for (const doc of vscode.workspace.textDocuments) {
if (doc.languageId !== 'Log') {
continue;
}
if (doc.isDirty || doc.isClosed) {
continue;
}
// The document's name should look like 'extension-output-#X'.
if (doc.fileName.indexOf('extension-output-') === -1) {
continue;
}
logs = doc.getText();
break;
}
return sanitizeGoplsTrace(logs);
}

// capture only panic stack trace and the initialization error message.
// exported for testing.
export function sanitizeGoplsTrace(logs?: string): string {
if (!logs) {
return '';
}
const panicMsgBegin = logs.lastIndexOf('panic: ');
if (panicMsgBegin > -1) { // panic message was found.
const panicMsgEnd = logs.indexOf('Connection to server got closed.', panicMsgBegin);
if (panicMsgEnd > -1) {
const panicTrace = logs.substr(panicMsgBegin, panicMsgEnd - panicMsgBegin);
const filePattern = /(\S+\.go):\d+/;
const sanitized = panicTrace.split('\n').map(
(line: string) => {
// Even though this is a crash from gopls, the file path
// can contain user names and user's filesystem directory structure.
// We can still locate the corresponding file if the file base is
// available because the full package path is part of the function
// name. So, leave only the file base.
const m = line.match(filePattern);
if (!m) { return line; }
const filePath = m[1];
const fileBase = path.basename(filePath);
return line.replace(filePath, ' ' + fileBase);
}
).join('\n');

return sanitized;
}
}
const initFailMsgBegin = logs.lastIndexOf('Starting client failed');
if (initFailMsgBegin > -1) { // client start failed. Capture up to the 'Code:' line.
const initFailMsgEnd = logs.indexOf('Code: ', initFailMsgBegin);
if (initFailMsgEnd > -1) {
const lineEnd = logs.indexOf('\n', initFailMsgEnd);
return lineEnd > -1 ? logs.substr(initFailMsgBegin, lineEnd - initFailMsgBegin) : logs.substr(initFailMsgBegin);
}
}
return '';
}
Loading

0 comments on commit 9ebcc1f

Please sign in to comment.