swiftswift3apple-watchwatchos-3

Apple Watch crashes on bit operations with error code Thread1: exc_breakpoint(code=exc_arm_breakpoint,subcode=0xe7ffdefe)


I am hashing user data on an Apple Watch using SHA1 and when running the SHA1Bytes function, I get the following error:

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]) )

This is the piece of code from which the above line is extracted:

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()
    }

The exact same code runs perfectly in an iOS Playground, but crashes when running on a first generation Apple Watch. I have checked and the input array exists, I am trying to access existing elements of it and the result of j should not overflow. The code fails with the following variable values:

j=(UInt32) 2308511418, k=(Int)48, msg=([Int])56values

and these are the values of 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

Solution

  • I managed to figure out that the simulator is not crashing even if a UInt32 overflows, however, the 32bit Apple Watch does crash in this case. The solution was to use an overflow operator, which only exists for addition, subtraction and multiplication. Hence, I changed bitwise left shift to multiplication by 2^(number of bits to be shifted). This is the correct solution: 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])