@@ -17,6 +17,7 @@ import { TargetPopulation } from 'vscode-tas-client';
1717import * as which from 'which' ;
1818import { logAndReturn } from '../Utility/Async/returns' ;
1919import * as util from '../common' ;
20+ import { getCrashCallStacksChannel } from '../logger' ;
2021import { PlatformInformation } from '../platform' ;
2122import * as telemetry from '../telemetry' ;
2223import { Client , DefaultClient , DoxygenCodeActionCommandArguments , openFileVersions } from './client' ;
@@ -38,6 +39,7 @@ export const configPrefix: string = "C/C++: ";
3839
3940let prevMacCrashFile : string ;
4041let prevCppCrashFile : string ;
42+ let prevCppCrashCallStackData : string = "" ;
4143export let clients : ClientCollection ;
4244let activeDocument : vscode . TextDocument | undefined ;
4345let ui : LanguageStatusUI ;
@@ -988,10 +990,12 @@ export function watchForCrashes(crashDirectory: string): void {
988990 if ( ! filename . startsWith ( "cpptools" ) ) {
989991 return ;
990992 }
993+ const crashDate : Date = new Date ( ) ;
994+
991995 // Wait 5 seconds to allow time for the crash log to finish being written.
992996 setTimeout ( ( ) => {
993997 fs . readFile ( path . resolve ( crashDirectory , filename ) , 'utf8' , ( err , data ) => {
994- void handleCrashFileRead ( crashDirectory , filename , err , data ) ;
998+ void handleCrashFileRead ( crashDirectory , filename , crashDate , err , data ) ;
995999 } ) ;
9961000 } , 5000 ) ;
9971001 } ) ;
@@ -1116,7 +1120,7 @@ function handleMacCrashFileRead(err: NodeJS.ErrnoException | undefined | null, d
11161120 logMacCrashTelemetry ( data ) ;
11171121}
11181122
1119- async function handleCrashFileRead ( crashDirectory : string , crashFile : string , err : NodeJS . ErrnoException | undefined | null , data : string ) : Promise < void > {
1123+ async function handleCrashFileRead ( crashDirectory : string , crashFile : string , crashDate : Date , err : NodeJS . ErrnoException | undefined | null , data : string ) : Promise < void > {
11201124 if ( err ) {
11211125 if ( err . code === "ENOENT" ) {
11221126 return ; // ignore known issue
@@ -1126,23 +1130,23 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, er
11261130
11271131 const lines : string [ ] = data . split ( "\n" ) ;
11281132 let addressData : string = ".\n." ;
1129- data = ( crashFile . startsWith ( "cpptools-srv" ) ? "cpptools-srv.txt" : crashFile ) + "\n" ;
1133+ const isCppToolsSrv : boolean = crashFile . startsWith ( "cpptools-srv" ) ;
1134+ const telemetryHeader : string = ( isCppToolsSrv ? "cpptools-srv.txt" : crashFile ) + "\n" ;
11301135 const filtPath : string | null = which . sync ( "c++filt" , { nothrow : true } ) ;
11311136 const isMac : boolean = process . platform === "darwin" ;
11321137 const startStr : string = isMac ? " _" : "<" ;
11331138 const offsetStr : string = isMac ? " + " : "+" ;
11341139 const endOffsetStr : string = isMac ? " " : " <" ;
11351140 const dotStr : string = "…" ;
1136- data += lines [ 0 ] ; // signal type
1141+ const signalType : string = lines [ 0 ] ;
1142+ let crashCallStack : string = "" ;
11371143 for ( let lineNum : number = 2 ; lineNum < lines . length - 3 ; ++ lineNum ) { // skip first/last lines
1138- if ( lineNum > 1 ) {
1139- data += "\n" ;
1140- addressData += "\n" ;
1141- }
1144+ crashCallStack += "\n" ;
1145+ addressData += "\n" ;
11421146 const line : string = lines [ lineNum ] ;
11431147 const startPos : number = line . indexOf ( startStr ) ;
11441148 if ( startPos === - 1 || line [ startPos + ( isMac ? 1 : 4 ) ] === "+" ) {
1145- data += dotStr ;
1149+ crashCallStack += dotStr ;
11461150 const startAddressPos : number = line . indexOf ( "0x" ) ;
11471151 const endAddressPos : number = line . indexOf ( endOffsetStr , startAddressPos + 2 ) ;
11481152 if ( startAddressPos === - 1 || endAddressPos === - 1 || startAddressPos >= endAddressPos ) {
@@ -1154,7 +1158,7 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, er
11541158 }
11551159 const offsetPos : number = line . indexOf ( offsetStr , startPos + startStr . length ) ;
11561160 if ( offsetPos === - 1 ) {
1157- data += "Missing offsetStr" ;
1161+ crashCallStack += "Missing offsetStr" ;
11581162 continue ; // unexpected
11591163 }
11601164 const startPos2 : number = startPos + 1 ;
@@ -1174,32 +1178,43 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, er
11741178 funcStr = funcStr . replace ( / , s t d : : a l l o c a t o r < s t d : : s t r i n g > / g, "" ) ;
11751179 }
11761180 }
1177- data += funcStr + offsetStr ;
1181+ crashCallStack += funcStr + offsetStr ;
11781182 const offsetPos2 : number = offsetPos + offsetStr . length ;
11791183 if ( isMac ) {
1180- data += line . substring ( offsetPos2 ) ;
1184+ crashCallStack += line . substring ( offsetPos2 ) ;
11811185 const startAddressPos : number = line . indexOf ( "0x" ) ;
11821186 if ( startAddressPos === - 1 || startAddressPos >= startPos ) {
11831187 // unexpected
1184- data += "<Missing 0x>" ;
1188+ crashCallStack += "<Missing 0x>" ;
11851189 continue ;
11861190 }
11871191 addressData += `${ line . substring ( startAddressPos , startPos ) } ` ;
11881192 } else {
11891193 const endPos : number = line . indexOf ( ">" , offsetPos2 ) ;
11901194 if ( endPos === - 1 ) {
1191- data += "<Missing > >" ;
1195+ crashCallStack += "<Missing > >" ;
11921196 continue ; // unexpected
11931197 }
1194- data += line . substring ( offsetPos2 , endPos ) ;
1198+ crashCallStack += line . substring ( offsetPos2 , endPos ) ;
11951199 }
11961200 }
11971201
1202+ if ( crashCallStack !== prevCppCrashCallStackData ) {
1203+ prevCppCrashCallStackData = crashCallStack ;
1204+
1205+ const settings : vscode . WorkspaceConfiguration = vscode . workspace . getConfiguration ( "C_Cpp" , null ) ;
1206+ if ( lines . length >= 6 && util . getNumericLoggingLevel ( settings . get < string > ( "loggingLevel" ) ) >= 1 ) {
1207+ const out : vscode . OutputChannel = getCrashCallStacksChannel ( ) ;
1208+ out . appendLine ( `\n${ isCppToolsSrv ? "cpptools-srv" : "cpptools" } \n${ crashDate . toLocaleString ( ) } \n${ signalType } ${ crashCallStack } ` ) ;
1209+ }
1210+ }
1211+
1212+ data = telemetryHeader + signalType + crashCallStack ;
1213+
11981214 if ( data . length > 8192 ) { // The API has an 8k limit.
11991215 data = data . substring ( 0 , 8191 ) + "…" ;
12001216 }
12011217
1202- console . log ( `Crash call stack:\n${ data } ` ) ;
12031218 logCppCrashTelemetry ( data , addressData ) ;
12041219
12051220 await util . deleteFile ( path . resolve ( crashDirectory , crashFile ) ) . catch ( logAndReturn . undefined ) ;
0 commit comments