如何确定我的 SIGTrap 崩溃的原因?

Posted

技术标签:

【中文标题】如何确定我的 SIGTrap 崩溃的原因?【英文标题】:How to identify the cause of my SIGTrap Crash? 【发布时间】:2018-06-08 01:23:57 【问题描述】:

我的团队最近推出了一个应用程序,该应用程序发生了很多 SIGTRAP 崩溃。以前我发现这些修复起来相对简单,因为它是在有问题的函数中找到一个糟糕的强制转换或一个隐式展开的选项被设置为 nil 的问题。这一次,虽然我找不到任何类似的东西。我的最佳猜测是,由于日历错误,TimeBlock 对象之一或其属性可能为 nil。

我们的应用程序是一个会议组织者,可根据空闲时间、冲突和会议TimeBlocks 向用户显示他们的原生 ios 日历事件。我可以访问多个崩溃用户的日历。

Apple SigTrap 定义

如果发生意外,Swift 代码将以这种异常类型终止 运行时遇到条件如:

具有 nil 值的非可选类型 强制类型转换失败

崩溃功能

    /**
    Updates the conflictHours and meetingHours according to the timeblocks
    it is used as quick light reference to the button
 */
func updateTimeHours(timeblocks : [Timeblock]) 
    for timeblock in timeblocks 
        switch timeblock 
        case is MeetingTimeblock:
            for i in timeblock.startHour...timeblock.endHour 
                self.meetingHours[i] = true
            
            break
        case is ConflictTimeblock:
            for i in timeblock.startHour...timeblock.endHour 
                self.conflictsHours[i] = true
            
            break
        default: break
        
    
    updateButtonByOffset(offset: self.scrollTimeline.contentOffset.x)

调用崩溃函数

    /**
    This function inits the variables and button layout according to the timeblocks
 */
func handleTimeblocksDependantComponents() 
    buttonLayout()
    guard Scheduler.sharedInstance.timelines.count > SharedGlobals.Calendar.TODAY_INDEX else 
        return
    
    updateTimeHours(timeblocks : (Scheduler.sharedInstance.timelines[SharedGlobals.Calendar.TODAY_INDEX].timeblocks))

SetHeaderHeight

/**
 Adjusts the height of the header depending on whether there are hosted meetings or 
 meeting VIP's or not.
*/
private func setHeaderHeight() 
    self.tableView.tableHeaderView = self.headerView
    let hostedMeetings = OverviewInteractor.getHostedMeetings(dayIndex: SharedGlobals.Calendar.SELECTED_DAY)
    let vips = OverviewInteractor.getVIPS(dayIndex: SharedGlobals.Calendar.SELECTED_DAY)

    self.tableView.beginUpdates()
    if let headerView = self.tableView.tableHeaderView 
        var height = 360.0
        if(vips.count == 0)  height -= 80.0 
        if(hostedMeetings.count == 0)  height -= 80.0 
        headerView.frame.size.height = CGFloat(height)
    
    self.tableView.endUpdates()


时间块定义

// The Timeblock parent class. It simply holds a start and end time and provides its own duration. Not to be used as such
public class Timeblock 
    public let startTime: Date
    public let endTime: Date

    /// Returns the hour the Timeblock starts, in current timezone
    public var startHour: Int 
        get 
            return Calendar.current.component(.hour, from: startTime)
        
    

    /// Returns the hour the Timeblocks ends, in current timezone
    public var endHour: Int 
        get 
            return Calendar.current.component(.hour, from: endTime)
        
    

    /// Returns the minutes the Timeblocks starts
    public var startMinutes: Int 
        get 
            return Calendar.current.component(.minute, from: startTime)
        
    

    /// Returns the minutes the Timeblocks ends
    public var endMinutes: Int 
        get 
            return Calendar.current.component(.minute, from: endTime)
        
    

    /**
        Initialises the instance with a start and end time
        - Parameters:
            - startTime: The start time of the timeblock
            - endTime: The end time of the timeblock
    */
    public init(startTime: Date, endTime: Date) 
        self.startTime = startTime
        self.endTime = endTime
    

    /**
        Provides the Timeblock's duration in the form of a DateInterval
        - warning: Only available on iOS 10.0 and up
        - returns: A DateInterval of the duration of the Timeblock
    */
    @available(iOS 10.0, *)
    public func getTimeInterval() -> DateInterval 
        return DateInterval(start: self.startTime, end: self.endTime)
    

    /**
        Provides the Timeblock's duration in the form of a `Double` (number of seconds)

        - returns: The number of seconds that this Timeblock goes on for
    */
    public func getDuration() -> Double 
        return self.endTime.timeIntervalSince(self.startTime)
    


崩溃报告

事件标识符:98D4F477-C57B-4767-B957-E9EA2E0EE3EA CrashReporter 密钥:0000000000000000000000000000000000000000 硬件 型号:未定义进程:xxxxxxx [784] 标识符: com.xxx.xxx.xx.xxxxxxx 版本:4.0.3 代码类型: arm64

日期/时间:2017 年 12 月 24 日星期日 09:55:23 GMT+0000 (GMT) 发布 时间:无效日期操作系统版本:未定义 11.0.3 (15A432) 报告版本:105

异常类型:SIGTRAP 异常子类型:未定义

线程 0 名称:线程 0 崩溃:0 CallIn 0x0000000102c224e4 专用 TimelineHeader.updateTimeHours(timeblocks:) (TimelineHeader.swift:0) 1 呼入 0x0000000102c20af0 TimelineHeader.handleTimeblocksDependantComponents() (TimelineHeader.swift:0) 2 呼入 0x0000000102c7a28c 专门的 MeetingTableViewController.tableView(:viewForHeaderInSection:) (TimelineHeader.swift:78) 3 呼入 0x0000000102c75d54 @objc MeetingTableViewController.tableView(:viewForHeaderInSection:) (MeetingTableViewController.swift:0) 4 UIKit 0x000000018d1157d8 -[UITableView _delegateViewForHeaderInSection:] (UIKit) 5 UIKit 0x000000018d11def0 96-[UITableView _sectionHeaderView:withFrame:forSection:floating:reuseViewIfPossible:willDisplay:]_block_invoke (UIKit) 6 UIKit 0x000000018cdf1a14 +[UIView(Animation) performWithoutAnimation:] (UIKit) 7 UIKit 0x000000018d11dc60 -[UITableView _sectionHeaderView:withFrame:forSection:floating:reuseViewIfPossible:willDisplay:] (UIKit) 8 UIKit 0x000000018cfc6c04 -[_UITableViewUpdateSupport(Private) _setupAnimationsForExistingHeadersAndFooters] (UIKit) 9 UIKit 0x000000018cfc1070 -[_UITableViewUpdateSupport _setupAnimations] (UIKit) 10 UIKit 0x000000018cfc0944 -[UITableView _updateWithItems:updateSupport:] (UIKit) 11 UIKit 0x000000018cfa8448 -[UITableView endCellAnimationsWithContext:] (UIKit) 12 UIKit 0x000000018cfa46e4 -[UITableView endUpdates] (UIKit) 13 CallIn 0x0000000102c761a4 MeetingTableViewController.setHeaderHeight() (MeetingTableViewController.swift:398) 14 CallIn 0x0000000102c7a7c8 专用闭包 #1 in MeetingTableViewController.refreshTable(:) (MeetingTableViewController.swift:513) 15 呼入 0x0000000102c7aacc 部分申请关闭#1 in MeetingTableViewController.refreshTable(_:) (MeetingTableViewController.swift:0) 16 CallIn 0x0000000102cd17f0 thunk for @callee_owned () -> () (LoginPageViewController.swift:0) 17 libdispatch.dylib 0x000000018327ea54 _dispatch_call_block_and_release (libdispatch.dylib) 18 libdispatch.dylib 0x000000018327ea14 _dispatch_client_callout (libdispatch.dylib) 19 libdispatch.dylib 0x000000018328b698 _dispatch_main_queue_callback_4CF$VARIANT$mp (libdispatch.dylib) 20 核心基础 0x00000001838aa544 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE (CoreFoundation) 21 CoreFoundation 0x00000001838a8120 __CFRunLoopRun (CoreFoundation) 22 CoreFoundation 0x00000001837c7e58 CFRunLoopRunSpecific (CoreFoundation) 23 图形服务 0x0000000185674f84 GSEventRunModal (GraphicsServices) 24 UIKit 0x000000018ce4767c UIApplicationMain (UIKit) 25 调用 0x0000000102c02c08 main (AppDelegate.swift:18) 26 libdyld.dylib 0x00000001832e456c 启动(libdyld.dylib)

【问题讨论】:

你能发布MeetingTableViewController.setHeaderHeight()方法吗? @ReinierMelian 我已经更新了问题以包含它。 我认为这个问题与您在外部修改标题高度有关,您需要更改它并在heightForHeaderInSection方法中返回高度 我认为 setHeaderHeight() 正在修改表格的标题视图高度,没有部分的标题 你能显示时间块的定义吗,因为我看不到它是否有任何选项。 【参考方案1】:

复制

这是由于Timeblock.startHourTimeblock.endHourInt 值弄乱了索引。查看我们的用户日历后,我注意到他们所有人的会议都在午夜结束。

所以对于下午 5 点到午夜之间进行的会议,我们会发生以下情况。

for i in timeblock.startHour...timeblock.endHour 变成了 for i in 0...17

这会给出一个非常精确的错误,告诉我一旦我重现了崩溃,我就无法向后迭代,不幸的是崩溃报告中没有出现,这有点误导。

修复

我们限制了创建 timeblock.endHour 属性的时间,因此将第二天的 > 0:00 更改为 23:59 以防止这种情况发生。解决方法是简单地将上限应用于 >= 0:00,因此在午夜结束的会议不会被视为多天会议。

未来的重构可能是将在该小时结束的所有时间设置为前一小时的结束时间,因为从技术上讲,如果您的会议在上午 11:00 结束,您仍然有空闲时间。我还想在 Timeblock 对象中处理这一切,而不是过滤用于创建它的参数。

【讨论】:

以上是关于如何确定我的 SIGTrap 崩溃的原因?的主要内容,如果未能解决你的问题,请参考以下文章

如何确定 Mobile Safari 崩溃的原因?

CollectionView cellForItemAt IndexPath 中的 SIGTRAP(TRAP_BRKPT) 崩溃

WordPress服务器不断耗尽内存并崩溃,我该如何确定和修复原因?

SwiftUI 因一位用户的 EXC_BREAKPOINT (SIGTRAP) 而崩溃,我无法在模拟器中复制它

一种signal 5 (SIGTRAP), code 1 (TRAP_BRKPT)的原因

一种signal 5 (SIGTRAP), code 1 (TRAP_BRKPT)的原因