In ARM mode we do an opt in noreturn functions that uses branch instead of calls and explicitly save the pc (r151645): mov lr, pc b _bar This isn't possible in thumb2 mode because the mode bit doesnt get set (r167657). However, we currently emit a branch and link but do not save the LR, which leads to bad backtraces coming from noreturn functions. Example: define void @a() noreturn nounwind ssp { tail call void @b() unreachable } define void @b() noreturn nounwind ssp { tail call void @abort() noreturn nounwind unreachable } declare void @abort() noreturn Currently generates: _a: bl _b _b: push {r7, lr} mov r7, sp blx _abort Leading to bad backtraces. This patch generates instead: _a: push {r7, lr} mov r7, sp bl _b _b: push {r7, lr} mov r7, sp blx _abort
Details
- Reviewers
t.p.northover MatzeB
Diff Detail
- Repository
- rL LLVM
Event Timeline
Hi Bruno,
I guess that it is general goodness to have the right stack trace when you debug something, but I thought noreturn + nounwind allow the compiler to trash the information for optimization purposes?
I am not saying that your patch is wrong, I am pointing out that it seems we regress some pattern to improve the debug experience, and I am not sure this is something we should do.
My 2c.
Cheers,
-Quentin
Yep, thanks for pointing that out, I completely missed the unwind meaning here!
I am not saying that your patch is wrong, I am pointing out that it seems we regress some pattern to improve the debug experience, and I am not sure this is something we should do.
Seems reasonable! One can always use "-funwind-tables" to override the behavior and LR will be there.
Thanks,
Isn't that the point of nounwind to not emit unwind information?
If you omit the "nounwind" from the function declaration you get your stack save.