Files
sing-box-for-apple/Library/Shared/NativeCrashReporter.swift
T

83 lines
2.8 KiB
Swift

import CrashReporter
import Foundation
import os
public enum NativeCrashReporter {
private static let logger = Logger(category: "NativeCrashReporter")
private static let installLock = NSLock()
private static var reporter: PLCrashReporter?
public static func installForCurrentProcess(basePath: URL? = nil) {
installLock.lock()
defer {
installLock.unlock()
}
guard reporter == nil else {
return
}
let crashBasePath = basePath ?? CrashReportArchive.pendingNativeCrashBaseDirectory
do {
try FileManager.default.createDirectory(at: crashBasePath, withIntermediateDirectories: true)
let config = PLCrashReporterConfig(
signalHandlerType: .BSD,
symbolicationStrategy: [],
basePath: crashBasePath.path
)
guard let crashReporter = PLCrashReporter(configuration: config) else {
logger.warning("Failed to create PLCrashReporter instance")
return
}
try crashReporter.enableAndReturnError()
reporter = crashReporter
} catch {
logger.warning("Failed to enable native crash reporting: \(error.localizedDescription)")
}
}
public static func loadAndPurgePendingCrashReportData() -> Data? {
installLock.lock()
guard let reporter else {
installLock.unlock()
return nil
}
installLock.unlock()
guard reporter.hasPendingCrashReport() else {
return nil
}
let data = try? reporter.loadPendingCrashReportDataAndReturnError()
reporter.purgePendingCrashReport()
return data
}
public static func archiveLiveReportForCurrentProcess() {
installLock.lock()
guard let reporter else {
installLock.unlock()
return
}
installLock.unlock()
do {
let data = try reporter.generateLiveReportAndReturnError()
let crashReport = try PLCrashReport(data: data)
guard let text = PLCrashReportTextFormatter.stringValue(for: crashReport, with: PLCrashReportTextFormatiOS),
!text.isEmpty
else {
return
}
let crashDate = crashReport.systemInfo.timestamp ?? Date()
_ = try CrashReportArchive.writeArchivedReport(
contents: CrashReportArtifactContents(nativeLog: text),
date: crashDate,
metadata: CrashReportMetadataBuilder.nativeMetadata(for: crashReport, content: text, source: "Application")
)
} catch {
logger.warning("Failed to archive live native crash report: \(error.localizedDescription)")
}
}
}