From 51a54c34be6b02ca47d0c92c2e7d5f3c7249476a Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sat, 11 Nov 2023 14:16:36 +0100 Subject: [PATCH] Fixes to native backtrace. --- lib/std/core/builtin.c3 | 32 ++++++++------------------------ lib/std/core/env.c3 | 2 +- lib/std/os/linux/linux.c3 | 11 +++++++---- resources/linux_stack.c3 | 19 +++++++++++++++++-- src/compiler/linker.c | 2 ++ src/compiler/llvm_codegen_stmt.c | 2 +- 6 files changed, 36 insertions(+), 32 deletions(-) diff --git a/lib/std/core/builtin.c3 b/lib/std/core/builtin.c3 index d8f1b729b..4b065192a 100644 --- a/lib/std/core/builtin.c3 +++ b/lib/std/core/builtin.c3 @@ -87,12 +87,14 @@ struct CallstackElement uint line; } -fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::DARWIN || env::LINUX) +fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::NATIVE_STACKTRACE) { @pool() { BacktraceList! backtrace = backtrace::backtrace_load(mem::temp()); + io::eprintn("A"); if (catch backtrace) return false; + io::eprintfn("B %d %d", backtraces_to_ignore, backtrace.len()); if (backtrace.len() <= backtraces_to_ignore) return false; io::eprint("\nERROR: '"); io::eprint(message); @@ -115,7 +117,7 @@ fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::DARWI return true; }; } -fn void default_panic(String message, String file, String function, uint line) @if(env::DARWIN) +fn void default_panic(String message, String file, String function, uint line) @if(env::NATIVE_STACKTRACE) { $if $defined(io::stderr): if (!print_backtrace(message, 2)) @@ -127,7 +129,7 @@ fn void default_panic(String message, String file, String function, uint line) @ $$trap(); } -fn void default_panic(String message, String file, String function, uint line) @if(!env::DARWIN) +fn void default_panic(String message, String file, String function, uint line) @if(!env::NATIVE_STACKTRACE) { CallstackElement* stack = $$stacktrace(); $if $defined(io::stderr): @@ -367,35 +369,17 @@ macro uint void*.hash(void* ptr) => ((ulong)(uptr)ptr).hash(); module std::core::builtin @if((env::LINUX || env::DARWIN) && env::COMPILER_SAFE_MODE && env::DEBUG_SYMBOLS); import libc; -fn void sig_panic(String message) @if(env::DARWIN) +fn void sig_panic(String message) { default_panic(message, "???", "???", 0); } -fn void sig_panic(String message) @if(!env::DARWIN) -{ - $if $defined(io::stderr) && $defined(File.printf): - CallstackElement* stack = $$stacktrace(); - if (stack) stack = stack.prev; - if (stack) stack = stack.prev; - (void)io::stderr().print("\nSYSTEM ERROR: '"); - (void)io::stderr().print(message); - (void)io::stderr().printn("'"); - while (stack) - { - (void)io::stderr().printfn(" in %s %s (%s:%s)", stack.location.name, stack.function, stack.file, stack.line); - if (stack == stack.prev) break; - stack = stack.prev; - } - $endif -} - SignalFunction old_bus_error; SignalFunction old_segmentation_fault; fn void sig_bus_error(CInt i) { - $if !env::DARWIN: + $if !env::NATIVE_STACKTRACE: sig_panic("Illegal memory access."); $else $if $defined(io::stderr): @@ -410,7 +394,7 @@ fn void sig_bus_error(CInt i) fn void sig_segmentation_fault(CInt i) { - $if !env::DARWIN: + $if !env::NATIVE_STACKTRACE: sig_panic("Out of bounds memory access."); $else $if $defined(io::stderr): diff --git a/lib/std/core/env.c3 b/lib/std/core/env.c3 index 8a31312c6..024ca1ddf 100644 --- a/lib/std/core/env.c3 +++ b/lib/std/core/env.c3 @@ -132,7 +132,7 @@ const MemoryEnvironment MEMORY_ENV = (MemoryEnvironment)$$MEMORY_ENVIRONMENT; const bool TRACK_MEMORY = DEBUG_SYMBOLS && (COMPILER_SAFE_MODE || TESTING); const bool X86_64 = ARCH_TYPE == X86_64; const bool AARCH64 = ARCH_TYPE == AARCH64; - +const bool NATIVE_STACKTRACE = LINUX || DARWIN; const bool LINUX = LIBC && OS_TYPE == LINUX; const bool DARWIN = LIBC && os_is_darwin(); const bool WIN32 = LIBC && OS_TYPE == WIN32; diff --git a/lib/std/os/linux/linux.c3 b/lib/std/os/linux/linux.c3 index 20963c95d..4c7eaee3d 100644 --- a/lib/std/os/linux/linux.c3 +++ b/lib/std/os/linux/linux.c3 @@ -140,15 +140,16 @@ fn Backtrace! backtrace_load_element(void* addr, Allocator* allocator = mem::hea if (!addr) return backtrace::BACKTRACE_UNKNOWN; char[] buf = mem::temp_array(char, 1024); Linux_Dl_info info; - if (dladdr(addr, &info) == 0) return backtrace::BACKTRACE_UNKNOWN; + if (dladdr(addr, &info) == 0) return backtrace::BACKTRACE_UNKNOWN; void* obj_address = addr - (uptr)info.dli_fbase + (uptr)elf_module_image_base(info.dli_fname.str_view())!; ZString obj_path = info.dli_fname; - String s = process::execute_stdout_to_buffer(buf, { "addr2line", "-p", "-i", "-C", "-f", "-e", obj_path.str_view(), string::tformat("0x%x", obj_address) })!; + ZString sname = info.dli_sname ? info.dli_sname : (ZString)"???"; + String s = process::execute_stdout_to_buffer(buf, { "addr2line", "-p", "-C", "-f", "-e", obj_path.str_view(), string::tformat("0x%x", obj_address) })!; String[] parts = s.tsplit(" at "); if (parts.len != 2) { return { - .function = info.dli_sname ? info.dli_sname.copy(allocator) : "???".copy(allocator), + .function = sname.copy(allocator), .object_file = info.dli_fname.copy(allocator), .offset = (uptr)addr, .file = "".copy(allocator), @@ -177,6 +178,7 @@ fn BacktraceList! backtrace_load(Allocator* allocator) { void*[256] bt_buffer; CInt size = posix::backtrace(&bt_buffer, 256); + io::printfn("Backtrace list %s", size); BacktraceList list; list.init_new(size, allocator); defer catch @@ -189,9 +191,10 @@ fn BacktraceList! backtrace_load(Allocator* allocator) } @pool(allocator) { - for (usz i = 1; i < size; i++) + for (usz i = 0; i < size; i++) { Backtrace trace = backtrace_load_element(bt_buffer[i], allocator)!; + io::printn(trace); list.append(trace); } }; diff --git a/resources/linux_stack.c3 b/resources/linux_stack.c3 index e8111cc2a..7e03269f7 100644 --- a/resources/linux_stack.c3 +++ b/resources/linux_stack.c3 @@ -3,8 +3,23 @@ import std::io; import std::collections::map; import std::os; -fn void! main() +fn void test2() { + //typeid y = int.typeid; + (void)linux::backtrace_load(mem::heap()); + io::printn("Hello"); + builtin::panicf("FEHifej", "file", "fun", 123); int x = 2; - builtin::print_backtrace("Hello", 0); + int[1] y; + int z = y[x]; +//assert(false, "ofkef"); +} + +fn void test1() +{ + test2(); +} +fn void main() +{ + test1(); } \ No newline at end of file diff --git a/src/compiler/linker.c b/src/compiler/linker.c index 572789b21..d092b856d 100644 --- a/src/compiler/linker.c +++ b/src/compiler/linker.c @@ -389,6 +389,7 @@ static void linker_setup_linux(const char ***args_ref, LinkerType linker_type) if (active_target.debug_info == DEBUG_INFO_FULL) { add_arg("-rdynamic"); + add_arg("-ldl"); } add_arg("-pthread"); return; @@ -432,6 +433,7 @@ static void linker_setup_linux(const char ***args_ref, LinkerType linker_type) add_arg2("-L", crt_dir); add_arg("--dynamic-linker=/lib64/ld-linux-x86-64.so.2"); add_arg("-lm"); + add_arg("-ldl"); add_arg("-lpthread"); add_arg("-lc"); add_arg("-L/usr/lib/"); diff --git a/src/compiler/llvm_codegen_stmt.c b/src/compiler/llvm_codegen_stmt.c index 110529785..65596a081 100644 --- a/src/compiler/llvm_codegen_stmt.c +++ b/src/compiler/llvm_codegen_stmt.c @@ -1408,7 +1408,7 @@ void llvm_emit_panic_if_true(GenContext *c, BEValue *value, const char *panic_na } } llvm_emit_panic(c, panic_name, loc, fmt, values); - llvm_emit_br(c, ok_block); + llvm_emit_unreachable(c); llvm_emit_block(c, ok_block); }