String's equals() method return wrong when using the generic C implementation of Android's Dalvik VM.

by Peter » Tue, 28 Apr 2009 14:43:25 GMT


Sponsored Links
 Hi,

I'm porting Android on a new architecture called XBurst, just like arm
and x86.

I did the following things:

1. Build a new toolchain for XBurst.
2. Porting the Linux 2.6.27 kernel to XBurst.
3. Porting the Android libc called bionic to XBurst (added syscalls,
linker etc.)
4. Use the generic C implementation of Dalvik VM (the quicker way for
me, next I will port it to XBurst)

Now, Android can be run successfully on XBurst and most applications
work normally.

But there is one problem with the String's equals() method. Some Java
codes using this method
get a wrong return value. For example:


String str1 = "android.intent.action.VIEW";
String str2 = "android.intent.action.PICK";
String str3 = "android.intent.action.GET_CONTENT";
Boolean res1, res2;

res1 = str1.equals(str2);
res2 = str1.equals(str3);

I ran these codes on the Android's emulator and they returned
res1=false and res2=false. (They are correct)

But when I ran them on XBurst, they returned res1=true and res2=false.
(They are wrong)

I did several tests with different strings and found that when the two
strings have different length, the method
can return a correct value. While they have the same length, the
method return a wrong value.

Then I ran above codes with dalvikvm on the command shell, and found
that they returned res1=false
and res2=false. (They are correct)

The difference is that the wrong one was got when the Android runtime
startuped and while the correct
one is just running .jar file on the command shell with dalvikvm.

So I guessed this should be the Android runtime problem when using the
generic C implementation of Dalvik VM.

Can anyone tell me the true reason? Is it a bug of the Android runtime
codes? Or is there other ways to help me to locate the issue?

Any suggestions are appreciated.

-
Peter





--~--~---------~--~----~------------~-------~--~----~

-~----------~----~----~----~------~----~------~--~---



String's equals() method return wrong when using the generic C implementation of Android's Dalvik VM.

by fadden » Wed, 29 Apr 2009 02:24:17 GMT


 


There might be something else at work, depending on how exactly you're
going about things.

The optimizations performed by "dexopt" include a form of instruction
inlining.  For a handful of methods, listed in the gDvmInlineOpsTable
in dalvik/vm/InlineNative.c, the method call is replaced with an
instruction that performs the desired action without any of the method
overhead.  The actual implementation doesn't run any faster than a
method declared "native", but we can skip all of the stack frame prep
and other method call overhead, so it's useful for simple methods that
are called very frequently.

Typically your String.equals() call will end up in
javaLangString_equals() in InlineNative.c.  This may use an Android-
specific ARM "memcmp16" function, or do a simple iterative loop in C.
The result goes into "pResult->i", and the function returns "true" to
indicate that no exception was thrown.

If for some reason "dexopt" didn't optimize the code that calls
String.equals(), you will call the implementation in String.java
(dalvik/libcore/luni/src/main/java/java/lang/String.java).

I looked over the code and all of the implementations seem correct.
They all test the length before comparing characters, so I can see how
you could get the results you described above if one of the comparison
loops was broken.

When invoking Dalvik from the command line, you can control which
interpreter runs with "-Xint"; use "-Xint:portable" or "-Xint:fast".
You can control DEX optimizations with -Xdexopt, e.g. -Xdexopt:none to
disable it.  You can verify what it did by running "dexdump -d" on the
optimized file in /data/dalvik-cache.  Note the file doesn't get
regenerated if it doesn't need to be, so remove the /data/dalvik-cache
entry before running dalvikvm with a different "-Xdexopt" option.

--~--~---------~--~----~------------~-------~--~----~

-~----------~----~----~----~------~----~------~--~---


Sponsored Links


String's equals() method return wrong when using the generic C implementation of Android's Dalvik VM.

by Peter » Wed, 29 Apr 2009 09:32:16 GMT


 i fadden,

Thanks for your suggestions.

Sure I traced the String.equals and found that some codes call the
implementation in String.java, while the test code of mine didn't call
it. Then I followed your advice to trace the inline native
implementation
in dalvik/vm/InlineNative.c, luckily that it was called.

Then I checked the code in InlineNative.c carefully. They are all
correct.
And then the __memcmp16() in my implementation. And finally I found
that my __memcmp16() was wrong. In my implementation, I think that
the third parameter "size_t count" is in byte-length. While by reading
InlineNative.c I knowed that it is in short-length, but not byte-
length.
So my __memcmp16() return a wrong value to "pResult->i" when the
two strings have the same length.

And now by fixing __memcmp16(), the test code ran well and can return
the correct result.

Thanks fadden again.

You know that my work is to porting Android to a new architecture
different from arm and x86. So almost everything needs to be added
for me, the toolchain, the kernel, the bionic C library, then the
Dalvik
VM. The problem of String.equals was caused by the bionic C library.
And your advice helped me to locate and fix the issue.

-
Peter

On 49 24 fadden <fad...@android.com> wrote:
--~--~---------~--~----~------------~-------~--~----~

-~----------~----~----~----~------~----~------~--~---



Other Threads

1. Google TV Remote Control App

Has anyone put a packet sniffer on the remote control app provided for
Android devices to interact with Google TV? I'm curious about what the
protocol is.  I would guess that it's ProtoBuf, or possibly XBMC
(wouldn't that be nice?)...

Dave

-- 

2. Invisible AlertDialog?

Believe me, I am not trying to create an invisible AlertDialog.

But I believe I have one. I'm not making this up.

Behavior: main activity starts and is completely unresponsive. No
dialog appears. No Force close/ANR appears even after much time in
this state. But if I push the back button, it becomes responsive
again.

This does not occur when debuggable is true in the manifest, so I
can't investigate using the de{*filter*}.

But I found out the following with log statements.

MainActrivity:OnCreate starts another activity, a welcome screen.
MainActivity:OnResume is called while the other activity is visible.
OnResume creates the dialog and calls dlg.Show();
WelcomeActivity is dismissed.
MainActivity:OnResume is called. The OnResume method is smart enough
to note that the dialog has already been shown and does not create it
again.
MainActivity is unresponsive. No dialog in sight.
When I push the back button, a log statement confirms that the
OnCancelListener is called on the dialog.

This is Nexus One with  2.2.1.

As cool as an invisible dialog is, I'd rather not have it. Can I fix
it?

-- 

3. problems with cancelling of BackgroundAsyncTask in Activity

4. displaying nearby schools and airports in google maps android

5. Best way for accessing web service

6. gmail.com not working on webview (after login)

7. is there a way to send an event like a user would...