Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 55 additions & 56 deletions vlib/builtin/backtraces_nix.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -173,69 +173,68 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
return false
} $else {
$if linux && !freestanding {
$if tinyc {
C.tcc_backtrace(c'Backtrace')
return false
} $else {
$if !glibc {
$if !glibc {
$if tinyc {
C.tcc_backtrace(c'Backtrace')
Comment thread
dy-tea marked this conversation as resolved.
} $else {
eprintln('backtrace_symbols is missing => printing backtraces is not available.')
eprintln('Some libc implementations like musl simply do not provide it.')
}
return false
Comment thread
dy-tea marked this conversation as resolved.
} $else {
current_executable_name := backtrace_current_executable_name()
buffer := [100]voidptr{}
nr_ptrs := C.backtrace(&buffer[0], 100)
if nr_ptrs < 2 {
eprintln('C.backtrace returned less than 2 frames')
return false
} $else {
current_executable_name := backtrace_current_executable_name()
buffer := [100]voidptr{}
nr_ptrs := C.backtrace(&buffer[0], 100)
if nr_ptrs < 2 {
eprintln('C.backtrace returned less than 2 frames')
return false
}
nr_actual_frames := nr_ptrs - skipframes
//////csymbols := backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames)
csymbols := C.backtrace_symbols(voidptr(&buffer[skipframes]), nr_actual_frames)
for i in 0 .. nr_actual_frames {
sframe := unsafe { tos2(&u8(csymbols[i])) }
executable := sframe.all_before('(')
addr2line_executable := backtrace_addr2line_executable(executable,
current_executable_name)
addr := sframe.all_after('[').all_before(']')
beforeaddr := sframe.all_before('[')
cmd := 'addr2line -e ' + addr2line_executable + ' ' + addr
// taken from os, to avoid depending on the os module inside builtin.v
f := C.popen(&char(cmd.str), c'r')
if f == unsafe { nil } {
eprintln(sframe)
continue
}
nr_actual_frames := nr_ptrs - skipframes
//////csymbols := backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames)
csymbols := C.backtrace_symbols(voidptr(&buffer[skipframes]), nr_actual_frames)
for i in 0 .. nr_actual_frames {
sframe := unsafe { tos2(&u8(csymbols[i])) }
executable := sframe.all_before('(')
addr2line_executable := backtrace_addr2line_executable(executable,
current_executable_name)
addr := sframe.all_after('[').all_before(']')
beforeaddr := sframe.all_before('[')
cmd := 'addr2line -e ' + addr2line_executable + ' ' + addr
// taken from os, to avoid depending on the os module inside builtin.v
f := C.popen(&char(cmd.str), c'r')
if f == unsafe { nil } {
eprintln(sframe)
continue
}
buf := [1000]u8{}
mut output := ''
unsafe {
bp := &u8(&buf[0])
for C.fgets(&char(bp), 1000, f) != 0 {
output += tos(bp, vstrlen(bp))
}
}
output = output.trim_chars(' \t\n', .trim_both) + ':'
if C.pclose(f) != 0 {
eprintln(sframe)
continue
}
if output in ['??:0:', '??:?:'] {
output = ''
buf := [1000]u8{}
mut output := ''
unsafe {
bp := &u8(&buf[0])
for C.fgets(&char(bp), 1000, f) != 0 {
output += tos(bp, vstrlen(bp))
}
// See http://wiki.dwarfstd.org/index.php?title=Path_Discriminators
// Note: it is shortened here to just d. , just so that it fits, and so
// that the common error file:lineno: line format is enforced.
output = output.replace(' (discriminator', ': (d.')
eprint(output)
eprint_space_padding(output, 55)
eprint(' | ')
eprint(addr)
eprint(' | ')
eprintln(demangle_backtrace_sym(beforeaddr))
}
if nr_actual_frames > 0 {
unsafe { C.free(csymbols) }
output = output.trim_chars(' \t\n', .trim_both) + ':'
if C.pclose(f) != 0 {
eprintln(sframe)
continue
}
if output in ['??:0:', '??:?:'] {
output = ''
}
// See http://wiki.dwarfstd.org/index.php?title=Path_Discriminators
// Note: it is shortened here to just d. , just so that it fits, and so
// that the common error file:lineno: line format is enforced.
output = output.replace(' (discriminator', ': (d.')
eprint(output)
eprint_space_padding(output, 55)
eprint(' | ')
eprint(addr)
eprint(' | ')
eprintln(demangle_backtrace_sym(beforeaddr))
}
if nr_actual_frames > 0 {
unsafe { C.free(csymbols) }
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion vlib/builtin/builtin.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ fn v_segmentation_fault_handler(signal_number i32) {
} $else {
C.fprintf(C.stderr, c'signal %d: segmentation fault\n', signal_number)
}
$if use_libbacktrace ? {
$if use_libbacktrace ? && !tinyc {
$if openbsd {
print_backtrace()
} $else {
Expand Down
27 changes: 17 additions & 10 deletions vlib/builtin/builtin_d_use_libbacktrace.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ $if openbsd {
@[noinline]
fn eprint_libbacktrace(frames_to_skip int) {
}
} $else {
} $else $if !tinyc {
// full libbacktrace implementation for gcc/clang (TCC can't compile libbacktrace's C code)
#flag -I@VEXEROOT/thirdparty/libbacktrace
#flag @VEXEROOT/thirdparty/libbacktrace/backtrace.o
#include <backtrace.h>
Expand All @@ -31,16 +32,13 @@ $if openbsd {
__global bt_state = init_bt_state()

fn init_bt_state() &C.backtrace_state {
$if !tinyc {
mut filename := &char(unsafe { nil })
$if windows {
filename = unsafe { string_from_wide(&&u16(g_main_argv)[0]).str }
} $else {
filename = unsafe { &&char(g_main_argv)[0] }
}
return C.backtrace_create_state(filename, 1, bt_error_handler, 0)
mut filename := &char(unsafe { nil })
$if windows {
filename = unsafe { string_from_wide(&&u16(g_main_argv)[0]).str }
} $else {
filename = unsafe { &&char(g_main_argv)[0] }
}
return &C.backtrace_state(unsafe { nil })
return C.backtrace_create_state(filename, 1, bt_error_handler, 0)
}

// for bt_error_callback
Expand Down Expand Up @@ -116,4 +114,13 @@ $if openbsd {
}
C.backtrace_full(bt_state, frames_to_skip, bt_print_callback, bt_error_callback, data)
}
} $else {
// no-op stubs for TCC (TCC can't compile libbacktrace's C code, and
// it has its own built-in backtrace via tcc_backtrace instead)
fn print_libbacktrace(frames_to_skip int) {
}

@[noinline]
fn eprint_libbacktrace(frames_to_skip int) {
}
Comment thread
dy-tea marked this conversation as resolved.
}
34 changes: 16 additions & 18 deletions vlib/builtin/panicing.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,15 @@ fn panic_debug(line_no int, file string, mod string, fn_name string, s string) {
C.exit(1)
} $else $if no_backtrace ? {
C.exit(1)
} $else {
$if tinyc {
$if panics_break_into_debugger ? {
break_if_debugger_attached()
} $else {
C.tcc_backtrace(c'Backtrace')
}
C.exit(1)
} $else $if tinyc && !glibc {
$if panics_break_into_debugger ? {
break_if_debugger_attached()
} $else {
C.tcc_backtrace(c'Backtrace')
}
$if use_libbacktrace ? {
C.exit(1)
} $else {
$if use_libbacktrace ? && !tinyc {
$if openbsd {
print_backtrace_skipping_top_frames(1)
} $else {
Expand Down Expand Up @@ -114,16 +113,15 @@ pub fn panic(s string) {
C.exit(1)
} $else $if no_backtrace ? {
C.exit(1)
} $else {
$if tinyc {
$if panics_break_into_debugger ? {
break_if_debugger_attached()
} $else {
C.tcc_backtrace(c'Backtrace')
}
C.exit(1)
} $else $if tinyc && !glibc {
Comment thread
dy-tea marked this conversation as resolved.
$if panics_break_into_debugger ? {
break_if_debugger_attached()
} $else {
C.tcc_backtrace(c'Backtrace')
}
$if use_libbacktrace ? {
C.exit(1)
} $else {
$if use_libbacktrace ? && !tinyc {
$if openbsd {
print_backtrace_skipping_top_frames(1)
} $else {
Expand Down
Loading