How to Determine Android Native Function Call

This article will show the required steps to precisely determine android native call for given java method. This step is very important when trying to find the root cause of various application errors in Android platform.

I’ve came across issue when try to solve the problem of GLES 2.0 in my emulator, i.e. that my emulator do not work for GLES 2.0 and above.

This is indicated by program error when trying to execute sample GLES 2.0 provided by Android as follows:

and01

More information about this error can be found in the LogCat:

and02

The debugging session now consists of 2 phase, one for the jdwp debugger protocol, this is required to let the application communicates to the jdwp client, so that it can get executed instead of wait indefinitely for some connections.

For the java debugging session, this is done by adb shell as follows:

and03

After that, activates the application as usual. The application now shows the dialog box, saying it is waiting for the debugger, in this case, the jdwp:

and04

Checks for the PID of running process using ps command:

and05

Perform the jdwp forwarding for given PID:

and06

Now, activates the JDWP debugger, in my case is Netbeans. Attach and let the application run and stops just before the exception occurs, in this case, at eglChooseConfig method. You should acquire the correct android java source code and java IDE environment (Netbeans) so that it points to correct line number:

and07

If I perform one more step, the application will causes exception. So, its time to move forward to native debugging. Leave the Netbeans IDE as it is, and activates server side debugger in the emulator shell:

and08

Don’t forget to also perform tcp forwarding for this port so that gdb client can be connected. For gdbserver, it only done one time only.

and09

Now activates the gdb client specific for the platform, in my case is arm architecture, and sets necessary environment:

and10

The library path is created by perform adb pulling from the emulator.

Next, is to place the breakpoint at dvmCallJNIMethod. This function has parameter values as:

void dvmCallJNIMethod(const u4* args, JValue* pResult, const Method* method, Thread* self)

It is declared at Jni.cpp in $ANDROIDROOT\dalvik\vm directory.

The third parameter which is Method is of interest here, because it can be used to log the native function name and class structure. Method structure is declared in Object.h header file inside $ANDROIDROOT\dalvik\vm\oo directory.

and11

At the start of the function, the r2 register contains pointer to the method structure:

and12

First, verify that indeed the native function is related to the method name at Java side call. This is done by examining the in-memory pointer structure of name property (inside Method structure):

and13

There’s a useful flag to tell the Android system to print log of native call, it is the shouldTrace property. This value is always false, and it can be set to true by using this command:

and14

Now, activates the logcat and wait until there are no more output, and perform continuing of execution, this is the output in the logcat after the function call:

and15

From the above log, it is revealed that eglChooseConfig method belongs to com.google.android.gles_jni.EGLImpl. This string value can be inquired into the Android source code inside $ANDROIDROOT\Frameworks\Base\core\jni directory. This is done by replacing the . (dot) with _ (underscore).

By examining mappings inside the source code, it is known that eglChooseConfig is mapped to jni_eglChooseConfig. This function will eventually calls eglChooseConfig which is part of libEGL system library.

Although it is possible to directly determine the call by examining the insns inside Method structure routines via dvmPlatformInvoke, due to the dynamic nature of native code generation, current gdbserver version (v7.6) hangs (blocking) when breaking into this function. It is also causes of SIGILL when trying to break into libandroid_runtime.so address space.

In the end, this process is rather tedious, which should be the nature of open source culture 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: