|
1 | 1 | package eu.darken.sdmse.common.ipc
|
2 | 2 |
|
| 3 | +import eu.darken.sdmse.common.debug.Bugs |
| 4 | +import eu.darken.sdmse.common.debug.logging.Logging.Priority.VERBOSE |
3 | 5 | import eu.darken.sdmse.common.debug.logging.Logging.Priority.WARN
|
4 | 6 | import eu.darken.sdmse.common.debug.logging.log
|
| 7 | +import java.io.ByteArrayInputStream |
| 8 | +import java.io.ObjectInputStream |
| 9 | +import kotlin.io.encoding.Base64 |
| 10 | +import kotlin.io.encoding.ExperimentalEncodingApi |
5 | 11 |
|
6 | 12 | interface IpcClientModule {
|
7 | 13 |
|
| 14 | + @OptIn(ExperimentalEncodingApi::class) |
| 15 | + fun String.decodeStacktrace(): Array<StackTraceElement>? = try { |
| 16 | + val decodedBytes = Base64.decode(this) |
| 17 | + ObjectInputStream(ByteArrayInputStream(decodedBytes)).use { |
| 18 | + it.readObject() as Array<StackTraceElement> |
| 19 | + } |
| 20 | + } catch (e: Exception) { |
| 21 | + null |
| 22 | + } |
| 23 | + |
8 | 24 | fun Throwable.unwrapPropagation(): Throwable {
|
9 |
| - val matchResult = Regex("^[a-zA-Z0-9.]+Exception").find((message ?: "")) |
10 |
| - val exceptionName = matchResult?.value ?: return this |
11 |
| - val exceptionMessage = message!!.removePrefix("$exceptionName: ").trim() |
| 25 | + val matchResult = Regex("^([a-zA-Z0-9.]+Exception): ").find((message ?: "")) |
| 26 | + val exceptionName = matchResult?.groupValues?.get(1) ?: return this |
| 27 | + val messageParts = message!! |
| 28 | + .removePrefix(matchResult.groupValues.first()) |
| 29 | + .trim() |
| 30 | + .split(IpcHostModule.STACK_MARKER) |
12 | 31 |
|
13 | 32 | return try {
|
14 | 33 | Class.forName(exceptionName)
|
15 | 34 | .asSubclass(Throwable::class.java)
|
16 | 35 | .getConstructor(String::class.java)
|
17 |
| - .newInstance(exceptionMessage) |
18 |
| - .also { it.stackTrace = this.stackTrace } |
| 36 | + .newInstance(messageParts.first()) |
| 37 | + .also { newException -> |
| 38 | + // TODO: Couldn't find a way to keep the trace through parceling |
| 39 | + // it.stackTrace = this.stackTrace |
| 40 | + if (Bugs.isDebug && messageParts.size > 1) { |
| 41 | + log(VERBOSE) { "Decoding stacktrace..." } |
| 42 | + messageParts[1].decodeStacktrace()?.let { remoteTrace -> |
| 43 | + // Stacktrace on this side of the binder + the stacktrace on the other side of it |
| 44 | + newException.stackTrace = (remoteTrace + stackTrace).filter { |
| 45 | + !it.className.startsWith("android.os.Binder") && !it.className.startsWith("android.os.Parcel") |
| 46 | + }.toTypedArray() |
| 47 | + } |
| 48 | + } |
| 49 | + } |
19 | 50 | } catch (e: Exception) {
|
20 | 51 | log(WARN) { "Failed to unwrap exception: $this" }
|
21 | 52 | this
|
|
0 commit comments