iOS在CoreFoundation中的CFStringGetLength出现崩溃问题

6
我遇到了一个崩溃问题,看起来像是苹果处理MKMapView的"goToDefaultLocation"消息的方式中存在一个bug。该消息调用"[ALCityManager localeWithCode:]",它又调用"[NSLocale componentsFromLocaleIdentifier:]",接着调用"CFLocaleCreateComponentsFromLocaleIdentifier",最后调用"CFStringGetLength",导致了崩溃。
如果这是我的代码引起的问题,请帮我指出如何修复。如果实际上这是苹果代码中的一个bug(不太可能?),请帮我找到解决方法。
以下是崩溃日志:
事件标识符:84198BB6-45BD-493B-955F-75CCB5246DDD 崩溃报告键:7dbf53bf1f1a3635d7c3c49e726dedc609ed9f3a 硬件型号:iPhone3,1 进程:MyApp [340] 路径:/var/mobile/Applications/DCE9A5A1-8E24-4D4F-A1ED-9855C6CA1742/MyApp.app/MyApp 标识符:MyApp 版本:??? (???) 代码类型:ARM (本机) 父进程:launchd [1]
日期/时间:2011-03-25 10:36:06.382 -0700 操作系统版本:iPhone OS 4.3 (8F190) 报告版本:104
异常类型:EXC_BAD_ACCESS (SIGBUS) 异常代码:KERN_PROTECTION_FAILURE at 0x00000000 崩溃的线程:0
线程0名称:调度队列:com.apple.main-thread 线程0崩溃: 0 CoreFoundation 0x00009a66 CFStringGetLength +6 1 CoreFoundation 0x0002f994 CFLocaleCreateComponentsFromLocaleIdentifier +60 2 CoreFoundation 0x000483b8 +[NSLocale componentsFromLocaleIdentifier:] +12 3 AppSupport 0x00016eee -[ALCityManager localeWithCode:] +130 4 MapKit 0x00038488 -[MKMapView goToDefaultLocation] +80 5 Foundation 0x000907c6 __NSFireTimer +130 6 CoreFoundation 0x00075a40 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ +8 7 CoreFoundation 0x00077ec4 __CFRunLoopDoTimer +844 8 CoreFoundation 0x0007883e __CFRunLoopRun +1082 9 CoreFoundation 0x00008ebc CFRunLoopRunSpecific +224 10 CoreFoundation 0x00008dc4 CFRunLoopRunInMode +52 11 GraphicsServices 0x00004418 GSEventRunModal +108 12 GraphicsServices 0x000044c4 GSEventRun +56 13 UIKit 0x0002ed62 -[UIApplication _run] +398 14 UIKit 0x0002c800 UIApplicationMain +664 15 MyApp 0x000023f0 main (main.m:34) 16 MyApp 0x00002370 start +44

1
除非你公开你的代码,否则很难知道代码中是否存在错误。goToDefaultLocation不是MKMapView的一个文档公开方法。当程序崩溃时,你在代码中实际做了什么? - CharlieMezak
无 -> 崩溃发生在启动时。 - fatfreddyscat
2个回答

2

我收到了完全相同的崩溃报告,仅限于iOS 4.3 / 4.3.1和iPhone 3GS/4(armv7)。

我认为这是一个苹果的错误,iOS4.3在MapKit方面还存在其他丑陋的回归问题。 (例如MKReverseGeocoder过早释放崩溃...)

  1. 一个简单的解决方法是覆盖-[MKMapView goToDefaultLocation],但风险是被苹果拒绝,因为它是一个私有API... (因为bug而被拒绝...我知道...人们很刻薄)

  2. 另一种解决方案是分析(反向...)CFLocaleCreateComponentsFromLocaleIdentifiercomponentsFromLocaleIdentifier:以及[ALCityManager localeWithCode:]来理解它如何崩溃,被调用时带有nil的语言环境标识符,并可能在应用程序中以编程方式修复应用程序语言环境,因为看起来错误来自于从设备设置确定用户位置的语言环境(或更糟的是,来自城市/地理位置)... 或者至少警告用户其语言环境设置可能会引起麻烦... 由于我无法重现该错误,所以我无法进行某些操作。


很高兴听到这个消息,请确保:1. 在运行时检查其区域设置,可能是 - [NSLocale currentLocale] 2. 使用 gdb 尝试 fb -[ALCityManager localeWithCode:] 和它的 朋友 在崩溃之前在堆栈跟踪中设置断点,并分析寄存器等... 如果您能阅读一些 ARM 汇编代码,也许可以逐步进行。我希望您能找到解决方法并分享您的经验! - Vincent Guerci
1
PS:解决方法是将语言环境设置为英语以外的其他语言,然后再将其设置回来。顺便说一下,我们正在等待修复。 - fatfreddyscat
1
我不知道如何“检测”它。这种情况非常罕见。如果有人报告启动时出现奇怪的崩溃,请发布免责声明,提及已知的苹果崩溃,并引导他们前往设置->通用->国际->地区格式,将其设置为其他选项,然后再设置回来。 - fatfreddyscat
我明白了,没有简单的解决方法,也没有办法轻易地检测/预防错误...只有少数人关心...好吧...我不喜欢这个,但是让我们等待新的iOS版本!...再次感谢您的回复。 - Vincent Guerci
我只希望我的发现能够帮助到某个人,因为这真的很痛苦。 - fatfreddyscat
显示剩余10条评论

1

你的异常代码是EXC_BAD_ACCESS。这通常是一个内存管理错误(即某些代码尝试访问已经被释放/解除分配的对象)。

虽然有可能是苹果/框架代码中的错误,但这种情况非常罕见。更有可能的是,在你的代码中,你要么过度释放了某些东西,要么保留了一个自动释放的对象实例,或者以其他方式访问了不应该访问的内容。

考虑到崩溃发生在MapKit中,我建议你查看与地图相关的代码,寻找可能导致此崩溃的原因。请注意,MapKit可能会有点暴躁;我曾经遇到过一些崩溃情况,比如当用户关闭位置服务时,尝试访问LocationManager的当前位置。我希望这种情况会失败(例如通过返回一个nil位置),但不会导致应用程序崩溃。


是的,我知道'EXC_BAD_ACCESS'是什么,我已经尝试查看所有Mapkit引用,例如错误释放等。问题实际上在于,在数百个设备中,我们只在2个设备上看到了这个崩溃,并且此外,崩溃似乎只在iOS 4.3发布后开始发生。而且,崩溃发生在应用程序启动时,这使得确定为什么/在哪里可能已被过度释放或设置为nil等更加困难。(即当崩溃发生时,此时我的代码尚未触及任何与MapKit相关的内容)。 - fatfreddyscat
我会继续查找,但似乎 MapKit 调用“goToDefaultLocation”导致的位置会导致 CFStringGetLength 崩溃... - fatfreddyscat
很棒的是,能够获取发送到[ALCityManager localeWithCode:]的代码以及它是如何确定的。尝试过断点调试吗? - Vincent Guerci
看这里:https://dev59.com/tHA75IYBdhLWcg3wYH7I 我认为你需要的是 1. 在 gdb 中输入 fb -[ALCityManager localeWithCode:] 2. 当断点被触发时,输入 po $r0 - Vincent Guerci
忘记更新了 -> 结果发现这是苹果代码在iOS 4.3更新中的一个错误。解决方法是将语言环境设置为非英文,然后再设置回来。FYI。正在等待修复。 - fatfreddyscat
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接