frostwire / frostwire-jlibtorrent

A swig Java interface for libtorrent by the makers of FrostWire. Develop libtorrent based apps with the joy of coding in Java.
http://www.frostwire.com
MIT License
444 stars 137 forks source link

JNI in call to NewStringUTF: DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal start byte #216

Closed gubatron closed 5 years ago

gubatron commented 5 years ago

Perhaps after an android studio or android update generate_fingerprint is causing a crash when NewStringUTF is called.

A/zygote: java_vm_ext.cc:504] JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal start byte 0x80
    java_vm_ext.cc:504]     string: '-FW211�-'
    java_vm_ext.cc:504]     input: '0x2d 0x46 0x57 0x32 0x31 0x31 <0x80> 0x2d'
    java_vm_ext.cc:504]     in call to NewStringUTF
    java_vm_ext.cc:504]     from java.lang.String com.frostwire.jlibtorrent.swig.libtorrent_jni.generate_fingerprint(java.lang.String, int, int, int, int)
    java_vm_ext.cc:504] "Thread-6" prio=5 tid=21 Runnable
    java_vm_ext.cc:504]   | group="main" sCount=0 dsCount=0 flags=0 obj=0x14cda318 self=0xd66b3400
    java_vm_ext.cc:504]   | sysTid=28284 nice=0 cgrp=default sched=0/0 handle=0xc8991970
    java_vm_ext.cc:504]   | state=R schedstat=( 48765310 56894835 480 ) utm=4 stm=0 core=4 HZ=100
    java_vm_ext.cc:504]   | stack=0xc888f000-0xc8891000 stackSize=1038KB
    java_vm_ext.cc:504]   | held mutexes= "mutator lock"(shared held)
    java_vm_ext.cc:504]   native: #00 pc 002c4bfb  /system/lib/libart.so (_ZN3art15DumpNativeStackERNSt3__113basic_ostreamIcNS0_11char_traitsIcEEEEiP12BacktraceMapPKcPNS_9ArtMethodEPv+130)
    java_vm_ext.cc:504]   native: #01 pc 003566a1  /system/lib/libart.so (_ZNK3art6Thread9DumpStackERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEEbP12BacktraceMapb+200)
    java_vm_ext.cc:504]   native: #02 pc 00352b73  /system/lib/libart.so (_ZNK3art6Thread4DumpERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEEbP12BacktraceMapb+34)
    java_vm_ext.cc:504]   native: #03 pc 002300d9  /system/lib/libart.so (_ZN3art9JavaVMExt8JniAbortEPKcS2_+736)
    java_vm_ext.cc:504]   native: #04 pc 002304cf  /system/lib/libart.so (_ZN3art9JavaVMExt9JniAbortVEPKcS2_St9__va_list+58)
    java_vm_ext.cc:504]   native: #05 pc 000d286f  /system/lib/libart.so (_ZN3art11ScopedCheck6AbortFEPKcz+46)
    java_vm_ext.cc:504]   native: #06 pc 000d2c01  /system/lib/libart.so (_ZN3art11ScopedCheck14CheckUtfStringEPKcb+504)
    java_vm_ext.cc:504]   native: #07 pc 000d0c05  /system/lib/libart.so (_ZN3art11ScopedCheck5CheckERNS_18ScopedObjectAccessEbPKcPNS_12JniValueTypeE+604)
    java_vm_ext.cc:504]   native: #08 pc 000c9191  /system/lib/libart.so (_ZN3art8CheckJNI12NewStringUTFEP7_JNIEnvPKc+452)
    java_vm_ext.cc:504]   native: #09 pc 0010e168  /data/app/com.frostwire.android-UlqKxBQHFq9BCV8HG8DyPQ==/lib/arm/libjlibtorrent-1.2.0.18.so (Java_com_frostwire_jlibtorrent_swig_libtorrent_1jni_generate_1fingerprint+296)
    java_vm_ext.cc:504]   native: #10 pc 0003cd51  /data/app/com.frostwire.android-UlqKxBQHFq9BCV8HG8DyPQ==/oat/arm/base.odex (Java_com_frostwire_jlibtorrent_swig_libtorrent_1jni_generate_1fingerprint__Ljava_lang_String_2IIII+144)
    java_vm_ext.cc:504]   at com.frostwire.jlibtorrent.swig.libtorrent_jni.generate_fingerprint(Native method)
    java_vm_ext.cc:504]   at com.frostwire.jlibtorrent.swig.libtorrent.generate_fingerprint(libtorrent.java:205)
    java_vm_ext.cc:504]   at com.frostwire.bittorrent.BTEngine.start(BTEngine.java:158)
    java_vm_ext.cc:504]   at com.frostwire.android.gui.MainApplication$BTEngineInitializer.run(MainApplication.java:162)
    java_vm_ext.cc:504]   at java.lang.Thread.run(Thread.java:764)

This is the C++ code from libtorrent_jni.cpp

SWIGEXPORT jstring JNICALL Java_org_libtorrent4j_swig_libtorrent_1jni_generate_1fingerprint(JNIEnv *jenv, jclass jcls, jstring jarg1, jint jarg2, jint jarg3, jint jarg4, jint jarg5) {
  jstring jresult = 0 ;
  std::string arg1 ;
  int arg2 ;
  int arg3 ;
  int arg4 ;
  int arg5 ;
  std::string result;
...
try {
      result = libtorrent::generate_fingerprint(arg1,arg2,arg3,arg4,arg5);
    } catch (std::exception& e) {
      SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, e.what());
      return 0;
    } catch (...) {
      SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "Unknown exception type");
      return 0;
    }
  }
  jresult = jenv->NewStringUTF((&result)->c_str());
gubatron commented 5 years ago

On the internet people just try avoiding returning String from C++ world, they instead return a byte[] and then our JNI wrapper should do the byte[] -> String conversion in Java land.

This previous fix should help do something similar.

Assuming that's going to be our solution, ignoring libtorrent::generate_fingerprint and redefining it as our own in swig/libtorrent.i, then the problem will be making the binaries without maven central in my macOS machine.

NOTES:

// how to return `byte_vector` (std::vector<int8_t>)
std::vector<int8_t> to_bytes() const {
                std::string s = $self->to_string();
                return std::vector<int8_t>(s.begin(), s.end());
}

In java land libtorrent.generate_fingerprint should use Vectors.byte_vector2string

public static String byte_vector2string(byte_vector v, String encoding) {