-
Notifications
You must be signed in to change notification settings - Fork 250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fseek crashes with sigsegv #562
Comments
Without knowing what is in your android_seek function, there is no way to understand the |
|
More functions:
|
where's the actual tombstone from the crash? have you attached gdb? this can't actually be true:
so there's some missing detail here. my guess is that you've messed up and built some of your code with _FILE_OFFSET_BITS=64 and some of it without, so different pieces disagree about whether fpos_t is 32- or 64-bit. but there's not enough information here. |
@enh Thank you for your comment. The full code is in https://github.com/soumith/torch-android I know the situation does not make much sense. But I kept other things exactly same and just changed the NDK version from 14 to 15. (I downloaded them from Google's official NDK website.) When I built with NDK 14 or below, the program ran okay. But when I built it with NDK 15 (also NDK 16 beta), the apk was built but it crashed with SIGSEGV. |
the _FILE_OFFSET_BITS stuff is new in r15 (unless you opted in to unified headers in r14):
do you have an actual full crash dump from logcat (preferably run through ndk-stack), or a tombstone from /data/tombstones? |
I searched on the mentioned project's github and |
Here I attached the log
|
oh, wait, until i saw those 64-bit pc values i hadn't realized
so it's definitely not the _FILE_OFFSET_BITS problem. the fault address looks like you have an invalid (but non-null) FILE*. i note that it's only 32 bits, so is it possible you've dropped the top 32 bits? (do you build with -Werror=pointer-to-int-cast and -Werror=int-to-pointer-cast to catch that class of error?) if you can attach a prebuilt i'll have a look in the morning... |
@enh Thanks for the comment. I also agree that
because the target file is located in the I will check the build options you mentioned ( Thanks again. Good night! |
I don't see any obvious mistakes in the code (aside from this needing to be It's failing super early in |
I am surprised that the system C runtime library uses C++ mangled function name. @jaewoosong, which device/ROM do you use? |
It's an implementation detail: the implementations of both |
@jmgao sure, it's not wrong, but this was introduced into AOSP relatively recently, so it may indicate some breaking change in fseek implementation, couldn't it? |
I thought a bit more about this scenario, and I believe strongly that the trick of android_fopen() is inherently wrong. One should not disguise AAsset* for FILE* even though both are oblique pointers while we wear NDK-colored glasses. It wasn't an oversight that android/asset_manager.h defined a separate pointer type, and did not reuse ones defined in stdio.h. Even if such substitution works sometimes, it will hit some implementation detail that will blow this substitution (essentially, @jaewoosong provides an AAsset-specific handler for seekfn, but since API 24, ::fseek() begins with some generic prologue, even before it checks whether funopen defined an override for ** __sseek**. This universal prologue assumes that the first parameter, fp, is a pointer to FILE. Actually, I believe that if this worked on Lollipop, that was by very good luck (see e.g. |
I tested the app on two devices: Samsung Galaxy S7 (Android 7.0) and Huawei Mate 9 (Android 7.0). I used default ROMs pre-installed by the manufacturers. |
It's not casting an The call to fseek happens directly on the return value of funopen: https://github.com/soumith/torch-android/blob/master/src/torchandroid.cpp#L57 |
Possible explanation: r15 turns on "unified headers" by default (https://android.googlesource.com/platform/ndk/+/master/docs/UnifiedHeaders.md). Unified headers were off by default in r14 and earlier. It appears that with unified headers, for C source files (rather than C++), the BSD-specific libc functions (like The fix is to ensure that With this C file: #include <stdio.h>
void foo() {
FILE *fp = funopen(NULL, NULL, NULL, NULL, NULL);
fseek(fp, 0, SEEK_END);
} Here are the default GCC and Clang ndk-build diagnostics from r15: GCC 4.9:
Clang:
|
@jaewoosong Can you confirm that an implicitly declared
|
Hi @rprichard , Good morning. Thank you for your comments. I tried the two things you mentioned. I tested with NDK version 16. First, I put
I hope this information be useful. Thanks again! |
When the app didn't compile, were you defining You could also define the symbol more globally using: |
Hi @rprichard , Thank you for your helpful comments. When the app didn't compile, I defined |
The general rule is: AFAICT, I wonder if Aside: you can use either of:
I suggest using the second one, which is equivalent to |
@rprichard Wow, thank you so much! I really appreciate your kind explanation. It is really helpful. I also thank @alexcohn , @enh and @jmgao for help. I learned a lot more about NDK from all of you. Now I will close this issue. Thanks! |
@jaewoosong @rprichard Another thing is I don't quite understand why @rprichard said: "AFAICT, Hope you can help me with this. |
If you have a reduced program showing the problem, we can look at that.
That's a call to android_fopen, which then calls funopen. The _BSD_SOURCE / _GNU_SOURCE macro is only required to be defined in the source file that directly calls funopen. |
Hi, sorry for my late reply. https://github.com/jalola/android_fmemopen You can have a look at the repo above. I have 4 files. I call I've tried to put |
That project doesn't have a makefile, and it doesn't compile when I add one:
See https://github.com/DanAlbert/dynamic-cast-repro for an example of a repro with a makefile. When I add a makefile, fix those errors, and define Maybe you're defining |
Thanks for your reply @rprichard You are right that I used the So if I use that flag and the API < 24, does it mean there is no way to use funopen? |
Roughly speaking, yes. Prior to API 24, there is no funopen on 32-bit targets that works with a 64-bit off_t seek function. There is still a funopen function but it uses a 32-bit off_t. After API 24, when |
thanks a lot for your explanation @rprichard. It helps a lot and It is clear now. Luckily, I changed the logic not to use |
See: - http://www.50ply.com/blog/2013/01/19/loading-compressed-android-assets-with-file-pointer/ - https://github.com/netguy204/gambit-game-lib/ - https://github.com/netguy204/gambit-game-lib/blob/dk94/android_fopen.h - https://github.com/netguy204/gambit-game-lib/blob/dk94/android_fopen.c - android/ndk#562
Description
Ndk version 11, 12, 13 and 14 can run the following jni code without problem. But Ndk version 15 (15, 15b, 15c) makes sigsegv error.
Environment Details
Not all of these will be relevant to every bug, but please provide as much
information as you can.
The text was updated successfully, but these errors were encountered: