【问题标题】:iOS Stack Trace Mystery, ABRecordCopyValue Is SuspectiOS Stack Trace 之谜,ABRecordCopyValue 疑点重重
【发布时间】:2011-09-07 17:01:48
【问题描述】:

我目前正在使用 TestFlight 来获取有关我们应用程序测试版的远程崩溃报告。我收到了堆栈跟踪,但是我不太确定如何缩小问题范围。这是我收到的报告:

0 Holler 0x0003f2a1 Holler + 254625
1 Holler 0x0003f6b7 Holler + 255671
2 libsystem_c.dylib 0x344da72f _sigtramp + 42
3 AppSupport 0x34dfc58d CPRecordCopyProperty + 12
4 AddressBook 0x33e333bf ABRecordCopyValue + 14
5 Holler 0x00018df5 Holler + 97781
6 Holler 0x000182d3 Holler + 94931
7 Holler 0x0000a561 Holler + 38241
8 Holler 0x00033e0f Holler + 208399
9 CoreFoundation 0x3675d571 -[NSObject(NSObject) performSelector:withObject:withObject:] + 24
10 UIKit 0x355efec9 -[UIApplication sendAction:to:from:forEvent:] + 84
11 UIKit 0x355efe69 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 32
12 UIKit 0x355efe3b -[UIControl sendAction:to:forEvent:] + 38
13 UIKit 0x355efb8d -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 356
14 UIKit 0x355f0423 -[UIControl touchesEnded:withEvent:] + 342
15 UIKit 0x355eebf5 -[UIWindow _sendTouchesForEvent:] + 368
16 UIKit 0x355ee56f -[UIWindow sendEvent:] + 262
17 UIKit 0x355d7313 -[UIApplication sendEvent:] + 298
18 UIKit 0x355d6c53 _UIApplicationHandleEvent + 5090
19 GraphicsServices 0x35f11e77 PurpleEventCallback + 666
20 CoreFoundation 0x367c4a97 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
21 CoreFoundation 0x367c683f __CFRunLoopDoSource1 + 166
22 CoreFoundation 0x367c760d __CFRunLoopRun + 520
23 CoreFoundation 0x36757ec3 CFRunLoopRunSpecific + 230
24 CoreFoundation 0x36757dcb CFRunLoopRunInMode + 58
25 GraphicsServices 0x35f1141f GSEventRunModal + 114
26 GraphicsServices 0x35f114cb GSEventRun + 62
27 UIKit 0x35601d69 -[UIApplication _run] + 404
28 UIKit 0x355ff807 UIApplicationMain + 670
29 Holler 0x00002d79 Holler + 7545
30 Holler 0x00002d44 Holler + 7492

不幸的是,堆栈跟踪中的最后 8 项似乎没有被符号化。我有办法做到这一点吗?我假设 hte 问题与 ABRecordCopyValue 有关,但我不是 100% 确定。因为我不知道最后两个 Holler 电话是什么,所以我有点困惑。有人知道我应该怎么做才能缩小问题范围吗?

我认为问题现在存在于特定方法中,因为重复了两个 Holler 调用之后的事件序列 (ABRecordCopyValue)。这是代码...我正在使用它来加载用户的电话簿/联系人列表。如果这提供了更多详细信息,请告诉我:

ContactLists *list = [ContactLists defaultLists];

//Delete the phone contacts, and load them
[list clearContacts];
//Load them
ABAddressBookRef addressbook = ABAddressBookCreate();
if( addressbook )
{
    //Got this via http://stackoverflow.com/questions/4641229/code-example-for-abaddressbookcopyarrayofallpeopleinsourcewithsortordering
    ABRecordRef source = ABAddressBookCopyDefaultSource(addressbook);
    CFArrayRef sortedPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressbook, source, kABPersonSortByFirstName);
    //Sort them first

    if( sortedPeople )
    {
        CFIndex contactCount = ABAddressBookGetPersonCount(addressbook);

        for( int i = 0; i<contactCount; i++ )
        {
            ABRecordRef ref = CFArrayGetValueAtIndex(sortedPeople, i);
            NSMutableString *fName = [[[NSMutableString alloc] init] autorelease];
            NSMutableString *lName = [[[NSMutableString alloc] init] autorelease];
            NSMutableDictionary *identifiers = [[[NSMutableDictionary alloc]init]autorelease];
            if( ref )
            {
                //Get the user's name first
                CFStringRef firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
                if( firstName )
                {
                    NSString *fn = [NSString stringWithFormat:@"%@",firstName];
                    if([fn hasPrefix:@"(null"])
                        [fName appendString:@""];
                    else
                    {
                        [fName appendString:[NSString stringWithFormat:@"%@", firstName]];
                        [fName setString:[fName stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[fName substringToIndex:1]uppercaseString]]];
                    }
                    CFRelease(firstName);
                }
                CFStringRef lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
                if( lastName )
                {
                    NSString *ln = [NSString stringWithFormat:@"%@",lastName];
                    if([ln hasPrefix:@"(null"])
                        [lName appendString:@""];
                    else
                        [lName appendString:[NSString stringWithFormat:@"%@",lastName]];
                    CFRelease(lastName);
                }
                //If there is no first name don't deal with adding this contact to the ContactsList
                if( [fName isEqualToString:@""] )
                {
                    continue;
                }

                //Handle phone and email contacts
                ABMultiValueRef phoneRef = ABRecordCopyValue(ref, kABPersonPhoneProperty);
                if(phoneRef)
                {
                    for( int i = 0; i<ABMultiValueGetCount(phoneRef); i++ )
                    {
                        CFStringRef phone = ABMultiValueCopyValueAtIndex(phoneRef, i);
                        if (phone) {
                            //Create the contact and add them to the phone contactList
                            NSString *mobileLabel = (NSString *)ABMultiValueCopyLabelAtIndex(phoneRef, i);
                            if( [mobileLabel isEqualToString:(NSString *)kABPersonPhoneMobileLabel] )
                                [identifiers setValue:(NSString *)phone forKey:@"Mobile:"];
                            if( [mobileLabel isEqualToString:(NSString *)kABPersonPhoneIPhoneLabel] )
                                [identifiers setValue:(NSString *)phone forKey:@"iPhone:"];
                            if( [mobileLabel isEqualToString:(NSString *)kABPersonPhoneMainLabel] )
                                [identifiers setValue:(NSString *)phone forKey:@"Main:"];
                            if( [mobileLabel isEqualToString:(NSString *)kABWorkLabel] )
                                [identifiers setValue:(NSString *)phone forKey:@"Work:"];
                            if( [mobileLabel isEqualToString:(NSString *)kABHomeLabel] )
                                [identifiers setValue:(NSString *)phone forKey:@"Home:"];
                            if( [mobileLabel isEqualToString:(NSString *)kABOtherLabel] )
                                [identifiers setValue:(NSString *)phone forKey:@"Other:"];

                            CFRelease(phone);
                            [mobileLabel release];
                        }
                    }
                    CFRelease(phoneRef);
                }


                ABMultiValueRef emailRef = ABRecordCopyValue(ref, kABPersonEmailProperty);
                if (emailRef) {
                    if (ABMultiValueGetCount(emailRef) > 0) {
                        CFStringRef email = ABMultiValueCopyValueAtIndex(emailRef, 0);

                        if (email) {
                            [identifiers setValue:(NSString *)email forKey:@"Email:"];
                            CFRelease(email);
                        }
                    }
                    CFRelease(emailRef);
                }
                if( [identifiers count] > 0 )
                {
                    //This is where I believe the problem is happen as it's two calls to internal Holler models
                    [list addContact:[[[Contact alloc]initWithIdentifiers:identifiers firstName:fName lastName:lName]autorelease]];
                }
            }
        }
        CFRelease(sortedPeople);
    }
    CFRelease(addressbook);
    CFRelease(source);
}

【问题讨论】:

    标签: objective-c ios xcode cocoa-touch


    【解决方案1】:

    您需要先对堆栈跟踪进行符号化,然后才能说出崩溃的位置。

    如果您在 Xcode 中打开堆栈跟踪文件(管理器窗口中的导入按钮),它将自动使用匹配的二进制和符号文件进行符号化...。 也就是说,如果您保存了二进制/符号文件 - 最好使用存档功能。

    如果您没有为该确切文件保存符号文件,那么您无法对崩溃日志进行符号化,并且必须疯狂地猜测真正的原因。

    【讨论】:

    • 我没有只有堆栈跟踪的文件。我可以自己保存符号文件吗?
    • 它是作为构建过程的一部分自动创建的。始终确保保留它们以备后用,以防您需要处理崩溃报告
    • 保留什么以备后用?也许您错过了通过 Testflight 分发给 beta 测试人员的部分......我所拥有的只是 testflight 提供的堆栈跟踪
    • 我想你自己把 ipa 文件上传到了 Testflight。该 ipa 文件是由您自己的构建过程基于应用程序文件生成的。除了该应用程序文件,构建过程还生成了一个符号文件。保留这两个文件(app + sym)以供以后使用 - 最好使用归档功能 i Xcode。需要它们来表示堆栈跟踪。
    【解决方案2】:

    您确实需要在堆栈跟踪中符号化 Holler 方法。就是这样: 转到 TestFlight --> 选择 Builds 选项卡,然后单击您遇到问题的构建下的 Testers 按钮。向下滚动到底部并单击可用于手动通知测试人员的 bit.ly 链接。在该页面的底部,您可以选择下载之前上传的 .ipa 文件。下载吧。

    下载到您的计算机后,将文件扩展名从 .ipa 重命名为 .zip。然后解压它,你应该会得到 .app 文件。由于您只有堆栈跟踪而不是完整的崩溃报告,因此您不能使用 XCode 进行符号化,但您可以使用此处的说明手动进行符号化:http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/311

    希望对您有所帮助,我很想成为您未来应用的 Beta 版测试人员!

    【讨论】:

    • 不幸的是,没有发现问题:(它只是象征着“<__destroy_helper_block_1>”
    猜你喜欢
    • 2011-10-01
    • 1970-01-01
    • 2011-04-02
    • 2023-04-06
    • 2011-05-30
    • 1970-01-01
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多