简体   繁体   English

Android本机代码fork()与IPC /活页夹有关

[英]Android native code fork() has issues with IPC/Binder

I have an Android native Server app compiled as Platform privileged module that forks itself. 我有一个Android本机服务器应用程序编译为分叉自身的平台特权模块。 This module also uses Android services, like SurfaceFlinger. 此模块还使用Android服务,例如SurfaceFlinger。 I need to fork to have one sandboxed process per client. 我需要让每个客户端拥有一个沙盒进程。

Fork() works fine and the parent process has no issue at all. Fork()可以正常工作,并且父进程完全没有问题。 But in the child process, when I try to access any Android service/resource I get: 但是在子进程中,当我尝试访问任何Android服务/资源时,我得到:

signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr xxxxxxxx ... ... 信号11(SIGSEGV),代码2(SEGV_ACCERR),故障加法器xxxxxxxx ... ...
/system/lib/libbinder.so (android::Parcel::ipcSetDataReference /system/lib/libbinder.so(android :: Parcel :: ipcSetDataReference
... ...
/system/lib/libbinder.so (android::BpBinder::transact /system/lib/libbinder.so(android :: BpBinder :: transact
NativeCrashListener( 1203): Couldn't find ProcessRecord for pid XXXX NativeCrashListener(1203):找不到pid XXXX的ProcessRecord

  • This happens even when I try to create a NEW client, thus, not using any previous created reference. 即使当我尝试创建一个新客户端时,也会发生这种情况,因此,不使用任何先前创建的引用。
  • NativeCrashListener doesn't know about my child process, thus, maybe ActivityManager also doesn't. NativeCrashListener不了解我的子进程,因此,也许ActivityManager也不知道。

I looked at the Zygote code but have not found anything helpful there. 我查看了Zygote代码,但没有找到任何有用的方法。 I'm probably missing some step or calling some function on the child process. 我可能缺少某些步骤或在子进程上调用了某些函数。 Any ideas ??? 有任何想法吗 ??? =) =)

You can't create a new Binder process this way. 您不能以这种方式创建新的Binder流程。

The problem is that fork() only clones the current thread, not all threads. 问题在于fork()仅克隆当前线程,而不克隆所有线程。 In the new process, the Binder IPC code will expect the Binder helper threads to be running, but none of them will be. 在新的过程中,Binder IPC代码将期望Binder帮助程序线程正在运行,但是没有一个将在运行。 You need to fork() and then exec() . 您需要fork()然后是exec()

The zygote process avoids this issue by having only one thread running when fork() is called. zygote进程通过在调用fork()时仅运行一个线程来避免此问题。 It deliberately defers initialization of the Binder code to the child process. 它故意将Binder代码的初始化推迟到子进程。 (In the current implementation, it actually has a couple of threads running in Dalvik, but the internal fork handling stops and restarts those threads on every fork). (在当前实现中,它实际上有几个在Dalvik中运行的线程,但是内部fork处理会停止并在每个fork上重新启动那些线程)。

fadden is right, fork() cannot be used to create a new process that uses Android APIs reliably. fadden是正确的,不能使用fork()创建可靠使用Android API的新进程。 The best you can do with it is exec() to run a standalone command-line program, everything else is likely to not work as you expect. 最好用exec()来运行一个独立的命令行程序,否则所有其他操作都可能无法按预期工作。

However, the platform supports sandboxed processes, in the form of isolated service processes. 但是,该平台以隔离服务流程的形式支持沙盒流程。 See http://developer.android.com/guide/topics/manifest/service-element.html#isolated for more details. 有关更多详细信息,请参见http://developer.android.com/guide/topics/manifest/service-element.html#isolated In essence, this runs your service in a special process under a random UID that has no permissions. 本质上,这将在没有权限的随机UID下以特殊过程运行您的服务。

For the record, this is what Chrome on Android uses to isolate 'tabs' into sandboxed 'renderer processes'. 记录下来,这就是Android上的Chrome用来将“标签”隔离到沙盒“渲染器进程”中的功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM