Apple Watch 在位操作上崩溃,错误代码为 Thread1:exc_breakpoint(code=exc_arm_breakpoint,subcode=0xe7ffdefe)
Apple Watch crashes on bit operations with error code Thread1: exc_breakpoint(code=exc_arm_breakpoint,subcode=0xe7ffdefe)
我在 Apple Watch 上使用 SHA1 散列用户数据,当 运行 SHA1Bytes
函数时,我收到以下错误:
Thread1: exc_breakpoint(code=exc_arm_breakpoint,subcode=0xe7ffdefe).
This specific line gives me the error:
j = ( UInt32((msg[i]<<24) | (msg[i+1]<<16) | (msg[i+2]<<8) | msg[i+3]) )
这是从中提取上述行的代码段:
class func SHA1Bytes(msg: [Int])->String{
func rotateLeft(number: UInt32, rotateBy: UInt32)->UInt32{
return ((number << rotateBy) | (number>>(32-rotateBy)))
}
func cvt_hex(value: UInt32)->String{
var str = ""
for i:UInt32 in stride(from: 7, through: 0, by: -1){
let v: UInt32 = (value >> (i*4)&0x0f)
str += String(v,radix: 16, uppercase: false)
}
return str
}
var W = [UInt32](repeating: 0, count: 80)
var H0 = UInt32("67452301",radix: 16)!
var H1 = UInt32("EFCDAB89",radix: 16)!
var H2 = UInt32("98BADCFE",radix: 16)!
var H3 = UInt32("10325476",radix: 16)!
var H4 = UInt32("C3D2E1F0",radix: 16)!
var wordArray = [UInt32]()
for k in stride(from: 0, to: msg.count-3, by: 4) {
let j = ( UInt32((msg[k]<<24) | (msg[k+1]<<16) | (msg[k+2]<<8) | msg[k+3]) )
wordArray.append(j)
}
...
return encoded.uppercased()
}
完全相同的代码在 iOS 游乐场中运行完美,但在第一代 Apple Watch 上 运行 时会崩溃。我已经检查过并且输入数组存在,我正在尝试访问它的现有元素并且 j
的结果不应该溢出。
该代码因以下变量值而失败:
j=(UInt32) 2308511418, k=(Int)48, msg=([Int])56values
这些是 msg 的值:
[47] Int 217
[48] Int 137
[49] Int 153
[50] Int 22
[51] Int 186
[52] Int 163
[53] Int 41
[54] Int 208
[55] Int 104
第一代 Apple Watch 是 32 位设备,与 64 位设备相比具有不同的溢出限制。
在 32 位设备上,Int
类型是 32 位,您可能会转移到符号位。
在 playground 中尝试以下操作:
UInt32(Int64(153) << 24) // Equivalent to your code
UInt32(Int32(153) << 24) // Simulates a 32-bit device and crashes.
UInt32(153) << 24 // A possible solution
我设法弄清楚即使 UInt32 溢出,模拟器也不会崩溃,但是,在这种情况下,32 位 Apple Watch 确实会崩溃。
解决方案是使用一个溢出运算符,它只存在于加法、减法和乘法中。因此,我将按位左移更改为乘以 2^(要移位的位数)。
这是正确的解决方案:UInt32(msg[k])&*UInt32(1<<24)
let j = (UInt32(msg[k])&*UInt32(1<<24))|UInt32(msg[k+1]&*(1<<16))|UInt32(msg[k+2]&*(1<<8))|UInt32(msg[k+3])
我在 Apple Watch 上使用 SHA1 散列用户数据,当 运行 SHA1Bytes
函数时,我收到以下错误:
Thread1: exc_breakpoint(code=exc_arm_breakpoint,subcode=0xe7ffdefe). This specific line gives me the error:
j = ( UInt32((msg[i]<<24) | (msg[i+1]<<16) | (msg[i+2]<<8) | msg[i+3]) )
这是从中提取上述行的代码段:
class func SHA1Bytes(msg: [Int])->String{
func rotateLeft(number: UInt32, rotateBy: UInt32)->UInt32{
return ((number << rotateBy) | (number>>(32-rotateBy)))
}
func cvt_hex(value: UInt32)->String{
var str = ""
for i:UInt32 in stride(from: 7, through: 0, by: -1){
let v: UInt32 = (value >> (i*4)&0x0f)
str += String(v,radix: 16, uppercase: false)
}
return str
}
var W = [UInt32](repeating: 0, count: 80)
var H0 = UInt32("67452301",radix: 16)!
var H1 = UInt32("EFCDAB89",radix: 16)!
var H2 = UInt32("98BADCFE",radix: 16)!
var H3 = UInt32("10325476",radix: 16)!
var H4 = UInt32("C3D2E1F0",radix: 16)!
var wordArray = [UInt32]()
for k in stride(from: 0, to: msg.count-3, by: 4) {
let j = ( UInt32((msg[k]<<24) | (msg[k+1]<<16) | (msg[k+2]<<8) | msg[k+3]) )
wordArray.append(j)
}
...
return encoded.uppercased()
}
完全相同的代码在 iOS 游乐场中运行完美,但在第一代 Apple Watch 上 运行 时会崩溃。我已经检查过并且输入数组存在,我正在尝试访问它的现有元素并且 j
的结果不应该溢出。
该代码因以下变量值而失败:
j=(UInt32) 2308511418, k=(Int)48, msg=([Int])56values
这些是 msg 的值:
[47] Int 217
[48] Int 137
[49] Int 153
[50] Int 22
[51] Int 186
[52] Int 163
[53] Int 41
[54] Int 208
[55] Int 104
第一代 Apple Watch 是 32 位设备,与 64 位设备相比具有不同的溢出限制。
在 32 位设备上,Int
类型是 32 位,您可能会转移到符号位。
在 playground 中尝试以下操作:
UInt32(Int64(153) << 24) // Equivalent to your code
UInt32(Int32(153) << 24) // Simulates a 32-bit device and crashes.
UInt32(153) << 24 // A possible solution
我设法弄清楚即使 UInt32 溢出,模拟器也不会崩溃,但是,在这种情况下,32 位 Apple Watch 确实会崩溃。
解决方案是使用一个溢出运算符,它只存在于加法、减法和乘法中。因此,我将按位左移更改为乘以 2^(要移位的位数)。
这是正确的解决方案:UInt32(msg[k])&*UInt32(1<<24)
let j = (UInt32(msg[k])&*UInt32(1<<24))|UInt32(msg[k+1]&*(1<<16))|UInt32(msg[k+2]&*(1<<8))|UInt32(msg[k+3])