Details
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
I do not object strongly, but two notes:
- I think that the alignment is more required by hw, which auto-aligns %rsp on traps
- What if we got a bug and stack becomes misaligned? Then ddb is less useful due to refusal to backtrace.
It is actually 2) that I'm worried about. If we get a frame that is misaligned, it is almost certainly garbage and dereferencing it may trigger a nested fault which is less useful. I think it's more likely if your frame pointer is misaligned that we've encountered a garbage frame that it isn't worth unwinding through due to the risk of a nested fault (but also low likelihood of getting useful information after the garbage).
On non-x86 architectures we have a bit more safety in that we can use kstack_contains, but that doesn't quite work on x86 due to the extra stacks used for double faults and machine checks, etc. We could maybe add an x86-specific helper for kstack validation that checks those additional stacks as well as kstack_contains and replace the INKERNEL checks with some of those for better protection. I still think a misaligned frame is unlikely to be useful to unwind through and is instead evidence of a corrupt stack?
As I mentioned, I do not object. But perhaps we can be extra verbose in this case and print a line stating that tracing aborted due to mis-alignment, not because we lost the stack.
Pedantically, having unaligned pointer to the type is UB. So might be, it is more future-proof against compiler brain-damage, to calculate the address as uintptr_t, then check alignment and INKERNEL (we cast to long anyway), and only then cast to trapframe *.
sys/amd64/amd64/db_trace.c | ||
---|---|---|
236–237 | There the uintptr_t is also needed, I believe. Should this function return unaligned frame address at all? |
sys/amd64/amd64/db_trace.c | ||
---|---|---|
236–237 | I thought about moving the aligned fp check in this function, but it makes it a bit messy. Alternatively, we could maybe return a uintptr_t or register_t value here instead of struct amd64_frame * |
sys/amd64/amd64/db_trace.c | ||
---|---|---|
236–237 | I do not see anything wrong with returning integer type from the function. It should also reduce the number of type casts, it seems. |
sys/amd64/amd64/db_trace.c | ||
---|---|---|
329 | I think I could now move this alignment check into db_nextframe at the start (just return 0/0 like we do for an invalid trapframe) and then this entire block can go away as when the previous db_nextframe returns the misaligned frame address we would loop around and print the address and then the db_nextframe call that sees the unaligned frame would trigger the early exit. |
sys/amd64/amd64/db_trace.c | ||
---|---|---|
217 | We are careful to use db_get_value for the regular frames, but not for trapframe. Of course, most other arches don't use db_get_value either relying on kstack_contains checks instead. |
sys/amd64/amd64/db_trace.c | ||
---|---|---|
320–321 | I do think they are a bit much, yes. |