Kernel: Don't get rbp from internal context switch structures
This has been broken on x86_64 since its introduction, as it features more registers to be saved, and we never held up the "rbp has to be the last pushed register" there. Instead, just copy rbp from the thread structure, which is now properly updated since the last commit.
This commit is contained in:
parent
0ee476948b
commit
aefd6e9ee1
Notes:
sideshowbarker
2024-07-16 21:18:38 +09:00
Author: https://github.com/timschumi Commit: https://github.com/SerenityOS/serenity/commit/aefd6e9ee1 Pull-request: https://github.com/SerenityOS/serenity/pull/18413 Reviewed-by: https://github.com/Panky-codes
1 changed files with 1 additions and 13 deletions
|
@ -863,23 +863,11 @@ ErrorOr<Vector<FlatPtr, 32>> Processor::capture_stack_trace(Thread& thread, size
|
|||
case Thread::State::Blocked:
|
||||
case Thread::State::Dying:
|
||||
case Thread::State::Dead: {
|
||||
// We need to retrieve ebp from what was last pushed to the kernel
|
||||
// stack. Before switching out of that thread, it switch_context
|
||||
// pushed the callee-saved registers, and the last of them happens
|
||||
// to be ebp.
|
||||
ScopedAddressSpaceSwitcher switcher(thread.process());
|
||||
auto& regs = thread.regs();
|
||||
auto* stack_top = reinterpret_cast<FlatPtr*>(regs.sp());
|
||||
if (Memory::is_user_range(VirtualAddress(stack_top), sizeof(FlatPtr))) {
|
||||
if (copy_from_user(&frame_ptr, &((FlatPtr*)stack_top)[0]).is_error())
|
||||
frame_ptr = 0;
|
||||
} else {
|
||||
void* fault_at;
|
||||
if (!safe_memcpy(&frame_ptr, &((FlatPtr*)stack_top)[0], sizeof(FlatPtr), fault_at))
|
||||
frame_ptr = 0;
|
||||
}
|
||||
|
||||
ip = regs.ip();
|
||||
frame_ptr = regs.rbp;
|
||||
|
||||
// TODO: We need to leave the scheduler lock here, but we also
|
||||
// need to prevent the target thread from being run while
|
||||
|
|
Loading…
Add table
Reference in a new issue