2014-10-10 42 views
1

我有一個Android本機服務器應用程序編譯爲平臺特權模塊,分叉自己。該模塊還使用Android服務,如SurfaceFlinger。我需要爲每個客戶端分派一個沙盒進程。Android本機代碼fork()與IPC/Binder存在問題

叉()工作正常,父進程沒有問題。但在子過程中,當我嘗試訪問任何Android服務/資源獲取:

信號11(SIGSEGV),碼2(SEGV_ACCERR),故障地址XXXXXXXX ......
/系統/lib/libbinder.so(機器人::地塊:: ipcSetDataReference
...
/system/lib/libbinder.so(機器人:: BpBinder ::交易
NativeCrashListener(1203):找不到ProcessRecord爲pid XXXX

  • 即使在我嘗試創建新客戶端時也會發生這種情況,因此不使用任何以前創建的引用。
  • NativeCrashListener不知道我的子進程,因此,也許ActivityManager也不知道。

我看着Zygote代碼,但沒有在這裏找到有用的東西。我可能會錯過某個步驟或在子進程上調用某個函數。有任何想法嗎 ??? =)

回答

2

您無法以此方式創建新的Binder進程。

問題是,fork()只克隆當前線程,不是所有的線程。在新進程中,Binder IPC代碼會期望Binder幫助程序線程正在運行,但它們都不會。你需要fork()然後exec()

zygote進程通過調用fork()時僅運行一個線程來避免此問題。它有意將Binder代碼初始化爲子進程。 (在當前的實現中,它實際上有一些在Dalvik中運行的線程,但內部fork處理停止並重新啓動每個fork上的線程)。

+0

您是否認爲嘗試做同樣的事情是可行的?停止並重新啓動線程,或按照Digit建議的其他方法進行操作? – Bruno 2014-10-13 17:47:49

+0

您將無法停止並重新啓動進程中的所有線程。按照數字的解決方案。 – fadden 2014-10-13 22:04:46

1

fadden是正確的,fork()不能用於創建一個可靠地使用Android API的新進程。你可以用它做的最好的是exec()來運行一個獨立的命令行程序,其他的可能不會像你期望的那樣工作。

但是,該平臺支持以獨立服務進程的形式存在的沙盒進程。有關更多詳情,請參閱http://developer.android.com/guide/topics/manifest/service-element.html#isolated。實質上,這是在一個沒有權限的隨機UID下的特殊進程中運行你的服務。

爲了記錄,這是Android上的Chrome用於將「標籤」分隔爲沙盒渲染過程的內容。

+0

感謝您的鏈接,我想如果Chrome使用這可能是一個很好的方法來實現。如果我不能「克隆」Zygote的行爲,我會看看它。 – Bruno 2014-10-13 17:48:33