builtin: print libbacktrace output to stderr, on panics/segfault crash (#14434)

Ned 2022-05-17 19:56:34 +08:00 committed by Jef Roosens
parent 9a0f499506
commit 5ada79c629
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
4 changed files with 32 additions and 10 deletions

View File

@ -55,7 +55,7 @@ fn panic_debug(line_no int, file string, mod string, fn_name string, s string) {
C.exit(1) C.exit(1)
} }
$if use_libbacktrace ? { $if use_libbacktrace ? {
print_libbacktrace(1) eprint_libbacktrace(1)
} $else { } $else {
print_backtrace_skipping_top_frames(1) print_backtrace_skipping_top_frames(1)
} }
@ -106,7 +106,7 @@ pub fn panic(s string) {
C.exit(1) C.exit(1)
} }
$if use_libbacktrace ? { $if use_libbacktrace ? {
print_libbacktrace(1) eprint_libbacktrace(1)
} $else { } $else {
print_backtrace_skipping_top_frames(1) print_backtrace_skipping_top_frames(1)
} }

View File

@ -130,6 +130,10 @@ pub:
[markused] [markused]
fn v_segmentation_fault_handler(signal int) { fn v_segmentation_fault_handler(signal int) {
eprintln('signal 11: segmentation fault') eprintln('signal 11: segmentation fault')
print_backtrace() $if use_libbacktrace ? {
eprint_libbacktrace(1)
} $else {
print_backtrace()
}
exit(128 + 11) exit(128 + 11)
} }

View File

@ -33,11 +33,11 @@ fn init_bt_state() &C.backtrace_state {
} }
// for bt_error_callback // for bt_error_callback
// struct BacktraceData { struct BacktraceOptions {
// state &C.backtrace_state stdin bool = true
// } }
fn bt_print_callback(data voidptr, pc voidptr, filename_ptr &char, line int, fn_name_ptr &char) int { fn bt_print_callback(data &BacktraceOptions, pc voidptr, filename_ptr &char, line int, fn_name_ptr &char) int {
filename := if isnil(filename_ptr) { '???' } else { unsafe { filename_ptr.vstring() } } filename := if isnil(filename_ptr) { '???' } else { unsafe { filename_ptr.vstring() } }
fn_name := if isnil(fn_name_ptr) { fn_name := if isnil(fn_name_ptr) {
'???' '???'
@ -46,7 +46,12 @@ fn bt_print_callback(data voidptr, pc voidptr, filename_ptr &char, line int, fn_
} }
// keep it for later // keep it for later
// pc_64 := u64(pc) // pc_64 := u64(pc)
println('$filename:$line: by $fn_name') bt_str := '$filename:$line: by $fn_name'
if data.stdin {
println(bt_str)
} else {
eprintln(bt_str)
}
return 0 return 0
} }
@ -81,6 +86,15 @@ fn print_libbacktrace(frames_to_skip int) {
$if no_backtrace ? { $if no_backtrace ? {
return return
} }
// data := &BacktraceData{bt_state} data := &BacktraceOptions{}
C.backtrace_full(bt_state, frames_to_skip, bt_print_callback, bt_error_callback, 0) C.backtrace_full(bt_state, frames_to_skip, bt_print_callback, bt_error_callback, data)
}
[noinline]
fn eprint_libbacktrace(frames_to_skip int) {
$if no_backtrace ? {
return
}
data := &BacktraceOptions{stdin: false}
C.backtrace_full(bt_state, frames_to_skip, bt_print_callback, bt_error_callback, data)
} }

View File

@ -2,3 +2,7 @@ module builtin
fn print_libbacktrace(frames_to_skip int) { fn print_libbacktrace(frames_to_skip int) {
} }
[noinline]
fn eprint_libbacktrace(frames_to_skip int) {
}