Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BAD_ACCESS during recursive calls in Swift

While toying with Swift, I've encountered a situation which crashes and I still not have figured out why.

Let define:

class TestClass {

    var iteration: Int = 0

    func tick() -> Void{
        if iteration > 100000 {
            print("Done!")
            return
        }
        iteration++
        tick()
    }
}

The tick() function calls itself and each time increments iteration. Any call of the type

let test = TestClass()
test.tick()

makes the program crash after a rather small number of recursions (around 50000 on my iMac), with a EXC_BAD_ACCESS error: The EXC_BAD_ACCESS

If I define a similar struct instead of a class, there is no crash (at least not in these limits). Note that when it crashes, the program uses only a few MB of RAM.

I can't explain yet why this crashes. Does anybody have an explanation? The callbackStorage value seem suspicious but I haven't found any pointer on this.

like image 994
Tom Avatar asked Jun 16 '15 19:06

Tom


1 Answers

In your program, each thread has something called a stack. A stack is a LIFO (last in first out) - a data container that has 2 main operations: push, which adds an element to the top of the stack, and pop, which removes an item from the top of the stack.

When your program calls a function, it pushes the location of the code that called the function, called the return address, (and sometimes some of the function's arguments also), then jumps to that function's code. (The function's local variables are also stored on the stack.) When the function returns, it pops the return address off of the stack and jumps to it.

However, the stack has a limited size. In your example, your function calls itself so many times that there isn't enough room in the stack for all of the return addresses, arguments, and local variables. This is called a stack overflow (which is where this website got its name from). The program tries to write past the end of the stack, causing a segfault.

The reason why the program doesn't crash when you use a struct is likely, as dans3itz said, because classes have more overhead than structs.

like image 187
NobodyNada Avatar answered Sep 22 '22 13:09

NobodyNada