How do you interpret a deobfuscated Android crash report? - proguard

I downloaded a crash report from my app's Google Play admin area, ran it through retrace.sh to deobfuscate the Proguard mapping, and it produced the output below.
Questions:
What is Unknown Source?
showHeader, showPhoto, etc. are indeed methods in my SummaryFragment class, but why are they listed in the order shown? These methods do not follow any sort of logical or execution order in my code.
In which method was the NPE actually thrown?
Caused by: java.lang.NullPointerException
at com.myapp.SummaryFragment.selectMenuItemAuth(Unknown Source)
showHeader
photoButtonClicked
showPhoto
nameButtonClicked
deleteByID
access$0
at com.myapp.SummaryFragment.onActivityCreated(Unknown Source)
at android.support.v4.app.Fragment.performActivityCreated(Unknown Source)
at android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source)
moveToState
moveToState
moveToState

ProGuard has removed the optional attributes SourceFile and LineNumberTable from the obfuscated application. As a result, the stack traces don't have line numbers, causing some ambiguity. ReTrace prints out a list of possible alternatives for each line of the stack trace.
You can get stack traces that are easier to interpret by adding the following lines to your proguard-project.txt:
-renamesourcefileattribute MyApplication
-keepattributes SourceFile,LineNumberTable
See the ProGuard manual > ReTrace > Usage.
See the ProGuard manual > Examples > Producing useful stack traces

Related

Kotlin - Document exception thrown by an interface method

Since Kotlin hasn't got checked exception, what's the correct way to document exception expected to be thrown by an interface method? Should I document it in the interface or in the implementing class (only if the concrete method actually throws it)?
Since clients program against the interface, I'd suggest the documentation to be made in the Javadoc/KDoc of that interface. Whether you actually should document them is discussed in this thread for example:
Oracle recommends:
If it's so good to document a method's API, including the exceptions it can throw, why not specify runtime exceptions too? Runtime exceptions represent problems that are the result of a programming problem, and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way. Such problems include arithmetic exceptions, such as dividing by zero; pointer exceptions, such as trying to access an object through a null reference; and indexing exceptions, such as attempting to access an array element through an index that is too large or too small. Runtime exceptions can occur anywhere in a program, and in a typical one they can be very numerous. Having to add runtime exceptions in every method declaration would reduce a program's clarity.
So if the information is useful for a client it should be documented (i.e. if the client can handle it, e.g. IOException). For "regular" runtime exceptions such as an IllegalArgumentException I would say "no", do not document them.

Too many classes in --main-dex-list, main dex capacity exceeded

I'm trying to run instrumentation test cases but getting the below error while dex conversion
UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexException: Too many classes in --main-dex-list, main dex capacity exceeded
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:494)
at com.android.dx.command.dexer.Main.runMultiDex(Main.java:334)
at com.android.dx.command.dexer.Main.run(Main.java:244)
at com.android.dx.command.dexer.Main.main(Main.java:215)
at com.android.dx.command.Main.main(Main.java:106)
:App:dexDebug FAILED
How to resolve this issue in gradle?
Let's first understand the problem:
On pre-Lollipop devices, only main dex is being loaded by the framework. To support multi-dex applications you have to explicitly patch application class loader with all the secondary dex files (this is why your Application class have to extend MultiDexApplication class or call MultiDex#install).
This means that your application's main dex should contain all the classes that are potentially accessible before class loader patching.
You will receive java.lang.ClassNotFoundException if your application code will try to reference a class that was packaged in one of your secondary dex files before successfully patching application class loader.
I've documented here how plugin decides which classes should be packaged in main-dex.
If total amount of methods that those classes are referencing exceeds the 65,536 limit, then build will fail with Too many classes in --main-dex-list, main dex capacity exceeded error.
I can think of three possible solutions for this issue:
(The easiest solution, but not suitable for most of the
applications) Change your minSdkVersion to 21.
Shrink your application code. This was discussed many times previously (see here and here).
If none of the above solutions work for you, you can try to use my workaround for this issue - I'm patching the Android gradle plugin to not include Activity classes in main dex. It's a bit hacky, but works well for me.
There's an issue in Android bug tracker regarding this error. Hopefully the Tools team will provide a better solution soon.
Update (4/27/2016)
Version 2.1.0 of Gradle plugin allows to filter main-dex list classes.
Warning: this is using an unsupported api that will be replaced in the future.
For example, to exclude all activity classes you can do:
afterEvaluate {
project.tasks.each { task ->
if (task.name.startsWith('collect') && task.name.endsWith('MultiDexComponents')) {
println "main-dex-filter: found task $task.name"
task.filter { name, attrs ->
def componentName = attrs.get('android:name')
if ('activity'.equals(name)) {
println "main-dex-filter: skipping, detected activity [$componentName]"
return false
} else {
println "main-dex-filter: keeping, detected $name [$componentName]"
return true
}
}
}
}
}
You can also check my example project that demonstrates this issue (and applies the above filtering).
Update 2 (7/1/2016)
Version 2.2.0-alpha4 of Gradle plugin (with build-tools v24) finally solves this issue by reducing multidex keep list to a minimum.
The unsupported (and undocumented) filter from 2.1.0 should not be used anymore. I've updated my sample project, demonstrating that build succeeds now without any custom build logic.
One other way to resolve this issue is to remove classes with Runtime annotations from the main DEX file:
android {
dexOptions {
keepRuntimeAnnotatedClasses false
}
}
This is particularly helpful for applications which are using dependency injection frameworks since even for Dagger annotations are usually kept in runtime.
You have two choices.
use ProGuard to strip down number of methods
use multidex feature
My advice - go with ProGuard, it require as little as zero changes to source code

Class not found exception in Java application : can PermGen size be the reason

Can class not found exception be caused due to PermGen size ? If not , then what could be the possible reasons for that when JVM is concerned.
Can class not found exception be caused due to PermGen size ?
No, and I wonder what could have ever led you to believe that this might be the case!
If not , then what could be the possible reasons for that when JVM is concerned.
Usually it occurs because of an attempt to load a class which isn't on the classpath (or which doesn't exist at all).

Is there a way to Track/trace and log all the methods, by Class and Method name, during a debug session?

I am not interested in logging into frameworks or under the covers but only at my source level code upon entry and exit of each method. I would like it to provide Class Name and Method Name and log it to file or at least have it fly by on the screen.
My query is if it is possible with existing Xcode/Debugger/Instruments facilities, can I implement it in an easy way other than an NSLog statement at every method entry and exit, or is there a commercial tool that provides this capability ?
I'm talking source methods here... not execution processes or threads. Thanks.
Dave Dribin covers precisely this in his article Tracing Objective-C messages.
The part you are after is probably this:
If you set the NSObjCMessageLoggingEnabled environment variable to YES, the Objective-C runtime will log all dispatched Objective-C messages to a file named /tmp/msgSends-<pid>.
Xtrace (https://github.com/johnno1962/Xtrace) has many features and works well for tracing Objective-C. One needs source access to their project, like you appear to have, and can emit messages on entry/exit, like you appear to want.
Debug-time configuration - can hard-code or configure tracing while debugging
Uncomplicated integration - one .mm and one .h
NSRegularExpression matching - classes, methods, types
An alternative which you can use with iOS simulator on the Mac (arm/x86_64)
Create a Symbolic Breakpoint
Symbol: objc_msgSend
Action: Debugger Command
Command:
p (void)printf("[%s, %s]\n", (char*)object_getClassName($arg1), $arg2)
*p is an alias for expr --
Check: Automatically continue after evaluating actions

Error while doing GetComponentParts in MEF

While doing GetComponentParts I am getting following error, to be specific it reporoduces while i do import in continuous loop while handling multiple messages in my WCF application
The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.
1) The composition failed because it did not complete within '100' iterations. This is most likely caused by a cycle in the dependency graph of a part which is marked with a non-shared creation policy.
One more thing I cant locate CompositionException.Errors to find the root cause.
Please suggest what workaround possible, as i am not getting a single thread on the net suggesting any way...
Many Thanks
Since this is working most of the time, it is probably a threading issue which is corrupting MEF's internal state and causing this error.
When using a CompositionContainer from multiple threads, you need to create it with the isThreadSafe parameter set to true, and avoid calling methods which modify what is available - such as Compose, ComposeParts, or AddExportedValue.
Methods which are safe to call are the GetExport and SatisfyImports methods.