use of com.microsoft.appcenter.crashes.model.NativeException in project mobile-center-sdk-android by Microsoft.
the class Crashes method initialize.
private void initialize() {
boolean enabled = isInstanceEnabled();
mInitializeTimestamp = enabled ? System.currentTimeMillis() : -1;
if (!enabled) {
if (mUncaughtExceptionHandler != null) {
mUncaughtExceptionHandler.unregister();
mUncaughtExceptionHandler = null;
}
} else {
/* Register Java crash handler. */
mUncaughtExceptionHandler = new UncaughtExceptionHandler();
mUncaughtExceptionHandler.register();
/* Convert minidump files to App Center crash files. */
for (File logFile : ErrorLogHelper.getNewMinidumpFiles()) {
/* Create missing files from the native crash that we detected. */
AppCenterLog.debug(LOG_TAG, "Process pending minidump file: " + logFile);
long minidumpDate = logFile.lastModified();
File dest = new File(ErrorLogHelper.getPendingMinidumpDirectory(), logFile.getName());
NativeException nativeException = new NativeException();
Exception modelException = new Exception();
modelException.setType("minidump");
modelException.setWrapperSdkName(Constants.WRAPPER_SDK_NAME_NDK);
modelException.setStackTrace(dest.getPath());
ManagedErrorLog errorLog = new ManagedErrorLog();
errorLog.setException(modelException);
errorLog.setTimestamp(new Date(minidumpDate));
errorLog.setFatal(true);
errorLog.setId(UUID.randomUUID());
/* Lookup app launch timestamp in session history. */
SessionContext.SessionInfo session = SessionContext.getInstance().getSessionAt(minidumpDate);
if (session != null && session.getAppLaunchTimestamp() <= minidumpDate) {
errorLog.setAppLaunchTimestamp(new Date(session.getAppLaunchTimestamp()));
} else {
/*
* Fall back to log date if app launch timestamp information lost
* or in the future compared to crash time.
* This also covers the case where app launches then crashes within 1s:
* app launch timestamp would have ms accuracy while minidump file is without
* ms, in that case we also falls back to log timestamp
* (this would be same result as truncating ms).
*/
errorLog.setAppLaunchTimestamp(errorLog.getTimestamp());
}
/*
* TODO The following properties are placeholders because fields are required.
* They should be removed from schema as not used by server.
*/
errorLog.setProcessId(0);
errorLog.setProcessName("");
/*
* TODO device properties are read after restart contrary to Java crashes.
* We should have a device property history like we did for session to fix that issue.
* The main issue with the current code is that app version can change between crash and reporting.
*/
try {
errorLog.setDevice(DeviceInfoHelper.getDeviceInfo(mContext));
errorLog.getDevice().setWrapperSdkName(Constants.WRAPPER_SDK_NAME_NDK);
saveErrorLogFiles(nativeException, errorLog);
if (!logFile.renameTo(dest)) {
throw new IOException("Failed to move file");
}
} catch (java.lang.Exception e) {
// noinspection ResultOfMethodCallIgnored
logFile.delete();
removeAllStoredErrorLogFiles(errorLog.getId());
AppCenterLog.error(LOG_TAG, "Failed to process new minidump file: " + logFile, e);
}
}
/* Check last session crash. */
File logFile = ErrorLogHelper.getLastErrorLogFile();
if (logFile != null) {
AppCenterLog.debug(LOG_TAG, "Processing crash report for the last session.");
String logFileContents = StorageHelper.InternalStorage.read(logFile);
if (logFileContents == null) {
AppCenterLog.error(LOG_TAG, "Error reading last session error log.");
} else {
try {
ManagedErrorLog log = (ManagedErrorLog) mLogSerializer.deserializeLog(logFileContents);
mLastSessionErrorReport = buildErrorReport(log);
AppCenterLog.debug(LOG_TAG, "Processed crash report for the last session.");
} catch (JSONException e) {
AppCenterLog.error(LOG_TAG, "Error parsing last session error log.", e);
}
}
}
}
}
use of com.microsoft.appcenter.crashes.model.NativeException in project mobile-center-sdk-android by Microsoft.
the class CrashesTest method testNativeCrashLog.
private ManagedErrorLog testNativeCrashLog(long appStartTime, long crashTime, boolean correlateSession) throws Exception {
/* Setup mock for a crash in disk. */
File minidumpFile = mock(File.class);
when(minidumpFile.getName()).thenReturn("mockFile");
when(minidumpFile.lastModified()).thenReturn(crashTime);
mockStatic(SessionContext.class);
SessionContext sessionContext = mock(SessionContext.class);
when(SessionContext.getInstance()).thenReturn(sessionContext);
if (correlateSession) {
SessionContext.SessionInfo sessionInfo = mock(SessionContext.SessionInfo.class);
when(sessionContext.getSessionAt(crashTime)).thenReturn(sessionInfo);
when(sessionInfo.getAppLaunchTimestamp()).thenReturn(appStartTime);
}
mockStatic(DeviceInfoHelper.class);
when(DeviceInfoHelper.getDeviceInfo(any(Context.class))).thenReturn(mock(Device.class));
ErrorReport report = new ErrorReport();
mockStatic(ErrorLogHelper.class);
when(ErrorLogHelper.getLastErrorLogFile()).thenReturn(mock(File.class));
when(ErrorLogHelper.getStoredErrorLogFiles()).thenReturn(new File[] { mock(File.class) });
when(ErrorLogHelper.getNewMinidumpFiles()).thenReturn(new File[] { minidumpFile });
File pendingDir = mock(File.class);
Whitebox.setInternalState(pendingDir, "path", "");
when(ErrorLogHelper.getPendingMinidumpDirectory()).thenReturn(pendingDir);
when(ErrorLogHelper.getStoredThrowableFile(any(UUID.class))).thenReturn(mock(File.class));
when(ErrorLogHelper.getErrorReportFromErrorLog(any(ManagedErrorLog.class), any(Throwable.class))).thenReturn(report);
when(StorageHelper.InternalStorage.read(any(File.class))).thenReturn("");
when(StorageHelper.InternalStorage.readObject(any(File.class))).thenReturn(new NativeException());
LogSerializer logSerializer = mock(LogSerializer.class);
ArgumentCaptor<Log> log = ArgumentCaptor.forClass(Log.class);
when(logSerializer.serializeLog(log.capture())).thenReturn("{}");
when(logSerializer.deserializeLog(anyString())).thenAnswer(new Answer<ManagedErrorLog>() {
@Override
public ManagedErrorLog answer(InvocationOnMock invocation) throws Throwable {
ManagedErrorLog log = mock(ManagedErrorLog.class);
when(log.getId()).thenReturn(UUID.randomUUID());
return log;
}
});
/* Start crashes. */
Crashes crashes = Crashes.getInstance();
crashes.setLogSerializer(logSerializer);
crashes.onStarting(mAppCenterHandler);
crashes.onStarted(mock(Context.class), "", mock(Channel.class));
/* Verify timestamps on the crash log. */
assertTrue(Crashes.hasCrashedInLastSession().get());
assertTrue(log.getValue() instanceof ManagedErrorLog);
return (ManagedErrorLog) log.getValue();
}
use of com.microsoft.appcenter.crashes.model.NativeException in project mobile-center-sdk-android by Microsoft.
the class CrashesAndroidTest method getLastSessionCrashReportNative.
@Test
public void getLastSessionCrashReportNative() throws Exception {
/* Null before start. */
Crashes.unsetInstance();
assertNull(Crashes.getLastSessionCrashReport().get());
assertFalse(Crashes.hasCrashedInLastSession().get());
assertNull(Crashes.getMinidumpDirectory().get());
/* Simulate we have a minidump. */
File newMinidumpDirectory = ErrorLogHelper.getNewMinidumpDirectory();
File minidumpFile = new File(newMinidumpDirectory, "minidump.dmp");
StorageHelper.InternalStorage.write(minidumpFile, "mock minidump");
/* Start crashes now. */
startFresh(null);
/* We can access directory now. */
assertEquals(newMinidumpDirectory.getAbsolutePath(), Crashes.getMinidumpDirectory().get());
ErrorReport errorReport = Crashes.getLastSessionCrashReport().get();
assertNotNull(errorReport);
assertTrue(Crashes.hasCrashedInLastSession().get());
assertTrue(errorReport.getThrowable() instanceof NativeException);
/* File has been deleted. */
assertFalse(minidumpFile.exists());
/* After restart, it's processed. */
Crashes.unsetInstance();
startFresh(null);
assertNull(Crashes.getLastSessionCrashReport().get());
assertFalse(Crashes.hasCrashedInLastSession().get());
}
Aggregations