diff --git a/AK/Debug.h.in b/AK/Debug.h.in index 3af90f4caa..54333a0fc3 100644 --- a/AK/Debug.h.in +++ b/AK/Debug.h.in @@ -14,6 +14,10 @@ #cmakedefine01 AWAVLOADER_DEBUG #endif +#ifndef BACKTRACE_DEBUG +#cmakedefine01 BACKTRACE_DEBUG +#endif + #ifndef BMP_DEBUG #cmakedefine01 BMP_DEBUG #endif diff --git a/Meta/CMake/all_the_debug_macros.cmake b/Meta/CMake/all_the_debug_macros.cmake index 5e3936f351..bf2493aefe 100644 --- a/Meta/CMake/all_the_debug_macros.cmake +++ b/Meta/CMake/all_the_debug_macros.cmake @@ -5,6 +5,7 @@ set(APIC_SMP_DEBUG ON) set(ARP_DEBUG ON) set(AUTOCOMPLETE_DEBUG ON) set(AWAVLOADER_DEBUG ON) +set(BACKTRACE_DEBUG ON) set(BBFS_DEBUG ON) set(BMP_DEBUG ON) set(BXVGA_DEBUG ON) diff --git a/Userland/Libraries/LibCoreDump/Backtrace.cpp b/Userland/Libraries/LibCoreDump/Backtrace.cpp index ea16b7c68b..c91922a3e2 100644 --- a/Userland/Libraries/LibCoreDump/Backtrace.cpp +++ b/Userland/Libraries/LibCoreDump/Backtrace.cpp @@ -84,8 +84,10 @@ void Backtrace::add_entry(const Reader& coredump, FlatPtr eip) auto* object_info = object_info_for_region(*region); if (!object_info) return; - auto function_name = object_info->debug_info.elf().symbolicate(eip - region->region_start); - auto source_position = object_info->debug_info.get_source_position(eip - region->region_start); + + auto function_name = object_info->debug_info->elf().symbolicate(eip - region->region_start); + auto source_position = object_info->debug_info->get_source_position_with_inlines(eip - region->region_start); + m_entries.append({ eip, object_name, function_name, source_position }); } @@ -98,11 +100,30 @@ String Backtrace::Entry::to_string(bool color) const return builder.build(); } builder.appendff("[{}] {}", object_name, function_name.is_empty() ? "???" : function_name); - if (source_position.has_value()) { - auto& source_position = this->source_position.value(); - auto fmt = color ? " (\033[34;1m{}\033[0m:{})" : " ({}:{})"; - builder.appendff(fmt, LexicalPath(source_position.file_path).basename(), source_position.line_number); + builder.append(" ("); + + Vector source_positions; + + for (auto& position : source_position_with_inlines.inline_chain) { + if (!source_positions.contains_slow(position)) + source_positions.append(position); } + + if (source_position_with_inlines.source_position.has_value() && !source_positions.contains_slow(source_position_with_inlines.source_position.value())) { + source_positions.insert(0, source_position_with_inlines.source_position.value()); + } + + for (size_t i = 0; i < source_positions.size(); ++i) { + auto& position = source_positions[i]; + auto fmt = color ? "\033[34;1m{}\033[0m:{}" : "{}:{}"; + builder.appendff(fmt, LexicalPath(position.file_path).basename(), position.line_number); + if (i != source_positions.size() - 1) { + builder.append(" => "); + } + } + + builder.append(")"); + return builder.build(); } diff --git a/Userland/Libraries/LibCoreDump/Backtrace.h b/Userland/Libraries/LibCoreDump/Backtrace.h index 32b32d0c28..a1a008213b 100644 --- a/Userland/Libraries/LibCoreDump/Backtrace.h +++ b/Userland/Libraries/LibCoreDump/Backtrace.h @@ -30,7 +30,7 @@ public: FlatPtr eip; String object_name; String function_name; - Optional source_position; + Debug::DebugInfo::SourcePositionWithInlines source_position_with_inlines; String to_string(bool color = false) const; }; diff --git a/Userland/Services/CrashDaemon/main.cpp b/Userland/Services/CrashDaemon/main.cpp index 5f6ea14fdf..c8b314b10e 100644 --- a/Userland/Services/CrashDaemon/main.cpp +++ b/Userland/Services/CrashDaemon/main.cpp @@ -74,8 +74,20 @@ static void print_backtrace(const String& coredump_path) if (thread_index > 0) dbgln(); dbgln("--- Backtrace for thread #{} (TID {}) ---", thread_index, thread_info.tid); - for (auto& entry : backtrace.entries()) + for (auto& entry : backtrace.entries()) { +#ifndef BACKTRACE_DEBUG dbgln("{}", entry.to_string(true)); +#else + auto region = coredump->region_containing(entry.eip); + String name; + u32 base_addr { 0 }; + if (region) { + name = region->region_name; + base_addr = region->region_start; + } + dbgln("{} ({} base: {:p}, offset: {:p})", entry.to_string(true), name, base_addr, entry.eip - base_addr); +#endif + } ++thread_index; return IterationDecision::Continue; });