做bionic(mips)的人犯错,sigsuspend 死锁

最近遇到一个让人晕头转向的问题:


我们工作是把 Android port到其他系统中,由于常用mips 架构的 CPU , 我们的code base 基于 mips-android (http://www.imgtec.com/mips/developers/mips-android.asp)

就是别人已经把 Android 系统改到 mips CPU 上了,能编译通过,但是要 运行起来,还需要对 INPUT, DISPLAY 视频播放,3D等进行 porting


以前我们做的 Android 系统是基于 glibc ,系统运行正常,但有 NDK apk 的不能跑起来,这是因为 NDK 的apk 有 so, 而这些 so 是基于 bionic, 现在我们做出基于 bionic 的系统,但是却出现了问题: CTS 跑不起来了,后来发现 CTS 需要调用 adb shell 执行命令, 最后调用 system/bin/sh ( 执行 system/bin/mksh), 用 gdb追踪,发现死锁在 sissuspend。

后来直接就用 adb shell am ... , 也是 mksh 有问题,但是最让人迷惑是问题不是每次都出现。又经过几天调试终于找到 rootcause


可以由于kernel 的差异, mips 可以用 128bits 的 sigmask,所以对 __NR_sigsuspend 的system call,MIPS linux 要求传指针,但 other linux只要 unsigned int data.

在做 mips bionic 的人,只针对 mips linux,没有考虑其他情况。

但做mips bionic 的人就犯错了,他们的代码把 mips 应用到 x86, arm, 直接给这些 kernel 传递指针

正是因为对 x86 linux 传递的是指针,指针的值被当做是数据,所以每次结果随机。


看一下 google 的 fixed 就知道了

https://android.googlesource.com/platform/bionic/+/abd10011a7a6066df76de7acf5eecb2cc870b0c4%5E%21/


diff --git a/libc/unistd/sigsuspend.c b/libc/unistd/sigsuspend.c
index 0db05ed..fd08631 100644
--- a/libc/unistd/sigsuspend.c
+++ b/libc/unistd/sigsuspend.c
@@ -26,12 +26,18 @@
  * SUCH DAMAGE.
  */
 #include <signal.h>
-
+#ifdef __mips__
+extern int __sigsuspend(const sigset_t *);
+#else
 extern int __sigsuspend(int, int, unsigned int);
+#endif
 
 int sigsuspend(const sigset_t *_mask)
 {
-    unsigned int    mask = (unsigned int)*_mask;
-
-	return __sigsuspend(0, 0, mask);
+#ifdef __mips__
+        return __sigsuspend(_mask);
+#else
+        unsigned int    mask = (unsigned int)*_mask;
+        return __sigsuspend(0, 0, mask);
+#endif
 }


在 Android 4.1 的还没有引入对 mips 的支持, 到4.1.2 的引入对mips 的支持,而 mips 的那个错误,也通过上面的 change 被在4.1.2 中被fix了

http://androidxref.com/4.1.2/xref/bionic/libc/unistd/sigsuspend.c

http://androidxref.com/4.2_r1/xref/bionic/libc/unistd/sigsuspend.c





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值