@@ -1161,8 +1161,8 @@ function handleMacCrashFileRead(err: NodeJS.ErrnoException | undefined | null, d
11611161 logMacCrashTelemetry ( data ) ;
11621162}
11631163
1164+ const regex : RegExp = / ( k e y | t o k e n | s i g | s e c r e t | s i g n a t u r e | p a s s w o r d | p a s s w d | p w d | a n d r o i d : v a l u e ) [ ^ a - z A - Z 0 - 9 ] / i;
11641165function containsFilteredTelemetryData ( str : string ) : boolean {
1165- const regex : RegExp = / ( k e y | t o k e n | s i g | s e c r e t | s i g n a t u r e | p a s s w o r d | p a s s w d | p w d | a n d r o i d : v a l u e ) [ ^ a - z A - Z 0 - 9 ] / i;
11661166 return regex . test ( str ) ;
11671167}
11681168
@@ -1175,139 +1175,154 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, cr
11751175 }
11761176
11771177 const lines : string [ ] = data . split ( "\n" ) ;
1178- let addressData : string = ".\n. " ;
1178+ let addressData : string = ".\n" ;
11791179 const isCppToolsSrv : boolean = crashFile . startsWith ( "cpptools-srv" ) ;
11801180 const telemetryHeader : string = ( isCppToolsSrv ? "cpptools-srv.txt" : crashFile ) + "\n" ;
11811181 const filtPath : string | null = which . sync ( "c++filt" , { nothrow : true } ) ;
11821182 const isMac : boolean = process . platform === "darwin" ;
11831183 const startStr : string = isMac ? " _" : "<" ;
11841184 const offsetStr : string = isMac ? " + " : "+" ;
11851185 const endOffsetStr : string = isMac ? " " : " <" ;
1186- const dotStr : string = "\n… " ;
1186+ const dotStr : string = "…\n " ;
11871187 let signalType : string ;
11881188 let crashLog : string = "" ;
11891189 let crashStackStartLine : number = 0 ;
11901190 if ( lines [ 0 ] === "LOG" ) {
11911191 let crashLogLine : number = 1 ;
11921192 for ( ; crashLogLine < lines . length ; ++ crashLogLine ) {
1193- const pendingCrashLogLine = lines [ crashLogLine ] ;
1193+ let pendingCrashLogLine = lines [ crashLogLine ] ;
11941194 if ( pendingCrashLogLine === "ENDLOG" ) {
11951195 break ;
11961196 }
1197+ pendingCrashLogLine += "\n" ;
11971198 if ( containsFilteredTelemetryData ( pendingCrashLogLine ) ) {
11981199 crashLog += "?\n" ;
11991200 } else {
1200- crashLog += pendingCrashLogLine + "\n" ;
1201+ crashLog += pendingCrashLogLine ;
12011202 }
12021203 }
12031204 crashLog = crashLog . trimEnd ( ) ;
12041205 crashStackStartLine = ++ crashLogLine ;
12051206 }
12061207 if ( lines [ crashStackStartLine ] . startsWith ( "SIG" ) ) {
1207- signalType = lines [ crashStackStartLine ] ;
1208+ signalType = lines [ crashStackStartLine ] + "\n" ;
12081209 } else {
12091210 // The signal type may fail to be written.
12101211 signalType = "SIG-??\n" ; // Intentionally different from SIG-? from cpptools.
12111212 }
1213+ data = telemetryHeader + signalType ;
12121214 let crashCallStack : string = "" ;
12131215 let validFrameFound : boolean = false ;
12141216 for ( let lineNum : number = crashStackStartLine ; lineNum < lines . length - 3 ; ++ lineNum ) { // skip last lines
12151217 const line : string = lines [ lineNum ] ;
12161218 const startPos : number = line . indexOf ( startStr ) ;
1219+ let pendingCallStack : string = "" ;
12171220 if ( startPos === - 1 || line [ startPos + ( isMac ? 1 : 4 ) ] === "+" ) {
12181221 if ( ! validFrameFound ) {
12191222 continue ; // Skip extra … at the start.
12201223 }
1221- crashCallStack + = dotStr ;
1224+ pendingCallStack = dotStr ;
12221225 const startAddressPos : number = line . indexOf ( "0x" ) ;
12231226 const endAddressPos : number = line . indexOf ( endOffsetStr , startAddressPos + 2 ) ;
1224- addressData += "\n" ;
12251227 if ( startAddressPos === - 1 || endAddressPos === - 1 || startAddressPos >= endAddressPos ) {
1226- addressData += "Unexpected offset" ;
1228+ addressData += "Unexpected offset\n " ;
12271229 } else {
1228- addressData += line . substring ( startAddressPos , endAddressPos ) ;
1229- }
1230- continue ;
1231- }
1232- const offsetPos : number = line . indexOf ( offsetStr , startPos + startStr . length ) ;
1233- if ( offsetPos === - 1 ) {
1234- crashCallStack += "\nMissing offsetStr" ;
1235- addressData += "\n" ;
1236- continue ; // unexpected
1237- }
1238- const startPos2 : number = startPos + 1 ;
1239- let funcStr : string = line . substring ( startPos2 , offsetPos ) ;
1240- if ( filtPath && filtPath . length !== 0 ) {
1241- let ret : util . ProcessReturnType | undefined = await util . spawnChildProcess ( filtPath , [ "--no-strip-underscore" , funcStr ] , undefined , true ) . catch ( logAndReturn . undefined ) ;
1242- if ( ret ?. output === funcStr ) {
1243- ret = await util . spawnChildProcess ( filtPath , [ funcStr ] , undefined , true ) . catch ( logAndReturn . undefined ) ;
1244- }
1245- if ( ret !== undefined && ret . succeeded && ! ret . output . startsWith ( "Could not open input file" ) ) {
1246- funcStr = ret . output ;
1247- funcStr = funcStr . replace ( / s t d : : (?: _ _ 1 | _ _ c x x 1 1 ) / g, "std" ) ; // simplify std namespaces.
1248- funcStr = funcStr . replace ( / s t d : : b a s i c _ / g, "std::" ) ;
1249- funcStr = funcStr . replace ( / > / g, ">" ) ;
1250- funcStr = funcStr . replace ( / , s t d : : (?: a l l o c a t o r | c h a r _ t r a i t s ) < c h a r > / g, "" ) ;
1251- funcStr = funcStr . replace ( / < c h a r > / g, "" ) ;
1252- 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, "" ) ;
1253- }
1254- }
1255- if ( containsFilteredTelemetryData ( funcStr ) ) {
1256- funcStr = "?" ;
1257- } else if ( ! validFrameFound && ( funcStr . startsWith ( "crash_handler(" ) || funcStr . startsWith ( "_sigtramp" ) ) ) {
1258- continue ; // Skip these on early frames.
1259- }
1260- validFrameFound = true ;
1261- crashCallStack += "\n" ;
1262- addressData += "\n" ;
1263- crashCallStack += funcStr + offsetStr ;
1264- const offsetPos2 : number = offsetPos + offsetStr . length ;
1265- if ( isMac ) {
1266- const pendingOffset : string = line . substring ( offsetPos2 ) ;
1267- if ( containsFilteredTelemetryData ( pendingOffset ) ) {
1268- crashCallStack += "?" ;
1269- } else {
1270- crashCallStack += pendingOffset ;
1271- }
1272- const startAddressPos : number = line . indexOf ( "0x" ) ;
1273- if ( startAddressPos === - 1 || startAddressPos >= startPos ) {
1274- // unexpected
1275- crashCallStack += "<Missing 0x>" ;
1276- continue ;
1230+ let pendingAddressData : string = line . substring ( startAddressPos , endAddressPos ) + "\n" ;
1231+ if ( containsFilteredTelemetryData ( pendingAddressData ) ) {
1232+ pendingAddressData = "?\n" ;
1233+ }
1234+ addressData += pendingAddressData ;
12771235 }
1278- addressData += `${ line . substring ( startAddressPos , startPos ) } ` ;
12791236 } else {
1280- const endPos : number = line . indexOf ( ">" , offsetPos2 ) ;
1281- if ( endPos === - 1 ) {
1282- crashCallStack += "<Missing > >" ;
1283- continue ; // unexpected
1284- }
1285- const pendingOffset : string = line . substring ( offsetPos2 , endPos ) ;
1286- if ( containsFilteredTelemetryData ( pendingOffset ) ) {
1287- crashCallStack += "?" ;
1237+ const offsetPos : number = line . indexOf ( offsetStr , startPos + startStr . length ) ;
1238+ if ( offsetPos === - 1 ) {
1239+ pendingCallStack = "Missing offsetStr\n" ;
1240+ addressData += "\n" ;
12881241 } else {
1289- crashCallStack += pendingOffset ;
1242+ const startPos2 : number = startPos + 1 ;
1243+ let funcStr : string = line . substring ( startPos2 , offsetPos ) ;
1244+ let origFuncStr : string = "" ;
1245+ if ( filtPath && filtPath . length !== 0 ) {
1246+ let ret : util . ProcessReturnType | undefined = await util . spawnChildProcess ( filtPath , [ "--no-strip-underscore" , funcStr ] , undefined , true ) . catch ( logAndReturn . undefined ) ;
1247+ if ( ret ?. output === funcStr ) {
1248+ ret = await util . spawnChildProcess ( filtPath , [ funcStr ] , undefined , true ) . catch ( logAndReturn . undefined ) ;
1249+ }
1250+ if ( ret !== undefined && ret . succeeded && ! ret . output . startsWith ( "Could not open input file" ) ) {
1251+ origFuncStr = funcStr ;
1252+ funcStr = ret . output ;
1253+ funcStr = funcStr . replace ( / s t d : : (?: _ _ 1 | _ _ c x x 1 1 ) / g, "std" ) ; // simplify std namespaces.
1254+ funcStr = funcStr . replace ( / s t d : : b a s i c _ / g, "std::" ) ;
1255+ funcStr = funcStr . replace ( / > / g, ">" ) ;
1256+ funcStr = funcStr . replace ( / , s t d : : (?: a l l o c a t o r | c h a r _ t r a i t s ) < c h a r > / g, "" ) ;
1257+ funcStr = funcStr . replace ( / < c h a r > / g, "" ) ;
1258+ 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, "" ) ;
1259+ }
1260+ }
1261+ if ( ! validFrameFound && ( funcStr . startsWith ( "crash_handler(" ) || funcStr . startsWith ( "_sigtramp" ) ) ) {
1262+ continue ; // Skip these on early frames.
1263+ }
1264+ validFrameFound = true ;
1265+
1266+ let pendingOffset : string = offsetStr ;
1267+ const offsetPos2 : number = offsetPos + offsetStr . length ;
1268+ // Compute pendingOffset.
1269+ if ( isMac ) {
1270+ pendingOffset += line . substring ( offsetPos2 ) ;
1271+ const startAddressPos : number = line . indexOf ( "0x" ) ;
1272+ if ( startAddressPos === - 1 || startAddressPos >= startPos ) {
1273+ // unexpected
1274+ pendingOffset += "<Missing 0x>" ;
1275+ addressData += "\n" ;
1276+ } else {
1277+ let pendingAddressData : string = line . substring ( startAddressPos , startPos ) + "\n" ;
1278+ if ( containsFilteredTelemetryData ( pendingAddressData ) ) {
1279+ pendingAddressData = "?\n" ;
1280+ }
1281+ addressData += pendingAddressData ;
1282+ }
1283+ } else {
1284+ const endPos : number = line . indexOf ( ">" , offsetPos2 ) ;
1285+ if ( endPos === - 1 ) {
1286+ pendingOffset += "<Missing > >" ; // unexpected
1287+ } else {
1288+ pendingOffset += line . substring ( offsetPos2 , endPos ) ;
1289+ }
1290+ addressData += "\n" ;
1291+ // TODO: It seems like addressData should be obtained on Linux in case the function is filtered.
1292+ }
1293+ pendingOffset += "\n" ;
1294+ pendingCallStack = funcStr + pendingOffset ;
1295+ if ( containsFilteredTelemetryData ( pendingCallStack ) ) {
1296+ if ( origFuncStr . length > 0 && origFuncStr !== funcStr ) {
1297+ pendingCallStack = origFuncStr + pendingOffset ;
1298+ if ( containsFilteredTelemetryData ( pendingCallStack ) ) {
1299+ pendingCallStack = "?\n" ;
1300+ }
1301+ } else {
1302+ pendingCallStack = "?\n" ;
1303+ }
1304+ }
12901305 }
12911306 }
1307+ if ( data . length + crashCallStack . length + pendingCallStack . length > 8191 ) { // The API has an 8k limit.
1308+ crashCallStack += "…" ;
1309+ break ;
1310+ }
1311+ crashCallStack += pendingCallStack ;
12921312 }
12931313
1314+ crashCallStack = crashCallStack . trimEnd ( ) ;
1315+ addressData = addressData . trimEnd ( ) ;
1316+
12941317 if ( crashCallStack !== prevCppCrashCallStackData ) {
12951318 prevCppCrashCallStackData = crashCallStack ;
12961319
12971320 if ( lines . length >= 6 && util . getLoggingLevel ( ) >= 1 ) {
1298- getCrashCallStacksChannel ( ) . appendLine ( `\n${ isCppToolsSrv ? "cpptools-srv" : "cpptools" } \n${ crashDate . toLocaleString ( ) } \n${ signalType } ${ crashCallStack } \n\n${ crashLog } ` ) ;
1321+ getCrashCallStacksChannel ( ) . appendLine ( `\n${ isCppToolsSrv ? "cpptools-srv" : "cpptools" } \n${ crashDate . toLocaleString ( ) } \n${ signalType } ${ crashCallStack } ${ crashLog . length > 0 ? " \n\n" + crashLog : "" } ` ) ;
12991322 }
13001323 }
13011324
1302- data = telemetryHeader + signalType + crashCallStack ;
1303-
1304- if ( data . length > 8192 ) { // The API has an 8k limit.
1305- data = data . substring ( 0 , 8191 ) + "…" ;
1306- }
1307-
1308- if ( containsFilteredTelemetryData ( addressData ) ) {
1309- addressData = "?" ;
1310- }
1325+ data += crashCallStack ;
13111326
13121327 logCppCrashTelemetry ( data , addressData , crashLog ) ;
13131328
0 commit comments