ReadyTalk / avian

[INACTIVE] Avian is a lightweight virtual machine and class library designed to provide a useful subset of Java's features, suitable for building self-contained applications.
https://readytalk.github.io/avian/
Other
1.22k stars 172 forks source link

GC crashes after Class#getResourceAsStream() #443

Closed tarotanaka0 closed 9 years ago

tarotanaka0 commented 9 years ago

GC crashes after calling Class#getResourceAsStream() on ios-arm-bootimage-android build. (Does not happen with avian classpath)

Test code: (modifying hello-ios)

diff --git a/src/Hello.java b/src/Hello.java
index 71fb67c..b22d15f 100644
--- a/src/Hello.java
+++ b/src/Hello.java
@@ -9,6 +9,10 @@ public class Hello {
     this.peer = peer;

     InputStream in = getClass().getResourceAsStream("/hello.properties");
+      for (int j = 0; j < 1000; j++) {
+          System.err.println(j);
+          byte[] b = new byte[1024 * 1024];
+      }
     try {
       Properties props = new Properties();

Backtrace (when j==18):

* thread #1: tid = 0xdb258, 0x001cd544 hello`(anonymous namespace)::HeapClient::isFixed(void*) [inlined] vm::objectFixed(vm::Thread*, vm::GcObject*) at machine.h:1952, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x79e6058)
  * frame #0: 0x001cd544 hello`(anonymous namespace)::HeapClient::isFixed(void*) [inlined] vm::objectFixed(vm::Thread*, vm::GcObject*) at machine.h:1952
    frame #1: 0x001cd544 hello`(anonymous namespace)::HeapClient::isFixed(this=0x14d4a360, p=0x079e6058) at machine.cpp:3368
    frame #2: 0x00100a18 hello`(anonymous namespace)::local::update((anonymous namespace)::local::Context*, void**, void*, unsigned int, bool*) + 16 at heap.cpp:1132
    frame #3: 0x00100a08 hello`(anonymous namespace)::local::update((anonymous namespace)::local::Context*, void**, void*, unsigned int, bool*) [inlined] (anonymous namespace)::local::update2(c=0x14d4a864)::local::Context*, void*, bool*) + 38 at heap.cpp:1164
    frame #4: 0x001009e2 hello`(anonymous namespace)::local::update(c=0x14d4a864, p=0x01f94460, target=0x01f94458, offset=2, needsVisit=0x02f922fc)::local::Context*, void**, void*, unsigned int, bool*) + 34 at heap.cpp:1257
    frame #5: 0x001008ac hello`(anonymous namespace)::local::collect(c=0x14d4a864, p=0x01f94460, target=<unavailable>, offset=<unavailable>)::local::Context*, void**, void*, unsigned int) + 44 at heap.cpp:1381
    frame #6: 0x000ff536 hello`(anonymous namespace)::local::MyHeap::collect(vm::Heap::CollectionType, unsigned int, int) [inlined] (anonymous namespace)::local::collect(c=<unavailable>)::local::Context*, void*, unsigned int) + 906 at heap.cpp:1578
    frame #7: 0x000ff52a hello`(anonymous namespace)::local::MyHeap::collect(vm::Heap::CollectionType, unsigned int, int) + 134 at heap.cpp:1618
    frame #8: 0x000ff4a4 hello`(anonymous namespace)::local::MyHeap::collect(vm::Heap::CollectionType, unsigned int, int) + 222 at heap.cpp:1739
    frame #9: 0x000ff3c6 hello`(anonymous namespace)::local::MyHeap::collect(vm::Heap::CollectionType, unsigned int, int) [inlined] (anonymous namespace)::local::collect(c=<unavailable>)::local::Context*) + 464 at heap.cpp:1819
    frame #10: 0x000ff1f6 hello`(anonymous namespace)::local::MyHeap::collect(this=<unavailable>, type=<unavailable>, incomingFootprint=<unavailable>, pendingAllocation=<unavailable>) + 74 at heap.cpp:1989
    frame #11: 0x001bffc0 hello`(anonymous namespace)::doCollect(t=0x1515e200, type=MinorCollection, pendingAllocation=1048600) + 104 at machine.cpp:3456
    frame #12: 0x001bff14 hello`vm::collect(t=0x1515e200, type=MajorCollection, pendingAllocation=1048600) + 92 at machine.cpp:4315
    frame #13: 0x001bfde0 hello`vm::allocate3(t=0x1515e200, allocator=0x14d4a860, type=FixedAllocation, sizeInBytes=1048584, objectMask=false) + 532 at machine.cpp:4259
    frame #14: 0x001c0620 hello`vm::makeByteArray(vm::Thread*, unsigned long) [inlined] vm::allocate2(t=0x1515e200, sizeInBytes=<unavailable>, objectMask=false) + 76 at machine.cpp:4175
    frame #15: 0x001c0612 hello`vm::makeByteArray(vm::Thread*, unsigned long) at machine.h:1639
    frame #16: 0x001c0612 hello`vm::makeByteArray(t=0x1515e200, length=1048576) + 62 at type-constructors.cpp:1206
    frame #17: 0x000e2cce hello`(anonymous namespace)::local::makeBlankArray(t=<unavailable>, type=<unavailable>, length=<unavailable>)::local::MyThread*, unsigned int, int) + 74 at compile.cpp:2563
    frame #18: 0x001fd364 hello`Hello.<init>(J)V + 280
    frame #19: 0x000e1cb4 hello`.LvmInvoke_argumentTest + 16
  frame #20: 0x01d8450f hello`
joshuawarner32 commented 9 years ago

Can you provide build instructions? Did you use the new avian-pack project, or the old (manual) android build instructions? OS and compiler versions you used would also be helpful.

I tried getting avian-pack compiling for iOS, but I'm seeing some unrelated build issues. (EDIT: filed here: https://github.com/bigfatbrowncat/avian-pack/issues/2)

tarotanaka0 commented 9 years ago

I'm using avian-pack project tree with manual build steps. (OS X 10.10.3, Xcode 6.3.2, iOS SDK 8.3, iPhone6, iOS 8.3)

hello.patch :

--- hello-ios/src/Hello.java
+++ hello-ios/src/Hello.java
@@ -9,6 +9,10 @@ public class Hello {
     this.peer = peer;

     InputStream in = getClass().getResourceAsStream("/hello.properties");
+      for (int j = 0; j < 1000; j++) {
+          System.err.println(j);
+          byte[] b = new byte[1024 * 1024];
+      }
     try {
       Properties props = new Properties();
       props.load(in);
--- hello-ios/hello/hello.xcodeproj/project.pbxproj
+++ hello-ios/hello/hello.xcodeproj/project.pbxproj
@@ -289,6 +289,12 @@
                GCC_PREFIX_HEADER = "hello/hello-Prefix.pch";
                INFOPLIST_FILE = "hello/hello-Info.plist";
                IPHONEOS_DEPLOYMENT_TARGET = 4.3;
+               OTHER_LDFLAGS = (
+                   "-filelist",
+                   ../build/libhello.list,
+                   "-lz",
+                   "-lc++",
+               );
                PRODUCT_NAME = "$(TARGET_NAME)";
                WRAPPER_EXTENSION = app;
            };
@@ -302,6 +308,12 @@
                GCC_PREFIX_HEADER = "hello/hello-Prefix.pch";
                INFOPLIST_FILE = "hello/hello-Info.plist";
                IPHONEOS_DEPLOYMENT_TARGET = 4.3;
+               OTHER_LDFLAGS = (
+                   "-filelist",
+                   ../build/libhello.list,
+                   "-lz",
+                   "-lc++",
+               );
                PRODUCT_NAME = "$(TARGET_NAME)";
                WRAPPER_EXTENSION = app;
            };
--- hello-ios/makefile
+++ hello-ios/makefile
@@ -31,7 +31,9 @@ developer-dir := $(shell if test -d /Developer/Platforms/$(target).platform/Deve
 sdk-dir = $(developer-dir)/Platforms/$(target).platform/Developer/SDKs

 ios-version := $(shell \
-       if test -d $(sdk-dir)/$(target)8.2.sdk; then echo 8.2; \
+       if test -d $(sdk-dir)/$(target)8.4.sdk; then echo 8.4; \
+   elif test -d $(sdk-dir)/$(target)8.3.sdk; then echo 8.3; \
+   elif test -d $(sdk-dir)/$(target)8.2.sdk; then echo 8.2; \
    elif test -d $(sdk-dir)/$(target)8.1.sdk; then echo 8.1; \
    elif test -d $(sdk-dir)/$(target)8.0.sdk; then echo 8.0; \
    elif test -d $(sdk-dir)/$(target)7.1.sdk; then echo 7.1; \
--- android/external/conscrypt/src/main/native/org_conscrypt_NativeCrypto.cpp
+++ android/external/conscrypt/src/main/native/org_conscrypt_NativeCrypto.cpp
@@ -349,7 +349,7 @@ typedef UniquePtr<STACK_OF(GENERAL_NAME), sk_GENERAL_NAME_Delete> Unique_sk_GENE
  * without triggering a warning by not using the result of release().
  */
 #define OWNERSHIP_TRANSFERRED(obj) \
-    do { typeof (obj.release()) _dummy __attribute__((unused)) = obj.release(); } while(0)
+    do { __typeof__ (obj.release()) _dummy __attribute__((unused)) = obj.release(); } while(0)

 /**
  * Frees the SSL error state.
--- android/system/core/include/utils/Compat.h
+++ android/system/core/include/utils/Compat.h
@@ -55,7 +55,7 @@ static inline ssize_t pread64(int fd, void* buf, size_t nbytes, off64_t offset)
 #ifndef TEMP_FAILURE_RETRY
 /* Used to retry syscalls that can return EINTR. */
 #define TEMP_FAILURE_RETRY(exp) ({         \
-    typeof (exp) _rc;                      \
+    __typeof__ (exp) _rc;                      \
     do {                                   \
         _rc = (exp);                       \
     } while (_rc == -1 && errno == EINTR); \
--- android/libnativehelper/include/nativehelper/JNIHelp.h
+++ android/libnativehelper/include/nativehelper/JNIHelp.h
@@ -182,7 +182,7 @@ inline void jniLogException(JNIEnv* env, int priority, const char* tag, jthrowab
 #ifndef TEMP_FAILURE_RETRY
 /* Used to retry syscalls that can return EINTR. */
 #define TEMP_FAILURE_RETRY(exp) ({         \
-    typeof (exp) _rc;                      \
+    __typeof__ (exp) _rc;                      \
     do {                                   \
         _rc = (exp);                       \
     } while (_rc == -1 && errno == EINTR); \

Instruction :


git clone https://github.com/bigfatbrowncat/avian-pack.git
cd avian-pack
make git-refresh
(cd avian && git checkout cp_fix2)
git clone https://github.com/ReadyTalk/hello-ios.git

patch -p0 < ../hello.patch

cp android/external/fdlibm/makefile.in android/external/fdlibm/Makefile.in 
(cd android/openssl-upstream && \
(for x in ../external/openssl/patches/*.patch; \
    do patch -p1 < $x; \
done))

mkdir -p icu4c_host
(cd icu4c_host/ && ../android/external/icu4c/configure && make -j8)

export SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk
export ARCH=armv7

(cd android/external/icu4c/ && \
    CFLAGS="-fPIC -arch ${ARCH} -pipe -isysroot ${SDKROOT} -miphoneos-version-min=7.0" \
    CXXFLAGS="-fPIC -arch ${ARCH} -pipe -isysroot ${SDKROOT} -miphoneos-version-min=7.0" \
    CPPFLAGS="-arch ${ARCH} -isysroot ${SDKROOT} -I$(pwd)/tools/tzcode" \
    ./configure --host=${ARCH}-apple-darwin \
    --enable-static --disable-shared -with-cross-build=$(pwd)/../../../icu4c_host/ && \
    make -j8)
(cd android/external/expat/ && \
    CFLAGS="-fPIC -arch ${ARCH} -pipe -isysroot ${SDKROOT} -miphoneos-version-min=7.0" \
    CXXFLAGS="-fPIC -arch ${ARCH} -pipe -isysroot ${SDKROOT} -miphoneos-version-min=7.0" \
    CPPFLAGS="-arch ${ARCH} -isysroot ${SDKROOT}" \
    ./configure --host=${ARCH}-apple-darwin --enable-static --disable-shared && \
    make)
(cd android/external/fdlibm/ && \
    CFLAGS="-fPIC -arch ${ARCH} -pipe -isysroot ${SDKROOT} -miphoneos-version-min=7.0" \
    CXXFLAGS="-fPIC -arch ${ARCH} -pipe -isysroot ${SDKROOT} -miphoneos-version-min=7.0" \
    CPPFLAGS="-arch ${ARCH} -isysroot ${SDKROOT}" \
    bash configure --host=${ARCH}-apple-darwin --enable-static --disable-shared && \
    make)
(cd android/openssl-upstream/ && \
    CC="gcc -fPIC -arch ${ARCH} -pipe -isysroot ${SDKROOT} -miphoneos-version-min=7.0" \
    ./Configure BSD-generic32 && \
    make)

With new shell :

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/
(cd hello-ios && make arch=arm android=$(pwd)/../android run-proguard=false)

Open hello-ios/hello/hello.xcodeproj with Xcode and Run, you will see EXC_BAD_ACCESS.

dicej commented 9 years ago

I don't have access to a real iOS device, but I just now managed to reproduce this in the simulator. I had to work around an assertion error to get that far, though; here's the patch I used:

diff --git a/luni/src/main/java/java/lang/System.java b/luni/src/main/java/java/lang/System.java
index 6cc77e6..0a50db6 100644
--- a/luni/src/main/java/java/lang/System.java
+++ b/luni/src/main/java/java/lang/System.java
@@ -759,7 +759,9 @@ public final class System {
             p.put("user.home", passwd.pw_dir);
             p.put("user.name", passwd.pw_name);
         } catch (ErrnoException exception) {
-            throw new AssertionError(exception);
+            p.put("user.home", "/tmp");
+            p.put("user.name", "unknown");
+            //throw new AssertionError(exception);
         }

         StructUtsname info = Libcore.os.uname();

I'll see if I can debug it from here.

tarotanaka0 commented 9 years ago

I've confirmed the fix on iOS device. Thank you.