Getting stack size using lldb

If you suspect stack overflow happening and for some reason don't trust Xcode diagnostic tools catching those (seems unlikely :thinking:), you may use this manual "checkStack" call every here and there:

func checkStack(param: Any) {
    var x: UInt8 = 1
    func approximateSP(_ p: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer {
        p
    }
    let sp = approximateSP(&x)
    let top = pthread_get_stackaddr_np(pthread_self())
    let size = pthread_get_stacksize_np(pthread_self())
    let bottom = top - size
    let safetySize = min(10*1024, size / 10)
    let safeBottom = bottom + safetySize // "relatively" safe stack bottom
    #if ENABLE_PRINTOUT
    print("top    : \(top)")
    print("SP     : \(sp) (approximate)")
    print("safe   : \(safeBottom) (relatively safe bottom)")
    print("bottom : \(bottom)")
    print("size   : \(size)")
    print("used   : \(top - sp) [\(100*(top - sp)/size)%]")
    print("param  : \(param)")
    print()
    #endif
    
    precondition(sp > safeBottom && sp <= top, "stack is about to overflow \(sp - bottom) bytes left, depth: \(param)")
}

func testRecursion(level: Int = 0) {
    checkStack(param: level)
    testRecursion(level: level + 1)
}

testRecursion()

With printout enabled it prints something like:

top    : 0x000000016ddfc000
SP     : 0x000000016dca9c77 (approximate)
safe   : 0x000000016d602800 (relatively safe bottom)
bottom : 0x000000016d600000
size   : 8372224
used   : 1385353 [16%]
param  : 17197

and with / without printout it checks available stack space and warns you if you are about to crash it with this:

failed: stack is about to overflow 10231 bytes left, depth: 104405

In the above for the safety margin I'm using the minimum of these two numbers: 10K and 10% of total stack size, adjust this according to your needs.

Edit: and when in lldb you can use the same calls:

(lldb) p pthread_get_stackaddr_np(pthread_self())
(UnsafeMutableRawPointer) $R0 = 0x16d600000
(lldb) p pthread_get_stacksize_np(pthread_self())
(Int) $R1 = 8372224
1 Like