1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:07:47 +00:00

Kernel: Make Thread::backtrace() fallible using KString

This commit is contained in:
Idan Horowitz 2022-01-11 22:44:29 +02:00
parent 06af81fcfb
commit 9a7cd8fef8
3 changed files with 16 additions and 17 deletions

View file

@ -6,6 +6,7 @@
#pragma once #pragma once
#include <AK/StringBuilder.h>
#include <AK/StringView.h> #include <AK/StringView.h>
#include <Kernel/KBuffer.h> #include <Kernel/KBuffer.h>
#include <stdarg.h> #include <stdarg.h>

View file

@ -1157,7 +1157,7 @@ struct RecognizedSymbol {
const KernelSymbol* symbol { nullptr }; const KernelSymbol* symbol { nullptr };
}; };
static bool symbolicate(RecognizedSymbol const& symbol, Process& process, StringBuilder& builder) static ErrorOr<bool> symbolicate(RecognizedSymbol const& symbol, Process& process, StringBuilder& builder)
{ {
if (symbol.address == 0) if (symbol.address == 0)
return false; return false;
@ -1165,30 +1165,29 @@ static bool symbolicate(RecognizedSymbol const& symbol, Process& process, String
bool mask_kernel_addresses = !process.is_superuser(); bool mask_kernel_addresses = !process.is_superuser();
if (!symbol.symbol) { if (!symbol.symbol) {
if (!Memory::is_user_address(VirtualAddress(symbol.address))) { if (!Memory::is_user_address(VirtualAddress(symbol.address))) {
builder.append("0xdeadc0de\n"); TRY(builder.try_append("0xdeadc0de\n"));
} else { } else {
if (auto* region = process.address_space().find_region_containing({ VirtualAddress(symbol.address), sizeof(FlatPtr) })) { if (auto* region = process.address_space().find_region_containing({ VirtualAddress(symbol.address), sizeof(FlatPtr) })) {
size_t offset = symbol.address - region->vaddr().get(); size_t offset = symbol.address - region->vaddr().get();
if (auto region_name = region->name(); !region_name.is_null() && !region_name.is_empty()) if (auto region_name = region->name(); !region_name.is_null() && !region_name.is_empty())
builder.appendff("{:p} {} + {:#x}\n", (void*)symbol.address, region_name, offset); TRY(builder.try_appendff("{:p} {} + {:#x}\n", (void*)symbol.address, region_name, offset));
else else
builder.appendff("{:p} {:p} + {:#x}\n", (void*)symbol.address, region->vaddr().as_ptr(), offset); TRY(builder.try_appendff("{:p} {:p} + {:#x}\n", (void*)symbol.address, region->vaddr().as_ptr(), offset));
} else { } else {
builder.appendff("{:p}\n", symbol.address); TRY(builder.try_appendff("{:p}\n", symbol.address));
} }
} }
return true; return true;
} }
unsigned offset = symbol.address - symbol.symbol->address; unsigned offset = symbol.address - symbol.symbol->address;
if (symbol.symbol->address == g_highest_kernel_symbol_address && offset > 4096) { if (symbol.symbol->address == g_highest_kernel_symbol_address && offset > 4096)
builder.appendff("{:p}\n", (void*)(mask_kernel_addresses ? 0xdeadc0de : symbol.address)); TRY(builder.try_appendff("{:p}\n", (void*)(mask_kernel_addresses ? 0xdeadc0de : symbol.address)));
} else { else
builder.appendff("{:p} {} + {:#x}\n", (void*)(mask_kernel_addresses ? 0xdeadc0de : symbol.address), symbol.symbol->name, offset); TRY(builder.try_appendff("{:p} {} + {:#x}\n", (void*)(mask_kernel_addresses ? 0xdeadc0de : symbol.address), symbol.symbol->name, offset));
}
return true; return true;
} }
String Thread::backtrace() ErrorOr<NonnullOwnPtr<KString>> Thread::backtrace()
{ {
Vector<RecognizedSymbol, 128> recognized_symbols; Vector<RecognizedSymbol, 128> recognized_symbols;
@ -1198,18 +1197,18 @@ String Thread::backtrace()
ScopedAddressSpaceSwitcher switcher(process); ScopedAddressSpaceSwitcher switcher(process);
for (auto& frame : stack_trace) { for (auto& frame : stack_trace) {
if (Memory::is_user_range(VirtualAddress(frame), sizeof(FlatPtr) * 2)) { if (Memory::is_user_range(VirtualAddress(frame), sizeof(FlatPtr) * 2)) {
recognized_symbols.append({ frame }); TRY(recognized_symbols.try_append({ frame }));
} else { } else {
recognized_symbols.append({ frame, symbolicate_kernel_address(frame) }); TRY(recognized_symbols.try_append({ frame, symbolicate_kernel_address(frame) }));
} }
} }
StringBuilder builder; StringBuilder builder;
for (auto& symbol : recognized_symbols) { for (auto& symbol : recognized_symbols) {
if (!symbolicate(symbol, process, builder)) if (!TRY(symbolicate(symbol, process, builder)))
break; break;
} }
return builder.to_string(); return KString::try_create(builder.string_view());
} }
size_t Thread::thread_specific_region_alignment() const size_t Thread::thread_specific_region_alignment() const

View file

@ -13,7 +13,6 @@
#include <AK/IntrusiveList.h> #include <AK/IntrusiveList.h>
#include <AK/Optional.h> #include <AK/Optional.h>
#include <AK/OwnPtr.h> #include <AK/OwnPtr.h>
#include <AK/String.h>
#include <AK/TemporaryChange.h> #include <AK/TemporaryChange.h>
#include <AK/Time.h> #include <AK/Time.h>
#include <AK/Variant.h> #include <AK/Variant.h>
@ -1247,7 +1246,7 @@ public:
bool is_allocation_enabled() const { return m_allocation_enabled; } bool is_allocation_enabled() const { return m_allocation_enabled; }
void set_allocation_enabled(bool value) { m_allocation_enabled = value; } void set_allocation_enabled(bool value) { m_allocation_enabled = value; }
String backtrace(); ErrorOr<NonnullOwnPtr<KString>> backtrace();
private: private:
Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Memory::Region>, NonnullRefPtr<Timer>, NonnullOwnPtr<KString>); Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Memory::Region>, NonnullRefPtr<Timer>, NonnullOwnPtr<KString>);