iOS10中的CFRelease崩溃 [英] CFRelease crash in iOS10

查看:195
本文介绍了iOS10中的CFRelease崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我的代码,该代码在iOS 9之前都可以正常工作.

Below is my code, which used to work fine till iOS 9.

- (NSData *)encryptWithDataPublicKey:(NSString*)data keyTag:(NSString*)tag
{  

    SecKeyRef publicKey = NULL;                                           
    NSData *publicTag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];

    NSMutableDictionary *queryPublicKey =
    [[NSMutableDictionary alloc] init];

    [queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];  

    [queryPublicKey setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag];

    [queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];

    [queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];

    OSStatus status = SecItemCopyMatching
    ((__bridge CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKey);

    NSData *encodedData = nil;  

    if (status == noErr && publicKey) {  
        NSData *dataToEncrypt = [data dataUsingEncoding:NSUTF8StringEncoding];  
        encodedData = [self encryptData:dataToEncrypt withKeyRef:publicKey];  
        CFRelease(publicKey);  
    }  
    return encodedData;  
}

该方法以前在iOS 9.x之前都可以正常工作,但是今天,当我将XCode更新为8并在iOS 10设备上运行时.应用程序在
时崩溃了 CFRelease(publicKey) .

This method used to work fine till iOS 9.x, But today when I have updated my XCode to 8 and run on iOS 10 device. Application is getting crashed at
CFRelease(publicKey).

在崩溃之前,下面是来自控制台的日志.

Before crashing below is the log from console.

无法加载任何Objective-C类信息.这会大大降低了可用类型信息的质量

could not load any Objective-C class information. This will significantly reduce the quality of type information available

无法完全找到问题.

当我启用Zombie并重现崩溃时.下面是控制台的日志.

When I enabled Zombie, and reproduce the crash. Below is the log from console.

***-[非A类型发行版]:消息发送到已释放实例0x170225880

*** -[Not A Type release]: message sent to deallocated instance 0x170225880

谢谢.

我知道了.有一个内部方法encodeData = [self cryptoData:dataToEncrypt withKeyRef:publicKey];

I got the Issue. there is an inner method encodedData = [self encryptData:dataToEncrypt withKeyRef:publicKey];

释放SecKeyRef对象的位置.

where SecKeyRef object is getting released.

但是我不知道它在iOS9之前如何工作???????

But I wonder how this worked till iOS9???????

-(NSData *)encryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{
    const uint8_t *srcbuf = (const uint8_t *)[data bytes];
    size_t srclen = (size_t)data.length;

    size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);
    void *outbuf = malloc(block_size);
    size_t src_block_size = block_size - 11;

    NSMutableData *ret = [[NSMutableData alloc] init];
    for(int idx=0; idx<srclen; idx+=src_block_size){
        size_t data_len = srclen - idx;
        if(data_len > src_block_size){
            data_len = src_block_size;
        }

        size_t outlen = block_size;
        OSStatus status = noErr;
        status = SecKeyEncrypt(keyRef,
                               kSecPaddingPKCS1,
                               srcbuf + idx,
                               data_len,
                               outbuf,
                               &outlen
                               );
        if (status != 0) {
            ret = nil;
            break;
        }else{
            [ret appendBytes:outbuf length:outlen];
        }
    }

    free(outbuf);
    CFRelease(keyRef);
    return ret;
}

推荐答案

encryptData:withKeyRef:中,方法结尾处的 CFRelease 不平衡.该方法中的任何内容都不会保留 keyRef ,但是您将其释放.删除该呼叫.

In encryptData:withKeyRef: you have an unbalanced CFRelease at the end of the method. Nothing in that method retained keyRef, but you release it. Remove that call.

为什么以前没有崩溃?因为以前可能在内部保留了其他内容,可能是缓存,也可能是其他内容.可可没有保证过度释放会立即(或曾经)导致崩溃.你陷入了不确定的行为.

Why didn't it crash before? Because something else was likely retaining it internally previously, possibly a cache, possibly something else. Cocoa makes no promises that an over-release will immediately (or ever) lead to a crash. You were into undefined behavior.

但是,非常令人沮丧的是,静态分析器没有检测到这一点.我将打开有关该错误的报告(bugreport.apple.com).您的内存管理违规情况非常明显,分析器应已发现它.

It's very distressing, though, that the static analyzer isn't detecting this. I would open a bug report about that (bugreport.apple.com). You have a very clear memory management violation and the analyzer should have caught it.

这篇关于iOS10中的CFRelease崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆