早些时候Tim Cook致信员工,宣布了iOS高级副总裁Scott Forstall将于明年离职,而Bob Mansfield将会续任2年等消息。这里是邮件的全文。
我们正处于苹果历史上最多创新和新产品的时期。这些我们已经在9和10月份介绍过的惊人的产品——iPhone 5,iOS 6,iPad mini,iPad,iMac,MacBook Pro,iPod touch,iPod nano和很多的应用程序——已经且只能在苹果才能创造出来,这是我们不懈专注整合世界一流软硬件和服务的直接结果。
今天,我宣布一些更激励我们世界级的软硬件和服务团队合作伙伴们的改变。作为变化的一部分,Jony Ive,Bob Mansfield,Eddy Cue和Craig Federighi将担负起更多的责任。我还宣布Scott Forstall将于明年离开苹果,并且在过渡期会以顾问的方式继续为苹果效力。我要感谢Scott在苹果的职业生涯中为苹果做出的诸多贡献。
根据Jony长期作为工业设计领导者的角色,他将领导全公司人类界面(Human Interface)的方向。Jony拥有令人难以置信的设计美学,以及让我们的产品外表下超越10年的背后驱动力。面对我们的许多产品是我们的软件,而 Jony的技能将会拉大我们与竞争对手的差距。
Eddy Cue将会承担Siri和地图的额外责任。这与我们所有的在线服务在同一个小组。Eddy和他的组织已经见证了很多的成功,比如iTunes Store,App Store,iBook store和iCloud。他们有一个优秀的记录建立和加强我们的在线服务,满足并超越客户的高期望值。
Craig Federighi将同时领导iOS和OS X。我们拥有地球上最先进的移动和桌面操作系统,将两个OS团队整合到一起,将使我们在两个平台上更容易地提供最好的技术和创新的用户体验。Craig最近领导了非常成功的Mountain Lion的发布。
Bob Mansfield将领导一个新的技术组织,它把全公司所有的无线团队汇集到了同一个组织,使我们在这一领域的创新更上一层楼。这个组织还将包括我们所有 的半导体团队,他们有一些雄心勃勃的计划。说到这里,我会很高兴的告诉你,Bob将会留在苹果额外工作2年。Bob已经领导了我们一些最具挑战性的工程项 目很多年。
此外,John Browett已经离职,我们寻找一位新的零售业主管的工作正在进行中。与此同时,零售团队将直接向我报告。我们在商店和区域层面有一个令人难以置信的强 大的网络零售的领导人,他们将继续他们所做的出色的工作,在过去的十年里,在零售业革命与独特的、创新的服务和专注于客户方面是首屈一指的。这非凡的团队 用心使我们的客户满意。他们会得到我们的敬重、钦佩和永恒的支持。
请与我一起祝贺大家的新角色。
我要感谢所有人的努力地工作,这使苹果能继续制造世界上最好的产品并取悦我们的客户。我任然认为,苹果拥有这个星球上最优秀、最有创意的人们,与你们共事是我莫大的荣幸和激励。
在JB上,有时候会发现,以前在ICS上跑的好好的程序,在JB上一运行,就发生 SEGV_ACCERR 问题,比如上一篇文章说到的,HAL模块的HMI中修改dso会造成段错误。
出错时的debuggerd输出,大约有如下信息:
fault addr 3cde4bf4 3cde2000-3cde5000 r--p 00050000 b3:01 595 /system/lib/libwilhelm.so 0x3cde4bf4 <IObject_Itf>: 0x3cdbf5ac 0x3cdbf3b4 0x3cdbed64 0x3cdbf1d4 0x3cde4c04 <IObject_Itf+16>: 0x3cdbeca8 0x3cdbf150 0x3cdbf8a0 0x3cdbec54 0x3cde4c14 <IObject_Itf+32>: 0x3cdbec00 0x3cdbebac
这里可以看到,linker将这一段地址map成只读的了,但代码是想要写它,这就造成访问错误而死掉。
为何ICS上是好好的,但到JB上就不行了呢?
从错误的现象和maps来看,这应该是jellybean对linker有了新的改动导致的。到bionic上查看一下linker的更新log:
$ git log linker/linker.c
找到如下的更新信息:
commit 9ec0f03a0d0b17bbb94ac0b9fef6add28a133c3a Author: Nick Kralevich <nnk@google.com> Date: Tue Feb 28 10:40:00 2012 -0800 Add relro support Add support for PT_GNU_RELRO. This allows the static linker to indicate that certain regions of memory should be marked as "read-only" after dynamic linking is complete. See: * http://www.akkadia.org/drepper/nonselsec.pdf (section 6) * http://tk-blog.blogspot.com/2009/02/relro-not-so-well-known-memory.html Note that this change has no effect on Android right now, because we don't compile our code with relro enabled. Change-Id: I6541f8775367e8558b4388f7d105b1ae6e8f046b
正是google加入了relro的支持,导致了这些问题(google说没影响,实际上还是看到了)。具体原因这里有说明,主要是安全性考量。可以看下链接中的文章的详细说明。
解决方法也很简单,一是将它revert掉就好了,或者是修改源代码,将要修改的const全局变量的const都给去掉。
package innoview.itouchviewcivil.util; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; /** * @declaration 自定义弹出对话框 * @author nilbounds@gmail.com * 2012-10-17 下午10:27:42 */ public class MyTipDialog { public interface IDialogMethod{ public void sure(); // public void cancel(); } public static AlertDialog getMyDialog(Context context, String title, String msg, String okBtnText, String cancelBtnText, final IDialogMethod md){ AlertDialog dlg = getMyDialog(context, msg, okBtnText, cancelBtnText, md); dlg.setTitle(title); return dlg; } public static AlertDialog getMyDialog(Context context, String msg, String okBtnText, String cancelBtnText, final IDialogMethod md){ AlertDialog dlg = new AlertDialog.Builder(context) .setMessage(msg) .setPositiveButton(okBtnText, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog,int which) { md.sure(); dialog.dismiss(); } }) .setNegativeButton(cancelBtnText, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }).create(); return dlg; } public static void popDialog(Context context, String msg, String okBtnText, String cancelBtnText, final IDialogMethod md){ getMyDialog(context, msg, okBtnText, cancelBtnText, md).show(); } public static void popDialog(Context context, String msg, int okBtnResID, int cancelBtnResID, final IDialogMethod md){ popDialog(context, msg, context.getResources().getString(okBtnResID), context.getResources().getString(cancelBtnResID), md); } public static void popDialog(Context context, int msgID, int okBtnResID, int cancelBtnResID, final IDialogMethod md){ popDialog(context, context.getResources().getString(msgID), context.getResources().getString(okBtnResID), context .getResources().getString(cancelBtnResID), md); } public static void popDialog(Context context, String title, String msg, int okBtnResID, int cancelBtnResID, final IDialogMethod md){ popDialog(context, title, msg, context.getResources() .getString(okBtnResID), context.getResources().getString(cancelBtnResID), md); } public static void popDialog(Context context, String title, int msgID, int okBtnResID, int cancelBtnResID, final IDialogMethod md){ popDialog(context, title, context.getResources().getString(msgID), context.getResources().getString(okBtnResID), context .getResources().getString(cancelBtnResID), md); } public static void popDialog(Context context, String title, String msg, String okBtnText, String cancelBtnText, final IDialogMethod md){ getMyDialog(context, title, msg, okBtnText, cancelBtnText, md).show(); } }