Android 不支持 SYSV IPC (SYSV IPC)
16lz
2021-01-23
Android 不支持 System V IPC, 即下面头文件提供的功能:
<sys/sem.h> /* SysV semaphores*/<sys/shm.h> /* SysV shared memory segments */
<sys/msg.h> /* SysV message queues */
<sys/ipc.h> /* General IPC definitions */
Android不支持SYSV IPC的原因: 会导致全局的内核资源泄漏。例如,当一个有bug的或恶意程序退出后或普通程序被强行杀死后,没有办法自动释放Sysv信号量(在内核中分配的)。然而Android系统经常自动杀死进程,给新的进程腾出空间(Android的重要机制)。这意味着,即使程序没有bug也不是恶意代码,随时间的推移,进程经常被杀死然后重新创建,内核中用于实现SysV IPC的全局表格会被填满。这个时候,就会发生奇怪的事件并导致使用SysV IPC的程序无法运行,只有重启系统。而且考虑到可能有人会故意写恶意程序,所以Android选择不支持SysV IPC。下面提供一个导致内核资源泄漏的程序(需在Linux系统上运行)作为例证:
#include <sys/sem.h>#include <sys/wait.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#define NUM_SEMAPHORES 32#define MAX_FAILS 10int main(void){ int counter = 0; int fails = 0; if (counter == IPC_PRIVATE) counter++; printf( "%d (NUM_SEMAPHORES=%d)\n", counter, NUM_SEMAPHORES); for (;;) { int ret = fork(); int status; if (ret < 0) { perror("fork:"); break; } if (ret == 0) { /* in the child */ ret = semget( (key_t)counter, NUM_SEMAPHORES, IPC_CREAT ); if (ret < 0) { return errno; } return 0; } else { /* in the parent */ ret = wait(&status); if (ret < 0) { perror("waitpid:"); break; } if (status != 0) { status = WEXITSTATUS(status); fprintf(stderr, "child %d FAIL at counter=%d: %d\n", ret, counter, status); if (++fails >= MAX_FAILS) break; } } counter++; if ((counter % 1000) == 0) { printf("%d\n", counter); } if (counter == IPC_PRIVATE) counter++; } return 0;}
如果上面的程序在当今典型的Linux发行版上编译运行,你会发现该程序将很快地用不同的key_t值占满内核表格,系统将会发生奇怪的事件。但某些Linux系统不一定有该问题(可运行 “ipcs -u” 命令查看内核资源表及资源分配情况)。根据我们的经验,在执行上面程序之后,任何一个程序仅仅调用了 strerror() 就会崩溃。USB子系统不断报告奇怪的错误信息到系统终端等。
更多相关文章
- Android多种方法获取系统时间
- 关于android的屏幕常亮和完全关闭程序
- cm-14.1 Android系统启动过程分析(四)-Launcher 启动过程
- 20172323 2017-2018-2《程序设计与数据结构》第十一周学习总结
- Android5.1系统通过包名给应用开放系统权限的方法
- Android 在init.rc启动一个c++程序