From 13f68fb29a62b209ee8b446ca96aafdf4c9309de Mon Sep 17 00:00:00 2001 From: Hongyan Jiang Date: Thu, 14 Dec 2023 21:06:18 -0800 Subject: [PATCH] Add more meta data to crash beacon (#33) Add more meta data, exceptionType exceptionCode and signal display processing to crash beacon --- Changelog.md | 5 + InstanaAgent.podspec | 2 +- Sources/InstanaAgent/.swiftlint.yml | 1 + .../InstanaAgent/Configuration/Defines.swift | 2 +- .../Configuration/VersionConfig.swift | 2 +- .../Monitors/Metric/DiagnosticPayload.swift | 150 ++++++++++-------- .../DiagnosticSymbolicator.swift | 75 +++++---- .../Metric/Symbolication/StackTrace.swift | 17 +- .../Symbolication/SymbolicationFrame.swift | 1 + .../InstanaSystemUtilsTests.swift | 2 +- .../Mocks/MXDiagnosticPayloadMocks.swift | 3 + .../Metric/DiagnosticPayloadTests.swift | 77 ++++----- 12 files changed, 194 insertions(+), 143 deletions(-) diff --git a/Changelog.md b/Changelog.md index 67bc9a8..fcb61e9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,10 @@ # Changelog +## 1.6.8 +- Add more meta data to crash beacon +- Add more exceptionType processing to crash beacon +- Display crash terminationReason as meta data rather than error message + ## 1.6.7 - Add more raw crash payload info to stackTrace diff --git a/InstanaAgent.podspec b/InstanaAgent.podspec index fcbb927..54abbd5 100644 --- a/InstanaAgent.podspec +++ b/InstanaAgent.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |s| # s.name = "InstanaAgent" - s.version = "1.6.7" + s.version = "1.6.8" s.summary = "Instana iOS agent." # This description is used to generate tags and improve search results. diff --git a/Sources/InstanaAgent/.swiftlint.yml b/Sources/InstanaAgent/.swiftlint.yml index af91958..1014df0 100644 --- a/Sources/InstanaAgent/.swiftlint.yml +++ b/Sources/InstanaAgent/.swiftlint.yml @@ -30,4 +30,5 @@ identifier_name: excluded: # excluded via string array - id large_tuple: 3 +cyclomatic_complexity: 20 diff --git a/Sources/InstanaAgent/Configuration/Defines.swift b/Sources/InstanaAgent/Configuration/Defines.swift index 1e323dd..45dc0b3 100644 --- a/Sources/InstanaAgent/Configuration/Defines.swift +++ b/Sources/InstanaAgent/Configuration/Defines.swift @@ -44,7 +44,7 @@ let crashMetaKeyUserID = "ui" let crashMetaKeyUserName = "un" let crashMetaKeyUserEmail = "ue" -let currentInstanaCrashPayloadVersion = "0.93" +let currentInstanaCrashPayloadVersion = "0.94" let defaultCrashViewName = "CrashView" let maxSecondsToKeepCrashLog = (maxDaysToKeepCrashLog * 60 * 60 * 24) diff --git a/Sources/InstanaAgent/Configuration/VersionConfig.swift b/Sources/InstanaAgent/Configuration/VersionConfig.swift index 137ecc2..7dbdc25 100644 --- a/Sources/InstanaAgent/Configuration/VersionConfig.swift +++ b/Sources/InstanaAgent/Configuration/VersionConfig.swift @@ -1,3 +1,3 @@ struct VersionConfig { - static let agentVersion = "1.6.7" + static let agentVersion = "1.6.8" } diff --git a/Sources/InstanaAgent/Monitors/Metric/DiagnosticPayload.swift b/Sources/InstanaAgent/Monitors/Metric/DiagnosticPayload.swift index b08855a..0656d84 100644 --- a/Sources/InstanaAgent/Monitors/Metric/DiagnosticPayload.swift +++ b/Sources/InstanaAgent/Monitors/Metric/DiagnosticPayload.swift @@ -34,6 +34,7 @@ class DiagnosticPayload: Codable { let appVersion: String? let osVersion: String? let deviceType: String? + let platformArchitecture: String? // crash let exceptionType: Int? let exceptionCode: Int? @@ -69,6 +70,7 @@ class DiagnosticPayload: Codable { case appVersion case osVersion case deviceType + case platformArchitecture case exceptionType // crash case exceptionCode case signal @@ -96,6 +98,7 @@ class DiagnosticPayload: Codable { appVersion: String?, osVersion: String?, deviceType: String?, + platformArchitecture: String?, exceptionType: Int?, exceptionCode: Int?, signal: Int?, @@ -122,6 +125,7 @@ class DiagnosticPayload: Codable { self.appVersion = appVersion self.osVersion = osVersion self.deviceType = deviceType + self.platformArchitecture = platformArchitecture self.exceptionType = exceptionType self.exceptionCode = exceptionCode self.signal = signal @@ -218,6 +222,7 @@ class DiagnosticPayload: Codable { var appVersion: String? let osVersion = oneDiag.metaData.osVersion var deviceType: String? + var platformArchitecture: String? var exceptionType: Int? // crash var exceptionCode: Int? var signal: Int? @@ -244,6 +249,7 @@ class DiagnosticPayload: Codable { appVersion = metaDict["appVersion"] as? String bundleIdentifier = metaDict["bundleIdentifier"] as? String deviceType = metaDict["deviceType"] as? String + platformArchitecture = metaDict["platformArchitecture"] as? String exceptionType = metaDict["exceptionType"] as? Int // crash exceptionCode = metaDict["exceptionCode"] as? Int signal = metaDict["signal"] as? Int @@ -257,6 +263,7 @@ class DiagnosticPayload: Codable { } let (errorType, errorMessage) = Self.parseErrorTypeAndMessage(crashType: crashType!, diagnostic: oneDiag) + guard errorMessage != nil else { continue } let rawMXPayload = Self.getMXPayloadStr(diagnostic: oneDiag) guard rawMXPayload != nil else { continue } @@ -275,6 +282,7 @@ class DiagnosticPayload: Codable { appVersion: appVersion, osVersion: osVersion, deviceType: deviceType, + platformArchitecture: platformArchitecture, exceptionType: exceptionType, exceptionCode: exceptionCode, signal: signal, @@ -363,95 +371,103 @@ class DiagnosticPayload: Codable { let signal = crashDiag.signal var errorCode: Int? - var errorMsg: String? - let machExceptionName = Self.getMachExceptionName(exceptionType: exceptionType, - exceptionCode: exceptionCode) - if machExceptionName != nil { - errorCode = Int(truncating: exceptionType!) - errorMsg = machExceptionName - } else { - let (sigName, sigCodeName) = Self.getSignalName(signal: signal) - if sigName != nil { - errorCode = Int(truncating: signal!) - if sigCodeName != nil { - errorMsg = sigName! + " - " + sigCodeName! - } else { - errorMsg = sigName - } - } + var errorMsg: String = "" + let machExceptionType = Self.getMachExceptionTypeDisplayName(exceptionType: exceptionType) + let machExceptionCode = Self.getMachExceptionCodeDisplayName(exceptionType: exceptionType, + exceptionCode: exceptionCode) + let sigName = Self.getSignalName(signal: signal) + + if machExceptionType != nil { + errorMsg = machExceptionType! + } + if sigName != nil { + errorMsg += " (\(sigName!))" } - if crashDiag.terminationReason != nil { - errorMsg = crashDiag.terminationReason! + if machExceptionCode != nil { + errorMsg += " - \(machExceptionCode!)" + } + + if errorMsg.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + errorMsg = "unkown error" + } + + if exceptionType != nil { + errorCode = Int(truncating: exceptionType!) + } else if signal != nil { + errorCode = Int(truncating: signal!) } + return (errorCode, errorMsg) } - static func getMachExceptionName(exceptionType: NSNumber?, exceptionCode: NSNumber?) -> String? { + static func getMachExceptionTypeDisplayName(exceptionType: NSNumber?) -> String? { guard let exceptionType = exceptionType else { return nil } - var name: String? - var codeName: String? switch Int32(truncating: exceptionType) { - case EXC_BAD_ACCESS: - name = "EXC_BAD_ACCESS" - codeName = Self.getMachExceptionBadAccessCodeName(exceptionType: exceptionType, exceptionCode: exceptionCode) - case EXC_BAD_INSTRUCTION: - name = "EXC_BAD_INSTRUCTION" - case EXC_ARITHMETIC: - name = "EXC_ARITHMETIC" - case EXC_BREAKPOINT: - name = "EXC_BREAKPOINT" - case EXC_GUARD: - name = "EXC_GUARD" + case EXC_BAD_ACCESS: // 1 + return "EXC_BAD_ACCESS" + case EXC_BAD_INSTRUCTION: // 2 + return "EXC_BAD_INSTRUCTION" + case EXC_ARITHMETIC: // 3 + return "EXC_ARITHMETIC" + case EXC_BREAKPOINT: // 6 + return "EXC_BREAKPOINT" + case EXC_CRASH: // 10 + return "EXC_CRASH" + case EXC_RESOURCE: // 11 + return "EXC_RESOURCE" + case EXC_GUARD: // 12 + return "EXC_GUARD" default: - name = exceptionType.stringValue - } - if name != nil { - if codeName != nil { - name = name! + " - " + codeName! - } - return name + return exceptionType.stringValue } - return nil } - static func getMachExceptionBadAccessCodeName(exceptionType: NSNumber, exceptionCode: NSNumber?) -> String? { - guard Int32(truncating: exceptionType) == EXC_BAD_ACCESS, - let exceptionCode = exceptionCode else { return nil } + static func getMachExceptionCodeDisplayName(exceptionType: NSNumber?, exceptionCode: NSNumber?) -> String? { + guard let exceptionCode = exceptionCode else { + return nil + } - switch Int32(truncating: exceptionCode) { - case KERN_INVALID_ADDRESS: - return "KERN_INVALID_ADDRESS" - case KERN_PROTECTION_FAILURE: - return "KERN_PROTECTION_FAILURE" - default: - return exceptionCode.stringValue + if exceptionType != nil, Int32(truncating: exceptionType!) == EXC_BAD_ACCESS { + switch Int32(truncating: exceptionCode) { + case KERN_INVALID_ADDRESS: // 1 + return "KERN_INVALID_ADDRESS" + case KERN_PROTECTION_FAILURE: // 2 + return "KERN_PROTECTION_FAILURE" + default: + return exceptionCode.stringValue + } } + return exceptionCode.stringValue } - static func getSignalName(signal: NSNumber?) -> (String?, String?) { + static func getSignalName(signal: NSNumber?) -> String? { guard let signal = signal else { - return (nil, nil) + return nil } switch Int32(truncating: signal) { - case SIGABRT: - return ("SIGABRT", "ABORT") - case SIGBUS: - return ("SIGBUS", nil) - case SIGFPE: - return ("SIGFPE", nil) - case SIGILL: - return ("SIGILL", nil) - case SIGSEGV: - return ("SIGSEGV", nil) - case SIGSYS: - return ("SIGSYS", nil) - case SIGTRAP: - return ("SIGTRAP", nil) + case SIGQUIT: // 3 + return ("SIGQUIT") + case SIGILL: // 4 + return ("SIGILL") + case SIGTRAP: // 5 + return ("SIGTRAP") + case SIGABRT: // 6 + return ("SIGABRT - ABORT") + case SIGFPE: // 8 + return ("SIGFPE") + case SIGKILL: // 9 + return ("SIGKILL") + case SIGBUS: // 10 + return ("SIGBUS") + case SIGSEGV: // 11 + return ("SIGSEGV") + case SIGSYS: // 12 + return ("SIGSYS") default: - return (signal.stringValue, nil) + return (signal.stringValue) } } } diff --git a/Sources/InstanaAgent/Monitors/Metric/Symbolication/DiagnosticSymbolicator.swift b/Sources/InstanaAgent/Monitors/Metric/Symbolication/DiagnosticSymbolicator.swift index 4ffa91d..9db6766 100644 --- a/Sources/InstanaAgent/Monitors/Metric/Symbolication/DiagnosticSymbolicator.swift +++ b/Sources/InstanaAgent/Monitors/Metric/Symbolication/DiagnosticSymbolicator.swift @@ -81,6 +81,23 @@ struct DiagnosticSymbolicator { let headers = outputHeaderSection(operation: operation, diagPayload: diagPayload) stackTrace.setHeader(stHeaders: headers) + // Binary Images section + // process before Threads section so as to build indices of binary images for frames to reference + var dictUUIDs: [String: Int] = [:] + dictUUIDs.reserveCapacity(binaryImages.count) + binaryImages.forEach { bii in + let mAddr = (bii.maxAddress == 0 ? (needToSymbolicate ? " " : "") + : String(format: "0x%llx", bii.maxAddress)) + + stackTrace.appendBinaryImage(startAddr: String(bii.loadAddress), + endAddr: needToSymbolicate ? mAddr : nil, + name: bii.binaryName, + arch: needToSymbolicate ? bii.arch : nil, + uuid: bii.binaryUUID, + path: needToSymbolicate ? bii.fullPath : nil) + dictUUIDs[bii.binaryUUID] = stackTrace.binaryImages.count - 1 + } + // Threads section for idx in 0 ..< threads.count { if operation.isCancelled { return nil } @@ -117,27 +134,21 @@ struct DiagnosticSymbolicator { stOffset = String(symFrame!.symbol!.offset!) } } - stThread.appendFrame(name: frame.binaryName!, + var sampleCount: Int? + if frame.sampleCount != nil, frame.sampleCount! != 1 { + sampleCount = frame.sampleCount! + } + let filteredUUID = frame.binaryUUID!.uuidString.lowercased().filter { $0 != "-" } + stThread.appendFrame(index: dictUUIDs[filteredUUID] ?? -1, + name: frame.binaryName!, address: String(format: "0x%llx", frame.address!), offsetIntoBinaryTextSegment: String(frame.offsetIntoBinaryTextSegment!), + sampleCount: sampleCount, symbol: stSymbol, symbolOffset: stOffset) } stackTrace.appendThread(stThread: stThread) } - - // Binary Images section - binaryImages.forEach { bii in - let mAddr = (bii.maxAddress == 0 ? (needToSymbolicate ? " " : "") - : String(format: "0x%llx", bii.maxAddress)) - - stackTrace.appendBinaryImage(startAddr: String(bii.loadAddress), - endAddr: needToSymbolicate ? mAddr : nil, - name: bii.binaryName, - arch: needToSymbolicate ? bii.arch : nil, - uuid: bii.binaryUUID, - path: needToSymbolicate ? bii.fullPath : nil) - } return stackTrace.serialize() } @@ -167,6 +178,10 @@ struct DiagnosticSymbolicator { stHeaders.append(StHeader(key: "OS Version", value: diagPayload.osVersion!)) } + if diagPayload.platformArchitecture != nil { + stHeaders.append(StHeader(key: "Platform Architecture", value: diagPayload.platformArchitecture!)) + } + // crash stHeaders.append(contentsOf: getCrashHeader(operation: operation, diagPayload: diagPayload)) // cpu @@ -199,27 +214,27 @@ struct DiagnosticSymbolicator { func getCrashHeader(operation: SymbolicationOperation, diagPayload: DiagnosticPayload) -> [StHeader] { var crashHeaders = [StHeader]() - let exceptionType = DiagnosticPayload.getMachExceptionName(exceptionType: diagPayload.exceptionType as? NSNumber, - exceptionCode: diagPayload.exceptionCode as? NSNumber) - let (sigType, sigSubType) = DiagnosticPayload.getSignalName(signal: diagPayload.signal as? NSNumber) - let signal = (sigSubType == nil) ? sigType : sigType! + " - " + sigSubType! - - var str: String? - if exceptionType != nil, signal != nil { - str = exceptionType! + " (" + signal! + ")" - } else if exceptionType != nil { - str = exceptionType! - } else { - str = signal + let exceptionTypeDisplay = DiagnosticPayload.getMachExceptionTypeDisplayName( + exceptionType: diagPayload.exceptionType as? NSNumber) + if exceptionTypeDisplay != nil { + crashHeaders.append(StHeader(key: "Exception Type", value: exceptionTypeDisplay!)) } - if str != nil { - crashHeaders.append(StHeader(key: "Exception Type", value: str!)) + var exceptionCodeDisplay = DiagnosticPayload.getMachExceptionCodeDisplayName( + exceptionType: diagPayload.exceptionType as? NSNumber, + exceptionCode: diagPayload.exceptionCode as? NSNumber) + if exceptionCodeDisplay != nil { + if exceptionCodeDisplay != String(diagPayload.exceptionCode!) { + exceptionCodeDisplay! += " (diagPayload.exceptionCode!)" + } + crashHeaders.append(StHeader(key: "Exception Code", value: exceptionCodeDisplay!)) } - if diagPayload.exceptionCode != nil { - crashHeaders.append(StHeader(key: "Exception Code", value: String(diagPayload.exceptionCode!))) + let signal = DiagnosticPayload.getSignalName(signal: diagPayload.signal as? NSNumber) + if signal != nil { + crashHeaders.append(StHeader(key: "signal", value: signal!)) } + if diagPayload.terminationReason != nil { crashHeaders.append(StHeader(key: "Termination Reason", value: diagPayload.terminationReason!)) } diff --git a/Sources/InstanaAgent/Monitors/Metric/Symbolication/StackTrace.swift b/Sources/InstanaAgent/Monitors/Metric/Symbolication/StackTrace.swift index 1c9163a..d0a68a8 100644 --- a/Sources/InstanaAgent/Monitors/Metric/Symbolication/StackTrace.swift +++ b/Sources/InstanaAgent/Monitors/Metric/Symbolication/StackTrace.swift @@ -71,34 +71,43 @@ class StThread: Codable { frames = [] } - func appendFrame(name: String, address: String, offsetIntoBinaryTextSegment: String, + func appendFrame(index: Int, name: String, address: String, + offsetIntoBinaryTextSegment: String, sampleCount: Int?, symbol: String?, symbolOffset: String?) { - frames.append(StFrame(name: name, address: address, + frames.append(StFrame(index: index, name: name, address: address, offsetIntoBinaryTextSegment: offsetIntoBinaryTextSegment, + sampleCount: sampleCount, symbol: symbol, symbolOffset: symbolOffset)) } } struct StFrame: Codable { - let name: String + let index: Int // index inside Binary Images array + let name: String // deprecated, use index instead let address: String // raw crash payload address let offsetIntoBinaryTextSegment: String // raw crash payload offsetIntoBinaryTextSegment + let sampleCount: Int? // for CPU exception let symbol: String? let symbolOffset: String? private enum CodingKeys: String, CodingKey { + case index = "i" case name = "n" case address = "a" case offsetIntoBinaryTextSegment = "o" + case sampleCount = "c" case symbol = "f" case symbolOffset = "o2" } - init(name: String, address: String, offsetIntoBinaryTextSegment: String, + init(index: Int, name: String, address: String, + offsetIntoBinaryTextSegment: String, sampleCount: Int?, symbol: String?, symbolOffset: String?) { + self.index = index self.name = name self.address = address self.offsetIntoBinaryTextSegment = offsetIntoBinaryTextSegment + self.sampleCount = sampleCount self.symbol = symbol self.symbolOffset = symbolOffset } diff --git a/Sources/InstanaAgent/Monitors/Metric/Symbolication/SymbolicationFrame.swift b/Sources/InstanaAgent/Monitors/Metric/Symbolication/SymbolicationFrame.swift index 935aa6e..60cfdda 100644 --- a/Sources/InstanaAgent/Monitors/Metric/Symbolication/SymbolicationFrame.swift +++ b/Sources/InstanaAgent/Monitors/Metric/Symbolication/SymbolicationFrame.swift @@ -8,6 +8,7 @@ class SymbolicationFrame { let binaryUUID: UUID let binaryName: String let offsetIntoBinaryTextSegment: UInt + var sampleCount: Int? var symbol: SymbolInfo? init(binaryUUID: UUID, diff --git a/Tests/InstanaAgentTests/Configuration/InstanaSystemUtilsTests.swift b/Tests/InstanaAgentTests/Configuration/InstanaSystemUtilsTests.swift index 50656c6..a9d4efd 100644 --- a/Tests/InstanaAgentTests/Configuration/InstanaSystemUtilsTests.swift +++ b/Tests/InstanaAgentTests/Configuration/InstanaSystemUtilsTests.swift @@ -5,7 +5,7 @@ class InstanaSystemUtilsTests: InstanaTestCase { func test_AgentVersion() { // Then - AssertTrue(InstanaSystemUtils.agentVersion == "1.6.7") + AssertTrue(InstanaSystemUtils.agentVersion == "1.6.8") } func test_systemVersion() { diff --git a/Tests/InstanaAgentTests/Mocks/MXDiagnosticPayloadMocks.swift b/Tests/InstanaAgentTests/Mocks/MXDiagnosticPayloadMocks.swift index f5245d6..6aaddb2 100644 --- a/Tests/InstanaAgentTests/Mocks/MXDiagnosticPayloadMocks.swift +++ b/Tests/InstanaAgentTests/Mocks/MXDiagnosticPayloadMocks.swift @@ -114,6 +114,9 @@ class MXCrashDiagnosticMock: MXCrashDiagnostic { override var exceptionCode: NSNumber? { return 0 } + override var signal: NSNumber? { + return 6 + } override var terminationReason: String? { return "mock Crash Termination Reason" } diff --git a/Tests/InstanaAgentTests/Monitors/Metric/DiagnosticPayloadTests.swift b/Tests/InstanaAgentTests/Monitors/Metric/DiagnosticPayloadTests.swift index 5b716a4..dcd0c60 100644 --- a/Tests/InstanaAgentTests/Monitors/Metric/DiagnosticPayloadTests.swift +++ b/Tests/InstanaAgentTests/Monitors/Metric/DiagnosticPayloadTests.swift @@ -46,8 +46,8 @@ class DiagnosticPayloadTests: InstanaTestCase { let (type, msg) = DiagnosticPayload.parseCrashErrorTypeAndMessage(diagnostic: diagnostic) // Then - XCTAssertNotNil(type) - XCTAssertEqual(msg, "mock Crash Termination Reason") + XCTAssertEqual(type, 10) + XCTAssertEqual(msg, "EXC_CRASH (SIGABRT - ABORT) - 0") } @available(iOS 14.0, macOS 12, *) @@ -64,72 +64,73 @@ class DiagnosticPayloadTests: InstanaTestCase { XCTAssertEqual(msg, "crash diagnostic") } - func test_getMachExceptionName() { - var ret = DiagnosticPayload.getMachExceptionName(exceptionType: EXC_BAD_ACCESS as NSNumber, - exceptionCode: KERN_INVALID_ADDRESS as NSNumber) - XCTAssertEqual(ret, "EXC_BAD_ACCESS - KERN_INVALID_ADDRESS") //1 - 1 + func test_getMachExceptionTypeDisplayName() { + var ret = DiagnosticPayload.getMachExceptionTypeDisplayName(exceptionType: EXC_BAD_ACCESS as NSNumber) + XCTAssertEqual(ret, "EXC_BAD_ACCESS") //1 - ret = DiagnosticPayload.getMachExceptionName(exceptionType: EXC_BAD_ACCESS as NSNumber, - exceptionCode: KERN_PROTECTION_FAILURE as NSNumber) - XCTAssertEqual(ret, "EXC_BAD_ACCESS - KERN_PROTECTION_FAILURE") //1 - 2 - - ret = DiagnosticPayload.getMachExceptionName(exceptionType: EXC_BAD_ACCESS as NSNumber, - exceptionCode: 333 as NSNumber) - XCTAssertEqual(ret, "EXC_BAD_ACCESS - 333") //1 - 333 - - ret = DiagnosticPayload.getMachExceptionName(exceptionType: EXC_BAD_INSTRUCTION as NSNumber, exceptionCode: nil) + ret = DiagnosticPayload.getMachExceptionTypeDisplayName(exceptionType: EXC_BAD_INSTRUCTION as NSNumber) XCTAssertEqual(ret, "EXC_BAD_INSTRUCTION") //2 - ret = DiagnosticPayload.getMachExceptionName(exceptionType: EXC_ARITHMETIC as NSNumber, exceptionCode: nil) + ret = DiagnosticPayload.getMachExceptionTypeDisplayName(exceptionType: EXC_ARITHMETIC as NSNumber) XCTAssertEqual(ret, "EXC_ARITHMETIC") //3 - ret = DiagnosticPayload.getMachExceptionName(exceptionType: EXC_BREAKPOINT as NSNumber, exceptionCode: nil) + ret = DiagnosticPayload.getMachExceptionTypeDisplayName(exceptionType: 4) + XCTAssertEqual(ret, "4") //4 + + ret = DiagnosticPayload.getMachExceptionTypeDisplayName(exceptionType: EXC_BREAKPOINT as NSNumber) XCTAssertEqual(ret, "EXC_BREAKPOINT") //6 - ret = DiagnosticPayload.getMachExceptionName(exceptionType: EXC_GUARD as NSNumber, exceptionCode: nil) + ret = DiagnosticPayload.getMachExceptionTypeDisplayName(exceptionType: EXC_CRASH as NSNumber) + XCTAssertEqual(ret, "EXC_CRASH") //10 + + ret = DiagnosticPayload.getMachExceptionTypeDisplayName(exceptionType: EXC_RESOURCE as NSNumber) + XCTAssertEqual(ret, "EXC_RESOURCE") //11 + + ret = DiagnosticPayload.getMachExceptionTypeDisplayName(exceptionType: EXC_GUARD as NSNumber) XCTAssertEqual(ret, "EXC_GUARD") //12 } - func test_getMachExceptionBadAccessCodeName() { - var ret = DiagnosticPayload.getMachExceptionBadAccessCodeName(exceptionType: 111 as NSNumber, exceptionCode: nil) + func test_getMachExceptionCodeDisplayName() { + var ret = DiagnosticPayload.getMachExceptionCodeDisplayName(exceptionType: 111 as NSNumber, exceptionCode: nil) XCTAssertNil(ret) - ret = DiagnosticPayload.getMachExceptionBadAccessCodeName(exceptionType: EXC_BAD_ACCESS as NSNumber, exceptionCode: nil) + ret = DiagnosticPayload.getMachExceptionCodeDisplayName(exceptionType: EXC_BAD_ACCESS as NSNumber, exceptionCode: nil) XCTAssertNil(ret) + + ret = DiagnosticPayload.getMachExceptionCodeDisplayName(exceptionType: EXC_BAD_ACCESS as NSNumber, exceptionCode: 1) + XCTAssertEqual(ret, "KERN_INVALID_ADDRESS") + + ret = DiagnosticPayload.getMachExceptionCodeDisplayName(exceptionType: EXC_BAD_ACCESS as NSNumber, exceptionCode: 2) + XCTAssertEqual(ret, "KERN_PROTECTION_FAILURE") + + ret = DiagnosticPayload.getMachExceptionCodeDisplayName(exceptionType: EXC_BAD_ACCESS as NSNumber, exceptionCode: 3) + XCTAssertEqual(ret, "3") } func test_getSignalName() { - var (sig, sub) = DiagnosticPayload.getSignalName(signal: SIGABRT as NSNumber) - XCTAssertEqual(sig, "SIGABRT") //6 - XCTAssertEqual(sub, "ABORT") + var sig = DiagnosticPayload.getSignalName(signal: SIGABRT as NSNumber) + XCTAssertEqual(sig, "SIGABRT - ABORT") //6 - (sig, sub) = DiagnosticPayload.getSignalName(signal: SIGBUS as NSNumber) + sig = DiagnosticPayload.getSignalName(signal: SIGBUS as NSNumber) XCTAssertEqual(sig, "SIGBUS") //10 - XCTAssertNil(sub) - (sig, sub) = DiagnosticPayload.getSignalName(signal: SIGFPE as NSNumber) + sig = DiagnosticPayload.getSignalName(signal: SIGFPE as NSNumber) XCTAssertEqual(sig, "SIGFPE") //8 - XCTAssertNil(sub) - (sig, sub) = DiagnosticPayload.getSignalName(signal: SIGILL as NSNumber) + sig = DiagnosticPayload.getSignalName(signal: SIGILL as NSNumber) XCTAssertEqual(sig, "SIGILL") //4 - XCTAssertNil(sub) - (sig, sub) = DiagnosticPayload.getSignalName(signal: SIGSEGV as NSNumber) + sig = DiagnosticPayload.getSignalName(signal: SIGSEGV as NSNumber) XCTAssertEqual(sig, "SIGSEGV") //11 - XCTAssertNil(sub) - (sig, sub) = DiagnosticPayload.getSignalName(signal: SIGSYS as NSNumber) + sig = DiagnosticPayload.getSignalName(signal: SIGSYS as NSNumber) XCTAssertEqual(sig, "SIGSYS") //12 - XCTAssertNil(sub) - (sig, sub) = DiagnosticPayload.getSignalName(signal: SIGTRAP as NSNumber) + sig = DiagnosticPayload.getSignalName(signal: SIGTRAP as NSNumber) XCTAssertEqual(sig, "SIGTRAP") //5 - XCTAssertNil(sub) - (sig, sub) = DiagnosticPayload.getSignalName(signal: 222 as NSNumber) + sig = DiagnosticPayload.getSignalName(signal: 222 as NSNumber) XCTAssertEqual(sig, "222") - XCTAssertNil(sub) } func test_canSymbolicate() {