此bounty已结束。回答此问题可获得+50声望奖励。奖励宽限期将在23小时后结束。Muni Perez希望引起更多人关注此问题。
你好!
我尝试对一段代码运行单元测试,但在执行以下代码时,遇到EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP)异常:
/// Decompresses the data using the gzip deflate algorithm. Self is expected to be a gzip deflate
/// stream according to [RFC-1952](https://tools.ietf.org/html/rfc1952).
/// - returns: uncompressed data
func gunzip() -> Data?
{
// 10 byte header + data + 8 byte footer. See https://tools.ietf.org/html/rfc1952#section-2
let overhead = 10 + 8
guard count >= overhead else { return nil }
typealias GZipHeader = (id1: UInt8, id2: UInt8, cm: UInt8, flg: UInt8, xfl: UInt8, os: UInt8)
let hdr: GZipHeader = withUnsafeBytes { (ptr: UnsafePointer<UInt8>) -> GZipHeader in
// +---+---+---+---+---+---+---+---+---+---+
// |ID1|ID2|CM |FLG| MTIME |XFL|OS |
// +---+---+---+---+---+---+---+---+---+---+
return (id1: ptr[0], id2: ptr[1], cm: ptr[2], flg: ptr[3], xfl: ptr[8], os: ptr[9])
}
typealias GZipFooter = (crc32: UInt32, isize: UInt32)
let ftr: GZipFooter = withUnsafeBytes { (bptr: UnsafePointer<UInt8>) -> GZipFooter in
// +---+---+---+---+---+---+---+---+
// | CRC32 | ISIZE |
// +---+---+---+---+---+---+---+---+
return bptr.advanced(by: count - 8).withMemoryRebound(to: UInt32.self, capacity: 2) { ptr in
return (ptr[0].littleEndian, ptr[1].littleEndian)
}
}
// Wrong gzip magic or unsupported compression method
guard hdr.id1 == 0x1f && hdr.id2 == 0x8b && hdr.cm == 0x08 else { return nil }
let has_crc16: Bool = hdr.flg & 0b00010 != 0
let has_extra: Bool = hdr.flg & 0b00100 != 0
let has_fname: Bool = hdr.flg & 0b01000 != 0
let has_cmmnt: Bool = hdr.flg & 0b10000 != 0
let cresult: Data? = withUnsafeBytes { (ptr: UnsafePointer<UInt8>) -> Data? in
var pos = 10 ; let limit = count - 8
if has_extra {
pos += ptr.advanced(by: pos).withMemoryRebound(to: UInt16.self, capacity: 1) {
return Int($0.pointee.littleEndian) + 2 // +2 for xlen
}
}
if has_fname {
while pos < limit && ptr[pos] != 0x0 { pos += 1 }
pos += 1 // skip null byte as well
}
if has_cmmnt {
while pos < limit && ptr[pos] != 0x0 { pos += 1 }
pos += 1 // skip null byte as well
}
if has_crc16 {
pos += 2 // ignoring header crc16
}
guard pos < limit else { return nil }
let config = (operation: COMPRESSION_STREAM_DECODE, algorithm: COMPRESSION_ZLIB)
return perform(config, source: ptr.advanced(by: pos), sourceSize: limit - pos)
}
guard let inflated = cresult else { return nil }
guard ftr.isize == UInt32(truncatingIfNeeded: inflated.count) else { return nil }
guard ftr.crc32 == inflated.crc32().checksum else { return nil }
return inflated
}
fileprivate extension Data {
func withUnsafeBytes<ResultType, ContentType>(_ body: (UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType
{
return try self.withUnsafeBytes({ (rawBufferPointer: UnsafeRawBufferPointer) -> ResultType in
return try body(rawBufferPointer.bindMemory(to: ContentType.self).baseAddress!)
})
}
}
这部分代码总是抛出上述异常:
这个问题一直在发生,这段代码已经有2年没有碰过了,在MacOS 10.15的云管道(Azure)中运行也没有失败
它在运行 Monterey (12.6)和Xcode 14的多台MacOS设备上失败。
有人知道是什么引起的吗?
我知道这个问题很模糊,但这是我唯一的背景。
谢谢
1条答案
按热度按时间fcwjkofz1#
根据您提供的代码段,没有明显的错误会导致EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP)异常。该错误似乎与内存管理有关,代码使用了指针,
bptr
指向的内存似乎无效或与withMemoryRebound
函数中指定的类型不匹配。导致此问题的一个可能原因是代码需要特定的内存布局或对齐方式,而新版本的macOS上不存在。您可以尝试以下几种方法:
lldb
来跟踪问题,看看是哪个指令导致了错误,这将帮助您了解问题并修复它。