Tech Stuff: Android segfault when using VelocityTracker?!

CoboltForge Berlin  -  Jun 12, 2012  -  No Comments

And here’s another one in the tech stuff series, this time about a recurring NDK segfault in a pure Java app…

The problem


I/DEBUG ( 107): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
I/DEBUG ( 107): r0 00000000 r1 00000000 r2 00000000 r3 50af4ed4
I/DEBUG ( 107): r4 00000000 r5 01df5c00 r6 00000000 r7 50af4ea8
I/DEBUG ( 107): r8 5afa0c10 r9 50af4ea0 10 00000008 fp 5afa0c24
I/DEBUG ( 107): ip 4021e744 sp 5afa0c00 lr 401d9a69 pc 405966fe cpsr 60000030
I/DEBUG ( 107): d0 42c8000042be6afd d1 3ff000000065eed0
I/DEBUG ( 107): d2 437e8000000000fe d3 000000003f000000
I/DEBUG ( 107): d4 000001fd00000000 d5 0006ea0000000000
I/DEBUG ( 107): d6 006b0ff000000000 d7 0000005f4e1f4525
I/DEBUG ( 107): d8 0000000000000000 d9 0000000000000000
I/DEBUG ( 107): d10 0000000000000000 d11 0000000000000000
I/DEBUG ( 107): d12 0000000000000000 d13 0000000000000000
I/DEBUG ( 107): d14 0000000000000000 d15 0000000000000000
I/DEBUG ( 107): d16 0000000700000001 d17 3ff0000000000000
I/DEBUG ( 107): d18 4146605000000000 d19 bfb1be5a93a83e1d
I/DEBUG ( 107): d20 3f1155e54e7e8408 d21 bebbbc6c1a570a20
I/DEBUG ( 107): d22 3ff0000000000000 d23 3fede16b9c24a98f
I/DEBUG ( 107): d24 3e66376972bea4d0 d25 3fc39a09d078c69f
I/DEBUG ( 107): d26 0000000000000000 d27 0000000000000000
I/DEBUG ( 107): d28 0000000000000000 d29 0000000000000000
I/DEBUG ( 107): d30 0000000000000000 d31 0000000000000000
I/DEBUG ( 107): scr 80000012
I/DEBUG ( 107):
I/DEBUG ( 107): #00 pc 0000b6fe /system/lib/libui.so (_ZN7android15VelocityTracker5clearEv)
I/DEBUG ( 107): #01 pc 00059a66 /system/lib/libandroid_runtime.so (_ZN7android20VelocityTrackerState5clearEv)
I/DEBUG ( 107): #02 pc 00059a7c /system/lib/libandroid_runtime.so
I/DEBUG ( 107): #03 pc 0001ec30 /system/lib/libdvm.so (dvmPlatformInvoke)
I/DEBUG ( 107): #04 pc 00058f6c /system/lib/libdvm.so (_Z16dvmCallJNIMethodPKjP6JValuePK6MethodP6Thread)

WTF?! This app is not using any NDK features! That is, not directly – some Android Java classes do of course call native code. In this app, we’re working with a pure Java API – but why do we get a nicee shiny reproducable segmentation violation after some time?

Seems to have something to do with our use of VelocityTracker, which needs to be obtained and recycled manually…

The solution

… To keep a long story short, never ever call a possibly not thread-safe method in a classes’ finalize() method! The reason is that from Honeycomb on, the garbage collector uses multi-threading more agressively, which increases the chance of your finalize() method being run on a different thread than the GUI thread. And recycling of those VelocityTrackers seems to have to be done on the main thread. Baam!

For the curious, the culprit was:

@Override
protected void finalize() throws Throwable {
	try {
		twoFingerFlingVelocityTracker.recycle();
		twoFingerFlingVelocityTracker = null;
	}
	catch (NullPointerException e) {
	}
	Log.d(TAG, "TouchpadInputHandler " + this +  " destroyed!");
        super.finalize();
	}

of a custom TouchPadInputHandler class containing a VelocityTracker. Refactoring this code to a manually called (i.e. on the GUI thread) shutdown() method fixed the problem…

Leave a Comment

Your email address will not be published. Required fields are marked *

*