@@ -1161,8 +1161,8 @@ function handleMacCrashFileRead(err: NodeJS.ErrnoException | undefined | null, d
1161
1161
logMacCrashTelemetry ( data ) ;
1162
1162
}
1163
1163
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;
1164
1165
function 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;
1166
1166
return regex . test ( str ) ;
1167
1167
}
1168
1168
@@ -1175,139 +1175,154 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, cr
1175
1175
}
1176
1176
1177
1177
const lines : string [ ] = data . split ( "\n" ) ;
1178
- let addressData : string = ".\n. " ;
1178
+ let addressData : string = ".\n" ;
1179
1179
const isCppToolsSrv : boolean = crashFile . startsWith ( "cpptools-srv" ) ;
1180
1180
const telemetryHeader : string = ( isCppToolsSrv ? "cpptools-srv.txt" : crashFile ) + "\n" ;
1181
1181
const filtPath : string | null = which . sync ( "c++filt" , { nothrow : true } ) ;
1182
1182
const isMac : boolean = process . platform === "darwin" ;
1183
1183
const startStr : string = isMac ? " _" : "<" ;
1184
1184
const offsetStr : string = isMac ? " + " : "+" ;
1185
1185
const endOffsetStr : string = isMac ? " " : " <" ;
1186
- const dotStr : string = "\n… " ;
1186
+ const dotStr : string = "…\n " ;
1187
1187
let signalType : string ;
1188
1188
let crashLog : string = "" ;
1189
1189
let crashStackStartLine : number = 0 ;
1190
1190
if ( lines [ 0 ] === "LOG" ) {
1191
1191
let crashLogLine : number = 1 ;
1192
1192
for ( ; crashLogLine < lines . length ; ++ crashLogLine ) {
1193
- const pendingCrashLogLine = lines [ crashLogLine ] ;
1193
+ let pendingCrashLogLine = lines [ crashLogLine ] ;
1194
1194
if ( pendingCrashLogLine === "ENDLOG" ) {
1195
1195
break ;
1196
1196
}
1197
+ pendingCrashLogLine += "\n" ;
1197
1198
if ( containsFilteredTelemetryData ( pendingCrashLogLine ) ) {
1198
1199
crashLog += "?\n" ;
1199
1200
} else {
1200
- crashLog += pendingCrashLogLine + "\n" ;
1201
+ crashLog += pendingCrashLogLine ;
1201
1202
}
1202
1203
}
1203
1204
crashLog = crashLog . trimEnd ( ) ;
1204
1205
crashStackStartLine = ++ crashLogLine ;
1205
1206
}
1206
1207
if ( lines [ crashStackStartLine ] . startsWith ( "SIG" ) ) {
1207
- signalType = lines [ crashStackStartLine ] ;
1208
+ signalType = lines [ crashStackStartLine ] + "\n" ;
1208
1209
} else {
1209
1210
// The signal type may fail to be written.
1210
1211
signalType = "SIG-??\n" ; // Intentionally different from SIG-? from cpptools.
1211
1212
}
1213
+ data = telemetryHeader + signalType ;
1212
1214
let crashCallStack : string = "" ;
1213
1215
let validFrameFound : boolean = false ;
1214
1216
for ( let lineNum : number = crashStackStartLine ; lineNum < lines . length - 3 ; ++ lineNum ) { // skip last lines
1215
1217
const line : string = lines [ lineNum ] ;
1216
1218
const startPos : number = line . indexOf ( startStr ) ;
1219
+ let pendingCallStack : string = "" ;
1217
1220
if ( startPos === - 1 || line [ startPos + ( isMac ? 1 : 4 ) ] === "+" ) {
1218
1221
if ( ! validFrameFound ) {
1219
1222
continue ; // Skip extra … at the start.
1220
1223
}
1221
- crashCallStack + = dotStr ;
1224
+ pendingCallStack = dotStr ;
1222
1225
const startAddressPos : number = line . indexOf ( "0x" ) ;
1223
1226
const endAddressPos : number = line . indexOf ( endOffsetStr , startAddressPos + 2 ) ;
1224
- addressData += "\n" ;
1225
1227
if ( startAddressPos === - 1 || endAddressPos === - 1 || startAddressPos >= endAddressPos ) {
1226
- addressData += "Unexpected offset" ;
1228
+ addressData += "Unexpected offset\n " ;
1227
1229
} 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 ;
1277
1235
}
1278
- addressData += `${ line . substring ( startAddressPos , startPos ) } ` ;
1279
1236
} 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" ;
1288
1241
} 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
+ }
1290
1305
}
1291
1306
}
1307
+ if ( data . length + crashCallStack . length + pendingCallStack . length > 8191 ) { // The API has an 8k limit.
1308
+ crashCallStack += "…" ;
1309
+ break ;
1310
+ }
1311
+ crashCallStack += pendingCallStack ;
1292
1312
}
1293
1313
1314
+ crashCallStack = crashCallStack . trimEnd ( ) ;
1315
+ addressData = addressData . trimEnd ( ) ;
1316
+
1294
1317
if ( crashCallStack !== prevCppCrashCallStackData ) {
1295
1318
prevCppCrashCallStackData = crashCallStack ;
1296
1319
1297
1320
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 : "" } ` ) ;
1299
1322
}
1300
1323
}
1301
1324
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 ;
1311
1326
1312
1327
logCppCrashTelemetry ( data , addressData , crashLog ) ;
1313
1328
0 commit comments