Is it possible to access Dalvik VM from native code



Answers

How to invoke an Android Dalvik internal method using Java reflection?

This doesn't work. The reflection mechanism only knows how to find things visible to Java-language code.

You can invoke methods that are visible to managed code but not part of the public API. The VM's internal native functions simply aren't visible, and there is no VM function for finding them. All VM functions that are intended to be called are published explicitly as "native" methods in a class.

Question

I'd like to be able to target the Dalvik VM using native code in Android. This means using native classes that are listed in platform/dalvik under android sources repositories.

In particular, i'd like to call Sync.dvmLockObject and its counterpart Sync.dvmUnlockObject.

Is it possible ? Could you provide a quick snippet of code, or instructions for particular libraries to include ?

Alternatively, you can provide a java, or native code alternative that does the same (that is, be able to access a java object's monitor. Using pthread for example doesn't seem to be appropriated for example).




Calling Dalvik Stack from native code

Generally speaking, you don't. They're called "internal" functions for a reason.

If you're really determined to do this, you can find the function pointers by using dlsym() to find the address at runtime. You'll need the "mangled" name, which you can get by examining the binary with nm. (This was easier before the code was switched from C to C++ back in 4.1 or thereabouts.) You can get the Thread* the same way the VM does it, by calling one of the dvmGetThread functions in Thread.cpp (dvmGetThreadByHandle, dvmGetThreadByThreadId, dvmGetThreadFromThreadObject), or by calling dvmThreadSelf() if you're interested in the current thread. Pass that to dvmDumpThread(), which will set up the DebugOutputTarget so you don't have to.

You don't need a header file that defines Thread* to pass a Thread* around. Just declare the thread-getter functions as returning void*, and the thread-dump function as accepting a void* argument. If you're worried about type-safety and portability, don't call internal VM functions from an app.

The one time I actually wanted to do this -- debugging something, don't remember what -- I actually added a new extern "C" function to the VM that took no arguments and just dumped the current thread's stack. That made everything much easier.




Links



Tags