-
Notifications
You must be signed in to change notification settings - Fork 205
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
synthesize native crash and anr reports (#2094)
* feat(ExitInfo): ExitInfo setOnEventStoreEmptyCallback * feat(ExitInfo): ExitInfo setOnEventStoreEmptyCallback * feat(ExitInfo): Track exitinfokey with event * feat(ExitInfo):new event with Anr exitInfo * refactor(EventStore): reworked the EventStore callback to only be called once, and only when the store is completely empty (no files in queue or in storage) * feat(ExitInfo):new event with Anr exitInfo * feat(ExitInfo): ExitInfo setOnEventStoreEmptyCallback * refactor(EventStore): reworked the EventStore callback to only be called once, and only when the store is completely empty (no files in queue or in storage) * refactor(EventStore): reworked the EventStore callback to only be called once, and only when the store is completely empty (no files in queue or in storage) * feat(ExitInfo): ExitInfo setOnEventStoreEmptyCallback * feat(ExitInfo):new event with Anr exitInfo * feat(ExitInfo):register EventStoreEmptyCallback in exitinfo plugin * feat(ExitInfo)synthesize native crash reports * feat(ExitInfo)add exit infos at first run --------- Co-authored-by: jason <[email protected]>
- Loading branch information
1 parent
1c13c98
commit e23af62
Showing
14 changed files
with
350 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 10 additions & 2 deletions
12
bugsnag-plugin-android-exitinfo/api/bugsnag-plugin-android-exitinfo.api
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,30 @@ | ||
public final class com/bugsnag/android/BugsnagExitInfoPlugin : com/bugsnag/android/Plugin { | ||
public static final field Companion Lcom/bugsnag/android/BugsnagExitInfoPlugin$Companion; | ||
public fun <init> ()V | ||
public fun <init> (Lcom/bugsnag/android/ExitInfoPluginConfiguration;)V | ||
public synthetic fun <init> (Lcom/bugsnag/android/ExitInfoPluginConfiguration;ILkotlin/jvm/internal/DefaultConstructorMarker;)V | ||
public fun load (Lcom/bugsnag/android/Client;)V | ||
public fun unload ()V | ||
} | ||
|
||
public final class com/bugsnag/android/BugsnagExitInfoPlugin$Companion { | ||
} | ||
|
||
public final class com/bugsnag/android/ExitInfoPluginConfiguration { | ||
public fun <init> ()V | ||
public fun <init> (ZZZ)V | ||
public synthetic fun <init> (ZZZILkotlin/jvm/internal/DefaultConstructorMarker;)V | ||
public fun <init> (ZZZZZ)V | ||
public synthetic fun <init> (ZZZZZILkotlin/jvm/internal/DefaultConstructorMarker;)V | ||
public fun equals (Ljava/lang/Object;)Z | ||
public final fun getDisableProcessStateSummaryOverride ()Z | ||
public final fun getIncludeLogcat ()Z | ||
public final fun getListOpenFds ()Z | ||
public final fun getReportUnmatchedAnrs ()Z | ||
public final fun getReportUnmatchedNativeCrashes ()Z | ||
public fun hashCode ()I | ||
public final fun setDisableProcessStateSummaryOverride (Z)V | ||
public final fun setIncludeLogcat (Z)V | ||
public final fun setListOpenFds (Z)V | ||
public final fun setReportUnmatchedAnrs (Z)V | ||
public final fun setReportUnmatchedNativeCrashes (Z)V | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
134 changes: 134 additions & 0 deletions
134
bugsnag-plugin-android-exitinfo/src/main/java/com/bugsnag/android/EventSynthesizer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package com.bugsnag.android | ||
|
||
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED | ||
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE | ||
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND | ||
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE | ||
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE | ||
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE | ||
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE_PRE_26 | ||
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE | ||
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_TOP_SLEEPING | ||
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE | ||
import android.app.ActivityManager.RunningAppProcessInfo.REASON_PROVIDER_IN_USE | ||
import android.app.ActivityManager.RunningAppProcessInfo.REASON_SERVICE_IN_USE | ||
import android.app.ApplicationExitInfo | ||
import android.app.ApplicationExitInfo.REASON_ANR | ||
import android.app.ApplicationExitInfo.REASON_CRASH_NATIVE | ||
import android.os.Build | ||
import androidx.annotation.RequiresApi | ||
|
||
@RequiresApi(Build.VERSION_CODES.R) | ||
internal class EventSynthesizer( | ||
private val anrEventEnhancer: (Event, ApplicationExitInfo) -> Unit, | ||
private val nativeEnhancer: (Event, ApplicationExitInfo) -> Unit, | ||
private val exitInfoPluginStore: ExitInfoPluginStore, | ||
private val reportUnmatchedAnrs: Boolean, | ||
private val reportUnmatchedNativeCrashes: Boolean | ||
) { | ||
fun createEventWithExitInfo(appExitInfo: ApplicationExitInfo): Event? { | ||
val knownExitInfoKeys = exitInfoPluginStore.exitInfoKeys | ||
val exitInfoKey = ExitInfoKey(appExitInfo) | ||
|
||
if (knownExitInfoKeys.contains(exitInfoKey)) return null | ||
else exitInfoPluginStore.addExitInfoKey(exitInfoKey) | ||
|
||
when (appExitInfo.reason) { | ||
REASON_ANR -> { | ||
return createEventWithUnmatchedAnrsReport(exitInfoKey, appExitInfo) | ||
} | ||
|
||
REASON_CRASH_NATIVE -> { | ||
return createEventWithUnmatchedNativeCrashesReport(exitInfoKey, appExitInfo) | ||
} | ||
|
||
else -> return null | ||
} | ||
} | ||
|
||
private fun createEventWithUnmatchedAnrsReport( | ||
exitInfoKey: ExitInfoKey, | ||
appExitInfo: ApplicationExitInfo | ||
): Event? { | ||
if (reportUnmatchedAnrs) { | ||
val newAnrEvent = InternalHooks.createEmptyANR(exitInfoKey.timestamp) | ||
addExitInfoMetadata(newAnrEvent, appExitInfo) | ||
anrEventEnhancer(newAnrEvent, appExitInfo) | ||
val thread = getErrorThread(newAnrEvent) | ||
val error = newAnrEvent.addError("ANR", appExitInfo.description) | ||
thread?.let { error.stacktrace.addAll(it.stacktrace) } | ||
|
||
return newAnrEvent | ||
} else { | ||
return null | ||
} | ||
} | ||
|
||
private fun createEventWithUnmatchedNativeCrashesReport( | ||
exitInfoKey: ExitInfoKey, | ||
appExitInfo: ApplicationExitInfo | ||
): Event? { | ||
if (reportUnmatchedNativeCrashes) { | ||
val newNativeEvent = InternalHooks.createEmptyCrash(exitInfoKey.timestamp) | ||
addExitInfoMetadata(newNativeEvent, appExitInfo) | ||
nativeEnhancer(newNativeEvent, appExitInfo) | ||
val thread = | ||
getErrorThread(newNativeEvent) | ||
val error = newNativeEvent.addError("Native", appExitInfo.description) | ||
thread?.let { error.stacktrace.addAll(it.stacktrace) } | ||
return newNativeEvent | ||
} else { | ||
return null | ||
} | ||
} | ||
|
||
private fun getErrorThread(newNativeEvent: Event): Thread? { | ||
val thread = | ||
newNativeEvent.threads.find { it.name == "main" } | ||
?: newNativeEvent.threads.firstOrNull() | ||
return thread | ||
} | ||
|
||
private fun addExitInfoMetadata( | ||
newEvent: Event, | ||
appExitInfo: ApplicationExitInfo | ||
) { | ||
newEvent.addMetadata("exitinfo", "description", appExitInfo.description) | ||
newEvent.addMetadata( | ||
"exitinfo", | ||
"importance", | ||
getExitInfoImportance(appExitInfo.importance) | ||
) | ||
newEvent.addMetadata( | ||
"exitinfo", "Proportional Set Size (PSS)", "${appExitInfo.pss} kB" | ||
) | ||
newEvent.addMetadata( | ||
"exitinfo", "Resident Set Size (RSS)", "${appExitInfo.rss} kB" | ||
) | ||
} | ||
|
||
private fun getExitInfoImportance(importance: Int): String = when (importance) { | ||
IMPORTANCE_FOREGROUND -> "foreground" | ||
IMPORTANCE_FOREGROUND_SERVICE -> "foreground service" | ||
IMPORTANCE_TOP_SLEEPING -> "top sleeping" | ||
IMPORTANCE_TOP_SLEEPING_PRE_28 -> "top sleeping" | ||
IMPORTANCE_VISIBLE -> "visible" | ||
IMPORTANCE_PERCEPTIBLE -> "perceptible" | ||
IMPORTANCE_PERCEPTIBLE_PRE_26 -> "perceptible" | ||
IMPORTANCE_CANT_SAVE_STATE -> "can't save state" | ||
IMPORTANCE_CANT_SAVE_STATE_PRE_26 -> "can't save state" | ||
IMPORTANCE_SERVICE -> "service" | ||
IMPORTANCE_CACHED -> "cached/background" | ||
IMPORTANCE_GONE -> "gone" | ||
IMPORTANCE_EMPTY -> "empty" | ||
REASON_PROVIDER_IN_USE -> "provider in use" | ||
REASON_SERVICE_IN_USE -> "service in use" | ||
else -> "unknown importance ($importance)" | ||
} | ||
|
||
companion object { | ||
const val IMPORTANCE_EMPTY = 500 | ||
const val IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170 | ||
const val IMPORTANCE_TOP_SLEEPING_PRE_28 = 150 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.