mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fixes to native backtrace.
This commit is contained in:
committed by
Christoffer Lerno
parent
dc0aa35522
commit
5e8816e6df
@@ -87,7 +87,7 @@ 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()
|
||||
{
|
||||
@@ -115,7 +115,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 +127,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 +367,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 +392,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):
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
ZString sname = info.dli_sname ? info.dli_sname : (ZString)"???";
|
||||
String s = process::execute_stdout_to_buffer(buf, { "addr2line", "-p", "-i", "-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,7 +191,7 @@ 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)!;
|
||||
list.append(trace);
|
||||
|
||||
Reference in New Issue
Block a user