I'm trying to calculate stack size based on thread backtrace
output. I thought it would be simple: getting the top frame and bottom frame's addresses and do a subtraction. My laptop has Intel CPU, so I expect the top frame has lower address.
But when I examine the log I find something unexpected: some higher frames have higher addresses then frames under them. See frame 2 and 3. I wonder is it normal?
(lldb) thread backtrace
* thread #5, queue = 'com.apple.root.default-qos.cooperative', stop reason = breakpoint 1.1
* frame #0: 0x000000013dd261e2 acdbCNTests`CEWViewMapIterator.init(map=$s6acdbCN8AllACMapVyAA9DDCEWViewVAA11FundCEWViewVAA9TDCEWViewVAA9FICEWViewVGD @ 0x0000700009020950) at cewViewMapT+iterator.swift:72:9
frame #1: 0x000000013dd25fe3 acdbCNTests`AllACMap<>.makeIterator(self=acdbCN.AllACMap<acdbCN.DDCEWView, acdbCN.FundCEWView, acdbCN.TDCEWView, acdbCN.FICEWView> @ 0x00007000090209f0) at cewViewMapT+iterator.swift:12:16
frame #2: 0x00000001423155c5 acdbCNTests`_cews(acData=$s6acdbCN8AllACMapVyAA6DDDataVAA8FundDataVAA6TDDataVAA6FIDataVGD @ 0x0000700009020be0, today=(date = 2023-02-18 16:00:00 UTC), acResolver=acdbCN.EntityCollection @ 0x00006000006027f0) at storeViewsT.swift:31:30
frame #3: 0x0000000142314f91 acdbCNTests`StoreViews.init(entities=acdbCN.EntityCollection @ 0x0000700009021ad0, acData=$s6acdbCN8AllACMapVyAA6DDDataVAA8FundDataVAA6TDDataVAA6FIDataVGD @ 0x0000700009020d70, today=(date = 2023-02-18 16:00:00 UTC)) at storeViewsT.swift:20:16
frame #4: 0x000000013db2d50b acdbCNTests`Store._run(action=0x000000013d7d78d0 acdbCNTests`partial apply forwarder for closure #1 (inout acdbCN.EntityCollection, inout acdbCN.ACChangeMap<acdbCN.S1Change>) throws -> () in acdbCNTests.DemoStore._generateSingleExpense(acID: acdbCN.Identifier<acdbCN.DD>, name: Swift.String, expenseMonthInterval: Swift.Int, expenseMonthDay: Swift.Int, expenseAmount: __C.NSDecimal) -> () at <compiler-generated>, self=acdbCN.Store @ 0x0000700009022540) at storeT+run.swift:84:30
frame #5: 0x000000013db2e495 acdbCNTests`Store.run(checkLimit=0x000000013d7c71b0 acdbCNTests`closure #1 (acdbCN.Store) -> Swift.Bool in default argument 0 of acdbCN.Store.run(checkLimit: (acdbCN.Store) -> Swift.Bool, _: (inout acdbCN.EntityCollection, inout acdbCN.ACChangeMap<acdbCN.S1Change>) throws -> ()) -> acdbCN.ACDBResult at <compiler-generated>, action=0x000000013d7d78d0 acdbCNTests`partial apply forwarder for closure #1 (inout acdbCN.EntityCollection, inout acdbCN.ACChangeMap<acdbCN.S1Change>) throws -> () in acdbCNTests.DemoStore._generateSingleExpense(acID: acdbCN.Identifier<acdbCN.DD>, name: Swift.String, expenseMonthInterval: Swift.Int, expenseMonthDay: Swift.Int, expenseAmount: __C.NSDecimal) -> () at <compiler-generated>, self=acdbCN.Store @ 0x0000700009022540) at storeT+run.swift:110:32
frame #6: 0x000000013d7cc3ce acdbCNTests`DemoStore.run(action=0x000000013d7d78d0 acdbCNTests`partial apply forwarder for closure #1 (inout acdbCN.EntityCollection, inout acdbCN.ACChangeMap<acdbCN.S1Change>) throws -> () in acdbCNTests.DemoStore._generateSingleExpense(acID: acdbCN.Identifier<acdbCN.DD>, name: Swift.String, expenseMonthInterval: Swift.Int, expenseMonthDay: Swift.Int, expenseAmount: __C.NSDecimal) -> () at <compiler-generated>, self=acdbCNTests.DemoStore @ 0x0000700009022540) at loadDemoData.swift:152:23
frame #7: 0x000000013d7d0094 acdbCNTests`DemoStore._generateSingleExpense(acID=(uuid = AEEA457D-A12C-4ECE-A046-2BB1A853D139), name="休假", expenseMonthInterval=12, expenseMonthDay=20, expenseAmount=10000.000000
, self=acdbCNTests.DemoStore @ 0x0000700009022540) at loadDemoData.swift:366:13
frame #8: 0x000000013d7ce8ee acdbCNTests`DemoStore.generateExpenseOnCashAC(self=acdbCNTests.DemoStore @ 0x0000700009022540) at loadDemoData.swift:253:9
frame #9: 0x000000013d7cbb62 acdbCNTests`DemoStore.generateExpenseAC(self=acdbCNTests.DemoStore @ 0x0000700009022540) at loadDemoData.swift:280:9
frame #10: 0x000000013d7c8adb acdbCNTests`DemoStore.init() at loadDemoData.swift:142:9
frame #11: 0x000000013d7c86c7 acdbCNTests`closure #1 in GenerateDemoDataTest.testLoadDemo() at loadDemoData.swift:61:66
frame #12: 0x000000013d7c7ca3 acdbCNTests`generateStore(filename="abc", createStore=0x000000013d7c8690 acdbCNTests`closure #1 () -> acdbCN.Store in acdbCNTests.GenerateDemoDataTest.testLoadDemo() async -> () at loadDemoData.swift:61) at loadDemoData.swift:18:17
frame #13: 0x000000013d7c8209 acdbCNTests`asyncGenerateStore(filename="abc", createStore=0x000000013d7c8690 acdbCNTests`closure #1 () -> acdbCN.Store in acdbCNTests.GenerateDemoDataTest.testLoadDemo() async -> () at loadDemoData.swift:61) at loadDemoData.swift:27:5
frame #14: 0x000000013d7c8430 acdbCNTests`GenerateDemoDataTest.testLoadDemo(self=0x00007fe357f052a0) at loadDemoData.swift:61
frame #15: 0x000000013d7c8c60 acdbCNTests`@objc closure #1 in GenerateDemoDataTest.testLoadDemo() at <compiler-generated>:0
frame #16: 0x000000013d7cbf80 acdbCNTests`partial apply for @objc closure #1 in GenerateDemoDataTest.testLoadDemo() at <compiler-generated>:0
frame #17: 0x000000013d7de300 acdbCNTests`thunk for @escaping @callee_guaranteed @Sendable @async () -> () at <compiler-generated>:0
frame #18: 0x000000013d7de500 acdbCNTests`partial apply for thunk for @escaping @callee_guaranteed @Sendable @async () -> () at <compiler-generated>:0
frame #19: 0x000000013d7de3e0 acdbCNTests`specialized thunk for @escaping @callee_guaranteed @Sendable @async () -> (@out A) at <compiler-generated>:0
frame #20: 0x000000013d7de720 acdbCNTests`partial apply for specialized thunk for @escaping @callee_guaranteed @Sendable @async () -> (@out A) at <compiler-generated>:0
UPDATE: The displayed addresses of frame 2 and 3 are not in the valid range of stack. So maybe it's just some kind of optimization (frame 2 is a global func call, and frame 3 is a init() call) and LLDB shows the address of the func that's actually called. instead of the frame address? If so, I think I can still calculate the stack size by subtracting top and bottom frame addresses?