代码之家  ›  专栏  ›  技术社区  ›  Declan McKenna

如何确定SIGTrap崩溃的原因?

  •  9
  • Declan McKenna  · 技术社区  · 7 年前

    我的团队最近发布了一个应用程序,其中出现了很多SIGTRAP崩溃。之前,我发现修复这些问题相对简单,因为在有问题的函数中找到一个糟糕的强制转换或一个隐式未包装的可选项设置为nil。不过这次我找不到这样的东西。我猜可能是 TimeBlock 由于日历错误,对象或其属性为零。

    我们的应用程序是一个会议组织者,可以向用户显示其本机iOS日历事件,包括空闲时间、冲突和会议 TimeBlocks . 我可以访问几个崩溃用户的日历。

    苹果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))
    }
    

    设置标头高度

    /**
     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密钥:0000000000000000000000000000000000硬件 型号:未定义流程:xxxxxxx[784]标识符:
    通用域名格式。xxx。xxx。xx。xxxxxxx版本:4.0.3代码类型:
    arm64

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

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

    线程0名称:线程0崩溃:0调用
    0x0000000102c224e4专用 TimelineHeader。updateTimeHours(时间段:)(TimelineHeader.swift:0)1 呼叫0x0000000102c20af0 TimelineHeader。HandleTimeBlocksDependeantComponents() (TimelineHeader.swift:0)2呼叫
    0x0000000102c7a28c专用 MeetingTableViewController。表格视图( :viewForHeaderInSection:) (TimelineHeader.swift:78)3 CallIn
    0x0000000102c75d54@objc MeetingTableViewController。表格视图(
    :viewForHeaderInSection:) (MeetingTableViewController.swift:0)4 UIKit
    0x000000018d1157d8-[UITableView \u delegateViewForHeaderInSection:] (UIKit)5 UIKit 0x000000018d11def0 96-[UITableView \u sectionHeaderView:withFrame:forSection:floating:ReuseViewFassible:willDisplay:]\u block\u invoke (UIKit)6 UIKit 0x000000018cdf1a14 +[UIView(动画)性能无动画:](UIKit)7 UIKit 0x000000018d11dc60-[UITableView _sectionHeaderView:withFrame:forSection:floating:ReuseViewer可能:将显示:] (UIKit)8 UIKit 0x000000018cfc6c04 -[\u UITableViewUpdateSupport(Private)\u setupAnimationsForExistingHeadersAndFooters](UIKit)9 UIKit 0x000000018cfc1070-[\u UITableViewUpdateSupport \u setupAnimations] (UIKit)10 UIKit 0x000000018cfc0944 -[UITableView \u updateWithItems:updateSupport:](UIKit)11 UIKit 0x000000018cfa8448-[UITableView endCellAnimationsWithContext:] (UIKit)12 UIKit 0x000000018cfa46e4 -[UITableView EndUpdate](UIKit)13调用0x0000000102c761a4 MeetingTableViewController。setHeaderHeight() (MeetingTableViewController,swift:398)14 CallIn
    0x0000000102c7a7c8专用封口#1英寸 MeetingTableViewController。刷新表(
    :) (MeetingTableViewController,swift:513)15呼叫
    0x0000000102c7aacc部分申请关闭#1英寸 MeetingTableViewController。刷新表(\u:) (MeetingTableViewController.swift:0)16呼叫
    0x0000000102cd17f0 thunk for@callee\u owned()->() (LoginPageViewController.swift:0)17 libdispatch。动态库
    0x000000018327ea54 \u dispatch\u call\u block\u and\u release (libdispatch.dylib)18 libdispatch。动态库
    0x000000018327ea14 \u dispatch\u client\u callout(libdispatch.dylib)19 libdispatch。dylib 0x000000018328b698 _dispatch\u main\u queue\u callback\u 4CF$VARIANT$mp(libdispatch.dylib)20 CoreFoundation 0x00000001838aa544 __CFRUNLOOP\u IS\u SERVICING\u THE\u MAIN\u DISPATCH\u QUEUE
    (CoreFoundation)21 CoreFoundation 0x00000001838a8120 \uu CFRunLoopRun (CoreFoundation)22 CoreFoundation
    0x00000001837c7e58 CFRunLoopRunSpecific(CoreFoundation)23 图形服务0x0000000185674f84 GSEventRunModal (GraphicsServices)24 UIKit
    0x000000018ce4767c UIApplicationMain(UIKit)25 CallIn
    0x0000000102c02c08 main(AppDelegate.swift:18)26 libdyld。动态库
    0x00000001832e456c启动(libdyld.dylib)

    1 回复  |  直到 7 年前
        1
  •  1
  •   Declan McKenna    6 年前

    生殖

    这是由于索引被 Timeblock.startHour Timeblock.endHour 存在 Int 价值观在查看了我们的用户日历后,我注意到他们所有人的会议都在午夜结束。

    因此,对于下午5点到午夜之间的会议,我们将看到以下情况。

    for i in timeblock.startHour...timeblock.endHour 成为 for i in 0...17

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

    修理

    我们限制了创造 timeblock.endHour 财产so > 0:00 第二天的更改为 23:59 以防止出现这种情况。修复方法只是将上限应用于 >= 0:00 因此,午夜结束的会议不被视为多日会议。

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