iPhone开发过程中调试多次Release问题 message sent to deallocated
初级:第一步 为程序添加符号断点 malloc_error_break 方法如下。
目标效果:让程序崩溃时跳转到出错到那一行。但是往往达不到这个效果。不行就继续往下看。
At times, while running through your app, you might come across this warning on console:
MyApp(2121,0xb0185000) malloc: *** error for object 0x1068310: double free
*** set a breakpoint in malloc_error_break to debug
Even though you might feel that its not affecting your app, but its still annoying, and might cause some memory related issues as well.
So before going ahead, what is the compiler actually trying to tell you?
Well, its pretty simple, it is trying to tell you that the object at the memory location 0×1068310 is being freed twice, and it is trying to help you by saying that you may set a breakpoint in malloc_error_break to find more about this object.
There may be several reasons for something like this to happen, the foremost reason that I have found is programmers trying to free something that is already in the auto-release pool.
So how to fix this up?
It’s fairly simple, You need to set a “symbolic breakpoint” on malloc_error_break .
Go to Run > Breakpoints > Add Symbolic Breakpoint. Then paste malloc_error_break into the window.
Here are some screenshots to describe the process:
After that activate the breakpoints and simply run. and the app’s execution will stop at the point where it sees you freeing the variable the second time.
参考:http://blog.csdn.net/devday/article/details/6460929
中级:使用 malloc_history 14003 0xb47fc50 在终端中查看
步骤1:设置参数
做如下设置:
Project -> Edit active executable ->Argument
添加如下四个参数
NSDebugEnabled
NSZombieEnabled
MallocStackLogging
MallocStackLoggingNoCompact
并都设置为YES。具体如下图:
这个时候,如果有如下一段代码:
//重复释放一个变量
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSData* data = [NSData dataWithBytes:"asklaskdxjgr" length:12];
[data release];
[pool release];
再Debug窗口会有如下的提示
2003-03-18 13:01:38.644 autoreleasebug[3939] *** *** Selector 'release'
sent to dealloced instance 0xa4e10 of class NSConcreteData.
虽然也能大致判断是哪种类型的变量重复释放了,但信息还不够多,当项目大,源码比较多的时候,也不太方便定位,
在console窗口运行如下命令可以得到更多信息:shell malloc_history <pid> <address>
第二步:在终端(terminal中)输入命令:malloc_history 3939 0xa4e10
就会出现更多的信息:
[dave@host193 Frameworks]$ malloc_history 3939 0xa4e10
Call [2] [arg=32]: thread_a0000dec |0x1000 | start | _start | main |
+[NSData dataWithBytes:length:] | NSAllocateObject | object_getIndexedIvars |
malloc_zone_calloc
这个时候就知道具体哪个函数出先问题了,从这里可以看到main里NSData出现问题了。
参考:iphone 内存管理的一些总结 很棒!
我的经验:
1、在终端中输入命令时,要保持xcode开启,且程序正卡在端点处。
2、我用到命令是 malloc_history <pid> <address> ,返回的结果是:
ALLOC 0xb47fc50-0xb47fc6f [size=]: thread_416c1a8 |start | main | UIApplicationMain | -[UIApplication _run] | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSource1 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ | PurpleEventCallback | _PurpleEventCallback | _UIApplicationHandleEvent | -[UIApplication sendEvent:] | -[UIApplication handleEvent:withNewEvent:] | -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] | -[UIApplication _reportAppLaunchFinished] | +[CATransaction flush] | CA::Transaction::commit() | CA::Context::commit_transaction(CA::Transaction*) | CA::Layer::layout_and_display_if_needed(CA::Transaction*) | CA::Layer::layout_if_needed(CA::Transaction*) | -[CALayer layoutSublayers] | -[NSObject performSelector:withObject:] | -[UIView(CALayerDelegate) layoutSublayersOfLayer:] | -[UILayoutContainerView layoutSubviews] | -[UINavigationController __viewWillLayoutSubviews] | -[UINavigationController _startDeferredTransitionIfNeeded:] | -[UINavigationController _startTransition:fromViewController:toViewController:] | -[UINavigationController _updateScrollViewFromViewController:toViewController:] | -[UINavigationController _layoutViewController:] | -[UIViewController loadViewIfRequired] | -[SQHomePageViewController viewDidLoad] | -[SQHomePageViewController requestRecommendList] | -[RecommendList requestRecommendList] | -[SQHomePageAction requestHomePage] | -[SQBaseAction requestUrl:] | -[ASIHTTPRequest startSynchronous] | -[NSRunLoop(NSRunLoop) runMode:beforeDate:] | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSources0 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ | _cfstream_shared_signalEventSync | _signalEventSync | ReadStreamClientCallBack | -[ASIHTTPRequest handleNetworkEvent:] | -[ASIHTTPRequest handleStreamComplete] | -[ASIHTTPRequest requestFinished] | -[NSObject(NSThreadPerformAdditions) performSelectorOnMainThread:withObject:waitUntilDone:] | -[NSObject(NSThreadPerformAdditions) performSelector:onThread:withObject:waitUntilDone:modes:] | -[ASIHTTPRequest reportFinished] | __27-[SQBaseAction requestUrl:]_block_invoke | -[SQBaseAction onSuccess:] | -[SQBaseAction validResponse:] | -[SQBaseAction parserJsonWithString:] | -[NSDictionary initWithDictionary:] | -[NSDictionary initWithDictionary:copyItems:] | -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] | +[__NSDictionaryI __new:::::] | __CFAllocateObject2 | class_createInstance | calloc | malloc_zone_calloc
问题定位在红色函数中。
上面这段代码应该是完整地描述了,程序执行的全部过程。包括每一个类和每一个方法。非常有意思。
实际出错代码:
//将json 格式的原始数据转解析成数据字典
-(NSDictionary *)parserJsonWithString:(NSString *)str
{
NSString *strJson = [self removeEscapeCodeFromString:str];
SBJsonParser *sbJsonParser = [[[SBJsonParser alloc]init]autorelease];
NSDictionary *tempDictionary = [[NSDictionary alloc]initWithDictionary:[sbJsonParser objectWithString:strJson]];
return [tempDictionary autorelease]; //不必release或autorelease将自动释放
}
参考: message sent to deallocated instance 讲解的很详细,值得参考
其它信息:
message sent to deallocated instance问题的解决方法(gdb和lldb)
当出现message sent to deallocated instance的时候,一般伴随牛逼的BAD_ACCESS.是的,是某个对象release了两次。可是那么多的疑似对象,到底是哪一个? 使用xcode环境变量(添加方法请自行google)MallocStackLoggingNoCompact,NSZombieEnabled,MallocStackLogging这三个,值都设置成YES.寻求更详细的错误信息。 message sent to deallocated instance后会有一个内存地址,如:×,我们需要查看该地址的malloc history.查看方法,在原来的gdb下,使用”info malloc_history ד即可显示malloc记录。但是新版的Xcode 不再支持,怎么办呢?秀逗麻袋,我们还有terminal,使用终端的malloc_history命令,如”malloc_history ד即可显示。其中的32009是该进程的pid,根据这个malloc记录,可以大致定位出错信息的代码位置。 (插一句,gdb或者lldb进行debug的向导:http://lldb.llvm.org/lldb-gdb.html) 其实,如果代码编写足够高效和有序的话,是不会出现这种烦人的问题的。还是代码重构问题。代码洁癖伤不起啊。
你好,请问pid具体是哪个进程的,通过活动监视器查看么?_是的,activity monitor
iPhone开发过程中调试多次Release问题 message sent to deallocated的更多相关文章
- vs2010 开发过程中调试时 有错误不中断
出现这个的原因是调试的设置有问题,修改下设置就好了. 修改方法:点击上边工具栏中 调试--异常 出现以下页面,把引发那列复选框全部勾上,点击确定就好了.
- iphone开发中数据持久化之——属性列表序列化(一)
数据持久化是应用程序开发过程中的一个基本问题,对应用程序中的数据进行持久化存储,有多重不同的形式.本系列文章将介绍在iphone开发过程中数据持久化的三种主要形式,分别是属性列表序列号.对象归档化以及 ...
- Eclipse中调试Android技巧
Android eclipse中程序调试 一:断点调试 用eclipse开发android程序的时,跟VS一样是可以断点单步调试的. 步骤如下. 1 设置断点:在编码窗体的左边框上用鼠标双击,或者右键 ...
- iOS开发中调试小技巧
对于软件开发而言,调试是必须学会的技能,重要性不言而喻.对于调试的技能,基本上是可以迁移的,也就是说你以前在其他平台上掌握的很多调试技巧,很多也是可以用在iOS开发中.不同语言.不同IDE.不同平台的 ...
- 在 Linux 平台中调试 C/C++ 内存泄漏方法(转)
由于 C 和 C++ 程序中完全由程序员自主申请和释放内存,稍不注意,就会在系统中导入内存错误.同时,内存错误往往非常严重,一般会带来诸如系统崩溃,内存耗尽这样严重的后果.本文将从静态分析和动态检测两 ...
- iOS - 开发中调试小技巧
对于软件开发而言,调试是必须学会的技能,重要性不言而喻.对于调试的技能,基本上是可以迁移的,也就是说你以前在其他平台上掌握的很多调试技巧,很多也是可以用在iOS开发中.不同语言.不同IDE.不同平台的 ...
- maven 中snapshot版本和release版本的区别
maven中的仓库分为两种,snapshot快照仓库和release发布仓库.snapshot快照仓库用于保存开发过程中的不稳定版本,release正式仓库则是用来保存稳定的发行版本.定义一个组件/模 ...
- SubSonic3.0 Demo1.0——应用了T4模版可减少开发过程中70%以上的代码量以及80%以上的出错率
应网友的要求,抽了点时间写了这个Demo,希望对2.2版想升级到3.0的朋友或正在使用3.0的朋友有所帮助.大家在使用Demo过程中如果发现什么问题或有什么建议,可以直接将Bug提交给我或告诉我,我会 ...
- 客户关系管理系统(CRM)的开发过程中使用到的开发工具总结
开发<客户关系管理系统(CRM)>软件过程,也就是一个标准的Winform程序的开发过程,我们可以通过这个典型的软件开发过程来了解目前的开发思路.开发理念,以及一些必要的高效率手段.本篇随 ...
随机推荐
- MySQL之EXPLAIN 执行计划详解
explain 可以分析 select 语句的执行,即 MySQL 的“执行计划. 一.type 列 MySQL 在表里找到所需行的方式.包括(由左至右,由最差到最好): | All | index ...
- springcloud使用Hystrix实现微服务的容错处理
使用Hystrix实现微服务的容错处理 容错机制 如果服务提供者相应非常缓慢,那么消费者对提供者的请求就会被强制等待,知道提供者相应超时.在高负载场景下,如果不作任何处理,此类问题可能会导致服务消费者 ...
- 启动tomcat时报错Several ports (8005, 8080, 8009) required by Tomcat v5.5 Server at localhost are already in use.
[报错] Several ports (8005, 8080, 8009) required by Tomcat v5.5 Server at localhost are already in use ...
- POJ 1948 Triangular Pastures
题意: 把很多单独的线段重新组合成一个三角形,使得三角形面积最大(所有的线段都必须用上). 思路: 三角形的任意一条边的边长不能超过周长的一半,只需要用dp枚举两条边j,k,剩下的一条边长为tot ...
- goodrain云平台 mysql主从同步应用创建
mysql 主从同步原理 1)在Slave 服务器上执行sart slave命令开启主从复制开关,开始进行主从复制. 2)此时,Slave服务器的IO线程会通过在master上已经授权的复制用户权限请 ...
- 镜像文件挂载及本地yum搭建
环境:centos7.2 背景:企业内网不能上网,需安装软件以及软件之间的依赖问题 解决方案:下载和企业内网服务器相同版本的centos7.2镜像文件完整版(不是最小化的iso) 挂载镜像文件 1.上 ...
- Codeforces 336D Dima and Trap Graph 并查集
Dima and Trap Graph 枚举区间的左端点, 然后那些左端点比枚举的左端点小的都按右端点排序然后并查集去check #include<bits/stdc++.h> #defi ...
- sed匹配多行替换
sed -i '/aaa/{:a;n;s/123/xyz/g;/eee/!ba}' yourfile 如题:aaa123123123123123eee怎么匹配aaa~eee(开始结束字符串确定),然后 ...
- Java学习之模拟纸牌游戏,List的ArrayList,Map的HashMap,重写Collections类的sort方法对指定类进行通过特定属性排序,输入异常处理等的学习
首先放上测试效果图 设计框架 具体的代码实现 创建玩家类 public class Player implements Comparable<Player>{ int id; String ...
- canvas入门级小游戏《开关灯》思路讲解
游戏很简单,10行10列布局,每行每列各10盏灯,游戏初始化时随机点亮其中一些灯,点击某盏灯,其上下左右的灯及本身状态反转,如果点击前是灭着的,点击后即点亮,将所有灯全部点亮才算过关.游戏试玩: 下面 ...