From 03f644e0999b1b71fe42aafa5e9e176851ec5571 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 12 Dec 2020 16:04:30 +0200 Subject: [PATCH] builtin: change V's panic() to not segfault; use `-d panics_break_into_debugger` to override --- vlib/builtin/builtin.v | 38 +++++++++++++++++++++++++++--------- vlib/builtin/builtin_nix.c.v | 2 +- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/vlib/builtin/builtin.v b/vlib/builtin/builtin.v index ee8e20b642..bc25584ad1 100644 --- a/vlib/builtin/builtin.v +++ b/vlib/builtin/builtin.v @@ -26,6 +26,7 @@ fn on_panic(f fn(int)int) { } */ +// print_backtrace shows a backtrace of the current call stack on stdout pub fn print_backtrace() { // at the time of backtrace_symbols_fd call, the C stack would look something like this: // 1 frame for print_backtrace_skipping_top_frames @@ -35,7 +36,7 @@ pub fn print_backtrace() { print_backtrace_skipping_top_frames(2) } -// replaces panic when -debug arg is passed +// panic_debug - private function that V uses for panics, -cg/-g is passed fn panic_debug(line_no int, file string, mod string, fn_name string, s string) { // NB: the order here is important for a stabler test output // module is less likely to change than function, etc... @@ -51,27 +52,44 @@ fn panic_debug(line_no int, file string, mod string, fn_name string, s string) { $if exit_after_panic_message ? { C.exit(1) } - // recent versions of tcc print better backtraces automatically - $if !tinyc { + if !should_use_native_backtraces() { print_backtrace_skipping_top_frames(1) } - break_if_debugger_attached() + $if panics_break_into_debugger ? { + break_if_debugger_attached() + } C.exit(1) } +// panic prints a nice error message, then exits the process with exit code of 1. +// It also shows a backtrace on most platforms. pub fn panic(s string) { eprintln('V panic: $s') $if exit_after_panic_message ? { C.exit(1) } - // recent versions of tcc print better backtraces automatically - $if !tinyc { - print_backtrace() + if !should_use_native_backtraces() { + print_backtrace_skipping_top_frames(1) + } + $if panics_break_into_debugger ? { + break_if_debugger_attached() } - break_if_debugger_attached() C.exit(1) } +fn should_use_native_backtraces() bool { + mut res := false + $if panics_break_into_debugger ? { + $if tinyc { + // recent versions of tcc print nicer backtraces automatically + res = true + } + } + return res +} + + +// eprintln prints a message with a line end, to stderr. Both stderr and stdout are flushed. pub fn eprintln(s string) { // eprintln is used in panics, so it should not fail at all if s.str == 0 { @@ -84,9 +102,10 @@ pub fn eprintln(s string) { C.fflush(C.stderr) } +// eprint prints a message to stderr. Both stderr and stdout are flushed. pub fn eprint(s string) { if s.str == 0 { - eprintln('eprint(NIL)') + eprint('eprint(NIL)') } C.fflush(C.stdout) C.fflush(C.stderr) @@ -94,6 +113,7 @@ pub fn eprint(s string) { C.fflush(C.stderr) } +// print prints a message to stdout pub fn print(s string) { C.write(1, s.str, s.len) } diff --git a/vlib/builtin/builtin_nix.c.v b/vlib/builtin/builtin_nix.c.v index 7892ddb4a1..27c8c96680 100644 --- a/vlib/builtin/builtin_nix.c.v +++ b/vlib/builtin/builtin_nix.c.v @@ -131,7 +131,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { // NB: 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.') - eprintln('${output:-46s} | ${addr:14s} | $beforeaddr') + eprintln('${output:-55s} | ${addr:14s} | $beforeaddr') } } return true