2

The NDK has the ability to enable the address sanitizer on anything you build with it by adding the -fsanitize=address flag to both LOCAL_CFLAGS and LOCAL_LDFLAGS, which is nice. Well, it would be nice if it actually worked. If you add that flag and try building your library, you get a bunch of "undefined symbol" errors. You can ignore these errors by passing -Wl,--unresolved-symbols=ignore to the linker and the build completes successfully, but of course the adventure doesn't end here.

The Google's guide then says that you need a rooted device on which you run a script that modifies the runtime executable on the system partition so it loads the ASan library, and then the aforementioned missing symbols link at runtime. I tried this, and the main problem with this approach is that it also profiles something in the JVM itself thus slowing it down so much that the app doesn't start at all or crashes somewhere inside the JVM.

I've also tried the new malloc debug on an emulator but it also debugs the entire JVM thus making it unusable. All these tools seem to be absolutely not intended for the app developers but for those who work on Android itself.

I desperately need a way to fix a memory corruption crash in my app without profiling the whole virtual machine in the process. Will ASan work if I just put its library into my apk and load it before my JNI library? Are there any other ways to debug this? How do people fix this kind of bugs on Android at all?

Making a "minimal wrapper executable" and running it on some other operating system that has proper debugging tools isn't really an option here because the way the JNI library is used depends substantially on the Java part, and even if I make one, I can't be entirely sure that this bug will reproduce.

Update: I tried the asan_device_setup script on an Oreo emulator because it didn't work at all this time on a Nexus 9 with Nougat. The log flooded with linker errors of 32-bit processes trying to load 64-bit libraries and then it froze and the only way to make it usable again was flashing the factory image. Just to be sure I didn't mess anything up, I tried it several times reflashing the factory image, then TWRP, than SuperSU, and then using the "adbd insecure" app to restart the adb daemon as root. So, I started the emulator with -writable-system and ran the script on it, it completed successfully. I then built my app with ASAN and installed it, but it crashes with java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__asan_init_v3" referenced by "/data/...full path to the shared library on launch. I tried it both with and without setprop wrap.com.app.package "asanwrapper", the result is the same.

8
  • You probably mean Davlik/ART where you say JVM. Commented Nov 29, 2017 at 19:13
  • "Well, it would be nice if it actually worked. If you add that flag and try building your library, you get a bunch of "undefined symbol" errors." That shouldn't be happening. That's normal for a non-Android ASAN build, but Android uses a shared library version of the ASAN runtime which avoids this. Take a look at android.googlesource.com/platform/ndk/+/master/tests/device/… for an example of how to use ASAN with the NDK. Commented Nov 30, 2017 at 7:13
  • The list of undefined symbols should've also helped. Commented Nov 30, 2017 at 8:27
  • @DanAlbert like every other example I've ever seen, the one you linked builds an executable instead of a shared library. Commented Nov 30, 2017 at 22:44
  • So change it to BUILD_SHARED_LIBRARY. Commented Dec 1, 2017 at 2:31

1 Answer 1

2

You should probably file bugs (http://b.android.com) if you're seeing performance issues this serious. We run devices that are fully ASAN instrumented every day and those work better than you'd expect. ASAN is a roughly 2x slowdown, but running your app with ASAN should work fine.

Same goes for debug malloc (I don't remember the performance implications of debug malloc, but I thought they were less severe than ASAN).

Sign up to request clarification or add additional context in comments.

3 Comments

I've tried ASAN on a Moto X running 5.1 if that matters, and malloc debug on an emulator because I don't have an Oreo device with an unlocked bootloader. As I was writing this I realized I also have a Nexus 9 that I unlocked bootloader on at some point so I'll now try rooting it and running ASAN on it as well.
KitKat/Lollipop is when the ASAN for Android stuff was just coming together. It might be a much better experience on something newer.
I've updated my question with the results of my further unsuccessful experiments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.