Exc_Badinstruction When Computing a Hash Value

EXC_BADINSTRUCTION when computing a hash value

The Swift language does not allow for math to overflow when using the basic arithmetic operators (as noted in the Arithmetic Operators area of the Basic Operators section of The Swift Programming Guide). If the 3 hash values you're adding exceed Int.max (Hashable declares the hashValue as an Int), you will receive that crash type.

If you want overflow, you have to use the overflow arithmetic operators, as defined in the Overflow Operators area of the Basic Operators section of the Swift Programming Guide.

They are: &+ &- and &*

EXC_BAD_INSTRUCTION evaluating boolean comparisons

Based on the error I would guess that the values indexChosen and/or offset are not what you expect, and the addition statement is causing rollover to occur. You can verify this by removing the math from the if statement and checking to see if the crash happens in the math specifically:

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let newIndex = indexChosen + offset
if (homeChosen == true && section > 0 && newIndex == section) {

If the crash is occurring on the line with the addition, see my answer to this question.

Swift hashValue crashes application

Update (Swift 4.2+)

If you do need to manually implement the Hashable conformance for some reason, upgrade to Swift 4.2+ to adopt the new Hashable protocol, which gives you an easy-to-use Hasher object that internally uses a well-designed hashing algorithm.

For example, the above hash function would be transformed into

func hash(into hasher: inout Hasher) {
hasher.combine(id)
hasher.combine(name)
hasher.combine(location)
}

Update (Swift 4.1+)

Upgrade to Swift 4.1 to gain compiler support for automatic synthesis of Hashable and Equatable conformance! See the Swift Evolution proposal for more details.


Original Answer

Yup, this looks like integer overflow. You can try using the overflow versions of the multiplication and addition operators: &* and &+.

Read more in The Swift Programming Language book.

Indexes as Ints in Swift

f = key.characters.indexOf(char) is an index into the characters
of key, therefore you have to compute the distance to the start index of key, not s:

z = z * key.startIndex.distanceTo(key.characters.indexOf(char)!))

which you can move back to your if-let block:

    if let f = key.characters.indexOf(char) {
z = z * key.startIndex.distanceTo(f)
}

You also might want to use the overflow operator &*

    if let f = key.characters.indexOf(char) {
z = z &* key.startIndex.distanceTo(f)
}

otherwise the application will crash if the result of the
multiplication does not fit into an Int.


Generally, the indexes of a Swift String can only be used
with the same string (regardless of string length), as the following
example demonstrates:

let s1 = "abc"
let i1 = s1.characters.indexOf("b")!
print(i1) // 1

let s2 = "abc"
print(s2.characters.count) // 6

let d2 = s2.startIndex.distanceTo(i1) // fatal error: can not increment endIndex

Accessing database in a command

It seems like this might be the way to go:

func run(using context: CommandContext) throws -> EventLoopFuture<Void> {
let email = try context.argument("email")
let password = try context.requireOption("password")
let passwordHash = try BCrypt.hash(password)
let user = User(email: email, password: password)

return context.container.withNewConnection(to: .psql) { db in
return user.save(on: db).transform(to: ())
}
}

Swift: How to disable integer overflow / underflow traps for a function

You can use addWithOverflow or subtractWithOverflow class method of Int, UInt8 etc types

E.g. let b = UInt8.subtractWithOverflow(a, 237)



Related Topics



Leave a reply



Submit