hello-ios
hello-ios copied to clipboard
Archiving and upload to TestFlight doesn't work
I was able to get the demo to work fine on my iphone device by launching the app from Xcode with the usb cable connected to it. But if I archive the app and upload to TestFlight, the app crashes when launched. Is there any changes that should be made to the build scripts so that when doing Build -> Archive the app will still work?
Thank you!
There's nothing that I can point out off the top of my head. If you can grab any data from a crash report, that would be super helpful in troubleshooting.
Hi josh! Thanks for getting back so quick! This is the assert that fails:
NSAssert(res, @"Failed to init virtual machine context");
Also, to generate the archive I modified your build script to use this command :
(cd hello && xcodebuild ARCHS=$(arch-xcode-name) ONLY_ACTIVE_ARCH=NO -sdk $(sdk) -scheme hello archive)
instead of
(cd hello && xcodebuild ARCHS=$(arch-xcode-name) ONLY_ACTIVE_ARCH=NO -sdk $(sdk) build)
That assert should only trigger if there was an exception in loadVM, which should be printed out. Do you see any other output? In particular, the (*e)->ExceptionDescribe(e); line should be printing the exception to stderr.
Here is my full device log right before/after the app launches and crashes
Jan 20 14:57:48 XXX-iPhone SpringBoard[57] <Error>: SecTrustEvaluate [leaf IssuerCommonName SubjectCommonName] Jan 20 14:57:48 XXX-iPhone SpringBoard[57] <Notice>: MIS: Using empty blacklist. Jan 20 14:57:48 XXX-iPhone SpringBoard[57] <Error>: SecTrustEvaluate [leaf IssuerCommonName SubjectCommonName] Jan 20 14:57:48 XXX-iPhone SpringBoard[57] <Notice>: MIS: Using empty blacklist. Jan 20 14:57:48 XXX-iPhone securityd[94] <Error>: secTaskDiagnoseEntitlements MISSING keychain entitlements: no stored taskRef found Jan 20 14:57:48 XXX-iPhone securityd[94] <Error>: secTaskDiagnoseEntitlements MISSING keychain entitlements: no stored taskRef found Jan 20 14:57:48 XXX-iPhone amfid[192] <Error>: SecTrustEvaluate [leaf IssuerCommonName SubjectCommonName] Jan 20 14:57:48 XXX-iPhone amfid[192] <Notice>: MIS: Using empty blacklist. Jan 20 14:57:48 XXX-iPhone kernel[0] <Notice>: xpcproxy[827] Container: /private/var/mobile/Containers/Data/Application/33D6C971-5EE7-499F-90F4-A8E0369F11F9 (sandbox) Jan 20 14:57:48 XXX-iPhone hello[827] <Warning>: *** Assertion failure in -[VMContext init], /Users/XXX/avian/hello-ios/hello/hello/VMContext.m:30 Jan 20 14:57:48 XXX-iPhone hello[827] <Error>: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Failed to init virtual machine context' *** First throw call stack: (0x181495900 0x180b03f80 0x1814957d0 0x181e0899c 0x1000d36e0 0x1000d1e70 0x1861a07ac 0x1862118d0 0x18621186c 0x186438c78 0x186446030 0x18144cde4 0x18144c71c 0x18144a680 0x181379680 0x182888088 0x1861f0d90 0x1000d3538 0x180f1a8b8) Jan 20 14:57:48 XXX-iPhone SpringBoard[57] <Warning>: HW kbd: Failed to set (null) as keyboard focus Jan 20 14:57:48 XXX-iPhone diagnosticd[88] <Error>: error evaluating process info - pid: 827, puniqueid: 827 Jan 20 14:57:48 XXX-iPhone com.apple.xpc.launchd1 <Notice>: Service exited due to signal: Abort trap: 6 Jan 20 14:57:48 XXX-iPhone ReportCrash[828] <Notice>: Formulating report for corpse[827] hello Jan 20 14:57:48 XXX-iPhone SpringBoard[57] <Warning>: Application 'UIKitApplication:com.xxx.yyy[0xa907]' crashed. Jan 20 14:57:48 XXX-iPhone UserEventAgent[23] <Warning>: 479786745876: id=com.xxx.yyy pid=827, state=0 Jan 20 14:57:48 XXX-iPhone ReportCrash[828] <Warning>: saved type '109_hello' report (1 of max 25) as /var/mobile/Library/Logs/CrashReporter/hello_2016-01-20-145748_XXX-iPhone.ips.beta Jan 20 14:57:49 XXX-iPhone SpringBoard[57] <Warning>: HW kbd: Failed to set (null) as keyboard focus Jan 20 14:57:52 XXX-iPhone networkd[98] <Error>: -[NETAWDManager reportStats:metricID:] AWDServerConnection newMetricContainerWithIdentifier failed for metric 2686980, server 0x145512710, not reporting:
Yeah, the exception is definitely not printed there - but I wouldn't expect it to be in a system log. We need to figure out what that exception is. I can think of two ways of getting at that: (1) get a hold of the real stderr output of that process (I think that's accessible in the devices view of xcode), or (2) modify avian to fail an NSAssert instead of printing to stderr in ExceptionDescribe (here, probably: https://github.com/ReadyTalk/avian/blob/126e3e4bacf0677f774ed3ace5aea75799881c17/src/machine.cpp#L5621).
That line should look something like NSAssert(false, @"Exception: %s", objectClass(t, e)->name()->body().begin()); (that may have to be adjusted, before it compiles).
We'll probably also want to find the exception message, which is printed a couple lines later - you may need to use a similar strategy to get that printed, if the name of the exception class doesn't make the problem obvious.
I can't compile with NSAssert in the machine.c . Should I import extra headers? I am going to try to use syslog now instead of your approach to fprintf to stderr as it does right now, to see if i can get the output.
I got the output with syslog!
Jan 20 16:35:55 XXX-iPhone hello[981] <Warning>: java/lang/NoClassDefFoundError
That likely means one of two things:
- You've somehow not included one of the classes you depend on in the build (unlikely, but possible), or
- The codeimage.o and bootimage.o are either not linked into the final binary, or don't contain all the compiled code they need to.
If it's the main class that's missing, the latter is the likely suspect.
You can turn on DebugFind and DebugStat (IIRC) by flipping them to true in src/finder.cpp to get even more information about what classes it's trying (and failing) to find where.
It's the main class that is missing. Let me try your suggestions.
Thanks so much for the help! I appreciate it a lot.
In that case, my next step would be to find the corresponding codeimage.o and dump it's symbols. You should see (obfuscated) versions of all your app's methods listed. If you're able to find some methods, but not the right ones (say, com/yyy/Main.
You might also look at the symbols for the final binary to make sure _codeimageBin, _bootimageBin, and _bootJar are defined and (importantly) visible, even in the final binary itself (i.e. not just debug symbols). Those are looked up dynamically at runtime, parsed from the arguments passed in here: https://github.com/ReadyTalk/hello-ios/blob/master/hello/hello/VMContext.m#L48.
I don't see codeimage.o and bootimage.o. Could it be codeimage-bin.o and codeimage-bin.o?
I see this line during the build process:
cp build/boot.o build/hello.o build/bootimage-bin.o build/codeimage-bin.o build/vm-objects/*.o build/resources-jar.o build/libhello
And I also see that it has a linker flag (-filelist ../build/libhello.list) to link against these files:
../build/libhello/boot.o ../build/libhello/bootimage-bin.o ../build/libhello/build_ios-arm64-bootimage_arm64-asm.o ../build/libhello/build_ios-arm64-bootimage_builtin.o ../build/libhello/build_ios-arm64-bootimage_classpath-avian.o ../build/libhello/build_ios-arm64-bootimage_codegen_compiler.o ../build/libhello/build_ios-arm64-bootimage_codegen_compiler_context.o ../build/libhello/build_ios-arm64-bootimage_codegen_compiler_event.o ../build/libhello/build_ios-arm64-bootimage_codegen_compiler_frame.o ../build/libhello/build_ios-arm64-bootimage_codegen_compiler_ir.o ../build/libhello/build_ios-arm64-bootimage_codegen_compiler_promise.o ../build/libhello/build_ios-arm64-bootimage_codegen_compiler_read.o ../build/libhello/build_ios-arm64-bootimage_codegen_compiler_regalloc.o ../build/libhello/build_ios-arm64-bootimage_codegen_compiler_resource.o ../build/libhello/build_ios-arm64-bootimage_codegen_compiler_site.o ../build/libhello/build_ios-arm64-bootimage_codegen_compiler_value.o ../build/libhello/build_ios-arm64-bootimage_codegen_runtime.o ../build/libhello/build_ios-arm64-bootimage_codegen_target_arm_assembler.o ../build/libhello/build_ios-arm64-bootimage_codegen_target_arm_block.o ../build/libhello/build_ios-arm64-bootimage_codegen_target_arm_context.o ../build/libhello/build_ios-arm64-bootimage_codegen_target_arm_fixup.o ../build/libhello/build_ios-arm64-bootimage_codegen_target_arm_multimethod.o ../build/libhello/build_ios-arm64-bootimage_codegen_target_arm_operations32.o ../build/libhello/build_ios-arm64-bootimage_codegen_target_arm_operations64.o ../build/libhello/build_ios-arm64-bootimage_codegen_targets.o ../build/libhello/build_ios-arm64-bootimage_compile-arm64-asm.o ../build/libhello/build_ios-arm64-bootimage_compile.o ../build/libhello/build_ios-arm64-bootimage_debug-util.o ../build/libhello/build_ios-arm64-bootimage_finder.o ../build/libhello/build_ios-arm64-bootimage_heap_heap.o ../build/libhello/build_ios-arm64-bootimage_heapdump.o ../build/libhello/build_ios-arm64-bootimage_heapwalk.o ../build/libhello/build_ios-arm64-bootimage_java-io.o ../build/libhello/build_ios-arm64-bootimage_java-lang.o ../build/libhello/build_ios-arm64-bootimage_java-net.o ../build/libhello/build_ios-arm64-bootimage_java-nio.o ../build/libhello/build_ios-arm64-bootimage_java-util-zip.o ../build/libhello/build_ios-arm64-bootimage_java-util.o ../build/libhello/build_ios-arm64-bootimage_jnienv.o ../build/libhello/build_ios-arm64-bootimage_machine.o ../build/libhello/build_ios-arm64-bootimage_process.o ../build/libhello/build_ios-arm64-bootimage_sockets.o ../build/libhello/build_ios-arm64-bootimage_system_posix.o ../build/libhello/build_ios-arm64-bootimage_system_posix_crash.o ../build/libhello/build_ios-arm64-bootimage_system_posix_memory.o ../build/libhello/build_ios-arm64-bootimage_system_posix_signal.o ../build/libhello/build_ios-arm64-bootimage_util.o ../build/libhello/build_ios-arm64-bootimage_util_fixed-allocator.o ../build/libhello/codeimage-bin.o ../build/libhello/hello.o ../build/libhello/resources-jar.o
Yep. I meant codeimage-bin.o and bootimage-bin.o. Do you perchance have a linker flag like -Wl,-export-dynamic specified in the build? That's what should make sure the codeimageBin, bootimageBin, and bootJar functions are exposed as dynamic symbols. It's unusual to do that for an app (usually it's just for .dll / .so / .dylib files), so it's not default.
I inspected the final app's binary that Xcode creates when I run it in the device (debug, which works) and the one that is created for the Archive (release, which crashes). I can see com.mymain.class in the former, but not in the later.
-
I couldn't find bootJar on the release binary. But I found it on the debug binary bootJar]:[resourcesJar]^@-Davian.aotonly=true^@-Dsun.reflect.inflationThreshold=2147483647
-
I found codeimageBin and bootimageBin in both release and debug binaries
�^Bmain^@�^BC^@�^BbootimageBin^@�^CcodeimageBin^@�^CresourcesJar^@�^Cvm^@�^CAvian_^@�^DJ^@
/lang/String;II)V^@_bootimageBin^@_codeima
Do you think adding -Wl,-export-dynamic to the linker could make the Archive/Release version produce the proper symbols and make it work? I will give it a try.
Thank you again.
I got it to work!
-
Strip debug symbols during copy: No
-
Strip Linked Product: No
-
Dead Code Stripping: No
-
Don't dead code stripping Inits and Terms: Yes
-
Linker flag: -Wl,-all_load
-
full path to:
-filelist /Users/xxx/avian/hello-ios/build/libhello.list
instead of -filelist ../build/libhello.list
Not sure yet which of the above fixed it. But thought about sharing. I will still go one by one and see what fixed it though.
Thanks!
Awesome!
I'm fairly sure you'll want to (and be able to) turn some of those off before going to the AppStore, primarily because those will tend to needlessly embiggen your binary.