Status Update
Comments
xt...@163.com <xt...@163.com> #2
ASharedMemory can no longer be mapped in child progress
am...@google.com <am...@google.com> #3
Device build details -- Device Make, Model, Android OS Version
Preconditions to reproduce the issue.
Please provide sample project.
Provide the bin file or apk if possible to depict it through JAVA API to reproduce the issue. Also mention the steps to be followed for reproducing the issue with the given sample project or apk.
Frequency
How frequently does this issue occur? (e.g 100% of the time, 10% of the time)
Expected output as per the apk shared.
What is the expected output?
Current output as per the apk shared.
What is the current output?
Android bug report (to be captured after reproducing the issue)
For steps to capture a bug report, please refer:
Alternate method
Navigate to “Developer options”, ensure “USB debugging” is enabled, then enable “Bug report shortcut”. Capture bug report by holding the power button and selecting the “Take bug report” option.
Note: Please upload the files to google drive and share the folder to android-bugreport@google.com, then share the link here.
xt...@163.com <xt...@163.com> #4
* Are you an Android developer?" (Y/N)
Yes
* Which Android Developer Preview build are you using? See Settings > About phone > Build number (for example RPP1.200123.000).
RPB3.200720.005
* Is this a regression from Android 10 to 11?
Yes
* What device are you using? (for example, Pixel 3 XL)
Pixel 2 API 30 emulated
* What are the steps to reproduce the problem? (Please provide the minimal reproducible test case.)
* Issue Category e.g. Framework (platform), NDK (platform), Hardware (CPU, GPU, Sensor, Camera), ART (platform), Runtime Permissions etc
NDK
* What was the expected result?
mmap in child progess success
*How frequently does this issue occur? (e.g 100% of the time, 10% of the time)
100% of the time
*Expected output as per the apk shared Relevant logcat output.
Code to reproduce the bug https://drive.google.com/file/d/1RKxloyiFUzVxniUHl_pGwB1C62hLAoKj/view?usp=sharing
Devices below android 11
E/MMap (24004): parent progess create ashmem success!! E/MMap (24004): parent progess mmap success!! E/MMap (24004): fork success on main process E/MMap (24024): fork child success E/MMap (24024): child process --child progess start!!--[/data/app/com.example.testmmap-2/lib/arm//libChild-mmap.so]--[26] E/MMap (24024): child process -- map ashmem region suceess !!! Device android 11 E MMap : parent progess create ashmem success!! E MMap : parent progess mmap success!! E MMap : fork success on main process E MMap : child progess start!!--[/data/app/~~dwoB2cD-fsG1UYLML_cKLw==/com.example.testmmap-m50nMorgvlONu3i6uNFhJw==/lib/x86//libChild-mmap.so]--[54] E MMap : child process --failed to map ashmem region: Bad file descriptor
* What was the actual result?
mmap in child progess failed
xt...@163.com <xt...@163.com> #6
Devices below android 11 E/MMap (24004): RegisterNatives--result-0 E/MMap (24004): parent progess create ashmem success!! E/MMap (24004): parent progess mmap success!! E/MMap (24004): fork success on main process E/MMap (24024): fork child success E/MMap (24024): child process --child progess start!!--[/data/app/com.example.testmmap-2/lib/arm//libChild-mmap.so]--[26] E/MMap (24024): child process -- map ashmem region suceess !!!
xt...@163.com <xt...@163.com> #7
08-21 12:12:36.552 11097 11097 E MMap : RegisterNatives--result-0
08-21 12:12:36.554 11097 11097 E MMap : parent progess create ashmem success!!
08-21 12:12:36.554 11097 11097 E MMap : parent progess mmap success!!
08-21 12:12:36.565 11097 11097 E MMap : fork success on main process
08-21 12:12:36.573 11136 11136 E MMap : fork child success
08-21 12:12:36.608 11136 11136 E MMap : child process --child progess start!!--[/data/app/~~dwoB2cD-fsG1UYLML_cKLw==/com.example.testmmap-m50nMorgvlONu3i6uNFhJw==/lib/x86//libChild-mmap.so]--[54]
08-21 12:12:36.608 11136 11136 E MMap : child process --failed to map ashmem region: Bad file descriptor
xt...@163.com <xt...@163.com> #8
E/MMap (24004): RegisterNatives--result-0
E/MMap (24004): parent progess create ashmem success!!
E/MMap (24004): parent progess mmap success!!
E/MMap (24004): fork success on main process
E/MMap (24024): fork child success
E/MMap (24024): child process --child progess start!!--[/data/app/com.example.testmmap-2/lib/arm//libChild-mmap.so]--[26]
E/MMap (24024): child process -- map ashmem region suceess !!!
am...@google.com <am...@google.com> #9
So, I have added the below ones in both the files, and able to compile and run the code.
#include <errno.h>
#include <cstring>
But now the problem is that it prints the logs only from parent process:
2020-08-26 18:04:47.314 32372-32372/com.example.testmmap E/MMap: RegisterNatives--result-0
2020-08-26 18:04:47.315 32372-32372/com.example.testmmap E/MMap: parent progess create ashmem success!!
2020-08-26 18:04:47.315 32372-32372/com.example.testmmap E/MMap: parent progess mmap success!!
2020-08-26 18:04:47.322 32372-32372/com.example.testmmap E/MMap: fork success on main process
No logs from child process.
So, please let me know if I am missing something to replicate the issue.
NDK used is 21.2.6472646.
xt...@163.com <xt...@163.com> #10
I will describe the problem in detail, I need parent-child process communication. Use ASharedMemory_create() to create shared memory in the parent process and use mmap mapping. This is successful.
int fd = ASharedMemory_create( "mem", 2 * 1024 * 1024);
base = mmap(nullptr, 2 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED,
fd, 0);
Pass the fd descriptor of ASharedMemory_create to the child process through the exec() command line
pid_t child = fork();
if (child == -1) {
} else if (child == 0) {
char fdStr[16];
snprintf(fdStr, 16, "%d", fd);
execve("",1, fdStr);
} else {}
and use fd for mmap in child progress, The device below andorid11 is successful, but the bad file descriptor is prompted on the device of andorid11. This usage is not valid in andorid11 (api_level 30)? Is it allowed? Are there any restrictions, such as permissions, and how to communicate with large amounts of data if it is not allowed
// child progress main function
int main(int argc, char** argv)
{
char *arg0 = argv[0];
int _fd = strtoint(arg0);
void *base = mmap(nullptr, IPCSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0);
if (base == MAP_FAILED) {
close(_fd);
LOGE("child process --failed to map ashmem region: %s", strerror(errno));
} else {
LOGE("child process -- map ashmem region suceess !!!");
}
am...@google.com <am...@google.com> #11
en...@google.com <en...@google.com> #12
ashmem is opened O_CLOEXEC, and has been since Android Pie. specifically since this change:
amusingly, since there was no unit test added for that (nor had there been one for the previous behavior), newer code to use memfd_create(2) to implement ashmem on sufficiently new kernels doesn't set O_CLOEXEC.
so right now, whether an ashmem fd (and thus the result of ASharedMemory_create) is O_CLOEXEC or not will depend on exactly what OS version and what kernel version your code runs on. oops.
i'll fix the memfd_create() variant and add the missing test, and update the ASharedMemory_create documentation to point out this issue.
what you'll need to do though is use fcntl with F_SETFD to clear O_CLOEXEC (
xt...@163.com <xt...@163.com> #13
je...@google.com <je...@google.com> #14
Re
xt...@163.com <xt...@163.com> #15
jm...@google.com <jm...@google.com> #16
(It's a bit surprising that you don't get EINVAL without changing the flags, but I guess that was the behavior since the beginning of time, so the kernel can't fix it without breaking everything.)
en...@google.com <en...@google.com> #17
Re
, nothing currently uses the memfd_create() code path, even on newer kernels. There's a giant switch (ok, a system property) to move the entire device over to memfd, but we first have to migrate apps off of non-NDK use of ashmem, if that's even possible. comment #12
afaik, that switch says "ro.vndk.version >= 29". so last year's OS release will already be using it, not just this year's. (and it's the vendor code's API version i see being checked, not the app's target API level.)
en...@google.com <en...@google.com> #18
oh, there are two different checks! weird. okay.
en...@google.com <en...@google.com> #19
to clarify what jmgao said:
Yes, but the flag for cloexec on fcntl is FD_CLOEXEC (1), not O_CLOEXEC (0x80000), which is for open, so you're clearing the flags.
"please change your code to call F_GETFD and clear the FD_CLOEXEC bit instead, or you might have weird issues on a future OS release long after you've forgotten about this" :-)
xt...@163.com <xt...@163.com> #20
I modified the code . Thank you everyone
int flg = fcntl(fd,F_GETFD);
flg &= ~FD_CLOEXEC;
fcntl(fd,F_SETFD,flg)
je...@google.com <je...@google.com> #21
For memfd to be used the vndk version must be >= 29 and the use_memfd property must be set to true, it's currently false for all devices.
flame:/ # getprop | grep vndk [ro.product.vndk.version]: [30] [ro.vndk.version]: [30]
flame:/ # getprop | grep memfd
[sys.use_memfd]: [false]
Anyway, it does need to be fixed so that we can eventually set use_memfd to true, so thanks for fixing.
Description
Yes * What device are you using? (for example, Pixel 3 XL) Pixel 3 XL Simulator * What are the steps to reproduce the problem? (Please provide the minimal reproducible test case.)
NDK, sepolicy * What was the expected result?
Link to captured Android bug report (shared privately in Drive.)
Optional: Link to any screenshot(s) that demonstrate the issue (shared privately in Drive.)
Code snippet that fails: