1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 10:18:11 +00:00

Kernel: Fix busted backtraces when a thread backtraces itself

When the current thread is backtracing itself, we now start walking the
stack from the current EBP register value, instead of the TSS one.

Now SystemMonitor always appears to be running Thread::backtrace() when
sampled, which makes perfect sense. :^)
This commit is contained in:
Andreas Kling 2020-01-12 10:19:37 +01:00
parent 0d961ece94
commit f6c0fccc01

View file

@ -698,6 +698,14 @@ String Thread::backtrace(ProcessInspectionHandle&) const
String Thread::backtrace_impl() const
{
u32 start_frame;
if (current == this) {
asm volatile("movl %%ebp, %%eax"
: "=a"(start_frame));
} else {
start_frame = frame_ptr();
}
SmapDisabler disabler;
auto& process = const_cast<Process&>(this->process());
ProcessPagingScope paging_scope(process);
@ -706,11 +714,14 @@ String Thread::backtrace_impl() const
const KSym* ksym;
};
StringBuilder builder;
Vector<RecognizedSymbol, 64> recognized_symbols;
recognized_symbols.append({ tss().eip, ksymbolicate(tss().eip) });
for (u32* stack_ptr = (u32*)frame_ptr(); process.validate_read_from_kernel(VirtualAddress((u32)stack_ptr), sizeof(void*) * 2); stack_ptr = (u32*)*stack_ptr) {
Vector<RecognizedSymbol, 128> recognized_symbols;
if (current != this)
recognized_symbols.append({ tss().eip, ksymbolicate(tss().eip) });
for (u32* stack_ptr = (u32*)start_frame; process.validate_read_from_kernel(VirtualAddress((u32)stack_ptr), sizeof(void*) * 2); stack_ptr = (u32*)*stack_ptr) {
u32 retaddr = stack_ptr[1];
recognized_symbols.append({ retaddr, ksymbolicate(retaddr) });
if (recognized_symbols.size() == 256)
break;
}
bool mask_kernel_addresses = !current->process().is_superuser();