I have an app in production and I'm using Firebase for error and crash logging. Lately, I've been seeing some lines in the stack trace of the exceptions, starting with <OR>. Below is an example taken directly (save for the package name) from an exception reported by Firebase:
Exception java.lang.NullPointerException: Attempt to invoke interface method 'void com.mycompany.myapp.managers.b$a.f()' on a null object reference
com.mycompany.myapp.managers.PermissionManager.getInstance (PermissionManager.java)
<OR>.checkPermission (PermissionManager.java)
<OR>.onRequestPermissionsResult (PermissionManager.java)
com.mycompany.myapp.activities.ShareImageActivity.onSaveShare (ShareImageActivity.java)
com.mycompany.myapp.activities.ShareImageActivity$3.onClick (ShareImageActivity.java)
I know that this is not a regular stack trace since onRequestPermissionResults does not call checkPermission and checkPermission does not call PermissionManager.getInstance.
I assume this is one of the ways Android obfuscates the stack trace for the sake of security, but I couldn't find any documentation on this. Does anyone know how to interpret this stack trace?
The you see here is an indication that that Crash Reporting could not determine the actual object at that point. Currently, there is a known situation with Proguard deobfuscation where it could be ambiguous which object is the target here. This could be the case if you're stripping line numbers from your classes, which it looks like you are doing. This situation may improve if you are able to change your Proguard settings to remove the stripping of line numbers.
Add this to your proguard-rules.pro:
// obfuscate file name and keep line numbers
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
It should remove ambiguity and you should not see <OR> in your stacktrace anymore.
Related
I have Unable to create application im.app.android.core.AppDemoApplication: e3.b: com.pushserver.android.huaweiPushClient cant cast com.myApp.android.push_lib.huawei.HcmPushClient to PushClient error
What proguard rule should I add? I have tried -keep class com.myApp.android.push_lib.** { *; } but after that I just see the blank screen - no crash, just stuck when trying to start.
Not really an answer, but too long for a comment. I'll update this answer in case we make progress.
1. What is the "normal bug"?
can't cast com.myApp.android.push_lib.huawei.HcmPushClient to PushClient
This means that somewhere in your code you are assigning/passing an instance of HcmPushClient to something that is expecting it to be a PushClient. I would assume that PushClient is some class that you defined in your project, but is does not extend from HcmPushClient. Try to find this piece of code and fix it or add it here to your question.
2. What does ProGuard have to do with this?
Actually, I think not much. If ProGuard would create this error, the message would look more like
can't cast com.myApp.android.push_lib.a.b to c
But since all class names in the error message are the original ones, it does not seem like ProGuard is making issues here. BUT: You can still decypher the message a little bit, because this part is obfuscated:
Unable to create application im.app.android.core.AppDemoApplication: e3.b:
e3.b refers to a class that was obfuscated by ProGuard. To find out what class it is, you can check the file /build/outputs/mapping/release/mapping.txt in your project folder. This is a simple text file that stores the information what class name was renamed to what obfuscated name. In this file search for -> e3 to find the class that was renamed to e3. Somewhere close to this line, you should also be able to find out what exactly e3.b is. Could be a method, could also be a member variable or an inner class.
I hope these two points will bring you closer to make the app run.
It started to happen out of the blue a couple of months ago.
Android 10 only.
After the user upgrades to a new version of our app, a crash happens on launch.
The crash is only observed once for a given user.
So we think the crash happens right after the upgrade to the new build.
It is the new build that crashes (not the old one).
This is an example of a crash.
Fatal Exception: android.app.RemoteServiceException: Bad notification(tag=null, id=30) posted from package yo.app,
crashing app(uid=10613, pid=16365):
Couldn't inflate contentViewsandroid.view.InflateException: Binary XML file line #19 in yo.app:layout/sky_eraser_main:
Binary XML file line #19 in yo.app:layout/sky_eraser_main: Error inflating class androidx.appcompat.widget.Toolbar
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2052)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7710)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
The crashes look different from build to build.
But the pattern is the same.
Let me transcribe what is happening in our opinion.
There is an ongoing notification (id=30) displaying the temperature (we are making a weather app).
The notification is not able to post because of a crash while inflating its RemoteViews layout.
It seems that the original layout is substituted by another,
completely unrelated layout (sky_eraser_main used in another place of our app).
The wrong layout is different from build to build.
It looks as though integer layout-ids are getting mixed up.
Could it be the result of some weird R8 optimisation?
Unfortunately, we are not able to reproduce the crash locally.
Do you have an idea how to tackle these crashes?
The context
Target SDK: 30
Deployed as Android app bundle.
minifyEnabled = true
This is a kotlin multiplatform project.
From what you've been explaining looks like the resource references got updated as the app launches. This guy has the same problem
Essentially, the R class is an autogenerated class by the whole Android Studio build system that gets autogenerated whenever you add, remove and edit resource files. At the end of the day, each field of the "final" R classes (drawable, id, layout, etc.) hold an int value. And for some dark unknown reasons those references are getting updated at the time you first launch the app after an update on Android 10, (and very probably in Android 11 or some other vendor-dependant implementations of Android)
And as per the comment section in his answer (100+) votes doesn't seem to have a fix. I would try to try-catch the inflation of the layout and abort the notification if I manage to catch any exceptions.
Another approach would be to delay the launch of the notification using something like WorkManager to ensure that the references got updated by the time the NotifyWork kicks in
You may want to explicitly keep the whole class yo.app.R:
-keepattributes InnerClasses
-keep class yo.app.R
-keep class yo.app.R$* {
<fields>;
}
I use Debug#startMethodTracing(in Activity#onCreate) and Debug#stopMethodTracing(in Activity#onWindowFocusChanged) to get method call traces. But I can not find ViewRootImpl#performTraversals in trace in Monitor. What's wrong?
My code works fine but after applying proguard i am getting the following exception
05-04 16:12:00.803: E/AndroidRuntime(22257):
java.lang.NoSuchMethodError:
com.android.internal.telephony.ITelephony.a
I ma having Itelephony.aidl but still getting the error. Can anyone tell me if there is a way to around this ?
On google, i couldn't get more information on examples of how to keep interfaces, interface members and inner classes along with inner class members.
Actually i want to keep everything in my app but just obsfucate and optimize it. Is there a way to achieve it ?
You need to exclude the ITelephony class from proguard, i.e. add this ...
-keep class com.android.internal.telephony.ITelephony { *; }
... entry to your proguard.cfg file. You'll find it in your project root folder.
Proguard is a tool that obfuscates your code, i.e. makes it more compact and less readable for others by applying various optimization (e.g. renaming classes). So in some cases this might have a negative impact on the functionality, e.g. if you consider dynamic reflection calls.
Cheers!
My logcat window in Eclipse only displays the first few lines of the StackTrace for each exception. This means that I often can't see where an exception occured. Is there any way to change this setting?
If you're referring to the "...12 more lines..." part, you only see that for exceptions that were the cause of another exception. If the top part of the stack trace is the same as the earlier trace, the full set of frames is only shown for the outermost exception, and the other traces get the "..." treatment.
Put another way, the chunk of a trace that isn't shown is a duplicate of a trace that appeared earlier in the exception cause chain. For example, suppose I have code where the method main() calls one(), which calls two(), and so on. four() throws an exception. two() catches it and re-throws it. The exception will look like this:
java.lang.RuntimeException: re-throw
at Foo.two(Foo.java:14)
at Foo.one(Foo.java:7)
at Foo.main(Foo.java:3)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: first
at Foo.four(Foo.java:23)
at Foo.three(Foo.java:19)
at Foo.two(Foo.java:12)
... 3 more
The "caused by" exception says "... 3 more" rather than explicitly listing one(), main(), and dalvik.system.NativeStart.main. So to get the full trace of the initial exception, you would start by reading its trace, then continue at the trace above.
Note there is no overlap -- two() appears in both, but in the "first" trace it's on the call to three(), and in the "re-throw" trace it's on the throw instruction.
you can overload all the log methods (log.d, log.i, log.e, etc) with (String tag, String msg, Throwable tr) parameters, where the third parameter is the exception. This will give you the full stacktrace in logcat
http://developer.android.com/reference/android/util/Log.html
If your code calls a method which produces too tall of stack you can (and should) handle the exception in your code and output whatever is relevant to logs.
If you have no exception handling whatsoever and you don't even know where in your code should you be putting such a handler then the problem is entirely elsewhere - you should be handling exceptions a bit better than that.