初级:第一步   为程序添加符号断点 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的更多相关文章

  1. vs2010 开发过程中调试时 有错误不中断

    出现这个的原因是调试的设置有问题,修改下设置就好了. 修改方法:点击上边工具栏中   调试--异常 出现以下页面,把引发那列复选框全部勾上,点击确定就好了.

  2. iphone开发中数据持久化之——属性列表序列化(一)

    数据持久化是应用程序开发过程中的一个基本问题,对应用程序中的数据进行持久化存储,有多重不同的形式.本系列文章将介绍在iphone开发过程中数据持久化的三种主要形式,分别是属性列表序列号.对象归档化以及 ...

  3. Eclipse中调试Android技巧

    Android eclipse中程序调试 一:断点调试 用eclipse开发android程序的时,跟VS一样是可以断点单步调试的. 步骤如下. 1 设置断点:在编码窗体的左边框上用鼠标双击,或者右键 ...

  4. iOS开发中调试小技巧

    对于软件开发而言,调试是必须学会的技能,重要性不言而喻.对于调试的技能,基本上是可以迁移的,也就是说你以前在其他平台上掌握的很多调试技巧,很多也是可以用在iOS开发中.不同语言.不同IDE.不同平台的 ...

  5. 在 Linux 平台中调试 C/C++ 内存泄漏方法(转)

    由于 C 和 C++ 程序中完全由程序员自主申请和释放内存,稍不注意,就会在系统中导入内存错误.同时,内存错误往往非常严重,一般会带来诸如系统崩溃,内存耗尽这样严重的后果.本文将从静态分析和动态检测两 ...

  6. iOS - 开发中调试小技巧

    对于软件开发而言,调试是必须学会的技能,重要性不言而喻.对于调试的技能,基本上是可以迁移的,也就是说你以前在其他平台上掌握的很多调试技巧,很多也是可以用在iOS开发中.不同语言.不同IDE.不同平台的 ...

  7. maven 中snapshot版本和release版本的区别

    maven中的仓库分为两种,snapshot快照仓库和release发布仓库.snapshot快照仓库用于保存开发过程中的不稳定版本,release正式仓库则是用来保存稳定的发行版本.定义一个组件/模 ...

  8. SubSonic3.0 Demo1.0——应用了T4模版可减少开发过程中70%以上的代码量以及80%以上的出错率

    应网友的要求,抽了点时间写了这个Demo,希望对2.2版想升级到3.0的朋友或正在使用3.0的朋友有所帮助.大家在使用Demo过程中如果发现什么问题或有什么建议,可以直接将Bug提交给我或告诉我,我会 ...

  9. 客户关系管理系统(CRM)的开发过程中使用到的开发工具总结

    开发<客户关系管理系统(CRM)>软件过程,也就是一个标准的Winform程序的开发过程,我们可以通过这个典型的软件开发过程来了解目前的开发思路.开发理念,以及一些必要的高效率手段.本篇随 ...

随机推荐

  1. KVM -> 虚拟化简介&虚拟机安装_01

    什么是虚拟化? 在计算机技术中,虚拟化(技术)或虚拟技术(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源(CPU.内存.磁盘空间.网络适配器等),予以抽象.转换后呈现 ...

  2. 详解PHP的执行原理和流程

    简介 先看看下面这个过程: • 我们从未手动开启过PHP的相关进程,它是随着Apache的启动而运行的: • PHP通过mod_php5.so模块和Apache相连(具体说来是SAPI,即服务器应用程 ...

  3. java.io.StreamCorruptedException: invalid stream header: EFBFBDEF 问题解决

    错误方式 @Test public void testDeserializeTest() throws IOException, ClassNotFoundException { ByteArrayO ...

  4. PHP 操作redis 封装的类 转的

    <?php/** * Redis 操作,支持 Master/Slave 的负载集群 * * @author jackluo */class RedisCluster{           // ...

  5. linux 检测远程端口是否打开

    linux 检测远程端口是否打开   检测远程端口是否打开   常用telnet 110.101.101.101 80方式测试远程主机端口是否打开.   除此之外还可以使用:   方法1.nmap i ...

  6. bzoj 1179

    题意:给你一个有向图,每个点有一个权值,有一个起点和q个终点,没经过一个点加上这个点的权值,让你选一条路,问你最大值是多少. 思路:tarjan强连通缩个点, 然后在拓扑图上dp一下就好啦, 注意第二 ...

  7. 黑马程序员_java基础笔记(15)...银行业务调度系统_编码思路及代码

    —————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流!—————————— 1,面试题目:银行业务调度系统 模拟实现银行业务调度系统逻辑,具体需求如下: 银行内 ...

  8. 过滤器中处理multipart/form-data头部的post请求request.getParameter(")获取不到参数问题

    如果不是文件类型请求,我们使用request.getParameter("");方法是可以获取到参数内容的,如果是文件类型的请求即请求的头部信息为“multipart/form-d ...

  9. 002.NTP服务端搭建

    一 安装及准备 1.1 安装NTP [root@server ~]# yum -y install ntp #也可下载之后rpm安装,或者源码安装 1.2 NTP服务地址 http://www.ntp ...

  10. maven deploy上传私服出错

    error 内容如下 Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.5:  deploy (default ...