v: add an -assert aborts/backtraces option to ease debugging
parent
f0c1e55637
commit
c7752ce8d3
|
@ -205,3 +205,13 @@ see also `v help build`.
|
||||||
Write all C flags into `file.txt`, one flag per line.
|
Write all C flags into `file.txt`, one flag per line.
|
||||||
If `file.txt` is `-`, then write the flags to stdout, one flag per line.
|
If `file.txt` is `-`, then write the flags to stdout, one flag per line.
|
||||||
|
|
||||||
|
-assert aborts
|
||||||
|
Call abort() after an assertion failure. Debuggers usually
|
||||||
|
install signal handlers for SIGABRT, so your program will stop and you
|
||||||
|
will get a backtrace. If you are running your program outside of a
|
||||||
|
debugger, you will most likely get a core dump file.
|
||||||
|
|
||||||
|
-assert backtraces
|
||||||
|
Call print_backtrace() after an assertion failure. Note that
|
||||||
|
backtraces are not implemented yet on all combinations of
|
||||||
|
platform/compiler.
|
||||||
|
|
|
@ -33,9 +33,7 @@ fn (mut g Gen) gen_assert_stmt(original_assert_statement ast.AssertStmt) {
|
||||||
g.writeln('\tg_test_fails++;')
|
g.writeln('\tg_test_fails++;')
|
||||||
metaname_fail := g.gen_assert_metainfo(node)
|
metaname_fail := g.gen_assert_metainfo(node)
|
||||||
g.writeln('\tmain__cb_assertion_failed(&$metaname_fail);')
|
g.writeln('\tmain__cb_assertion_failed(&$metaname_fail);')
|
||||||
if 'abort_on_assert' in g.pref.compile_defines_all {
|
g.gen_assert_postfailure_mode(node)
|
||||||
g.writeln('\tabort();')
|
|
||||||
}
|
|
||||||
g.writeln('\tlongjmp(g_jump_buffer, 1);')
|
g.writeln('\tlongjmp(g_jump_buffer, 1);')
|
||||||
g.writeln('\t// TODO')
|
g.writeln('\t// TODO')
|
||||||
g.writeln('\t// Maybe print all vars in a test function if it fails?')
|
g.writeln('\t// Maybe print all vars in a test function if it fails?')
|
||||||
|
@ -48,14 +46,24 @@ fn (mut g Gen) gen_assert_stmt(original_assert_statement ast.AssertStmt) {
|
||||||
g.writeln(' {')
|
g.writeln(' {')
|
||||||
metaname_panic := g.gen_assert_metainfo(node)
|
metaname_panic := g.gen_assert_metainfo(node)
|
||||||
g.writeln('\t__print_assert_failure(&$metaname_panic);')
|
g.writeln('\t__print_assert_failure(&$metaname_panic);')
|
||||||
if 'abort_on_assert' in g.pref.compile_defines_all {
|
g.gen_assert_postfailure_mode(node)
|
||||||
g.writeln('\tabort();')
|
|
||||||
}
|
|
||||||
g.writeln('\tv_panic(_SLIT("Assertion failed..."));')
|
g.writeln('\tv_panic(_SLIT("Assertion failed..."));')
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) gen_assert_postfailure_mode(node ast.AssertStmt) {
|
||||||
|
match g.pref.assert_failure_mode {
|
||||||
|
.default {}
|
||||||
|
.aborts {
|
||||||
|
g.writeln('\tabort();')
|
||||||
|
}
|
||||||
|
.backtraces {
|
||||||
|
g.writeln('\tprint_backtrace();')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut g Gen) gen_assert_metainfo(node ast.AssertStmt) string {
|
fn (mut g Gen) gen_assert_metainfo(node ast.AssertStmt) string {
|
||||||
mod_path := cestring(g.file.path)
|
mod_path := cestring(g.file.path)
|
||||||
fn_name := g.fn_decl.name
|
fn_name := g.fn_decl.name
|
||||||
|
|
|
@ -17,6 +17,12 @@ pub enum BuildMode {
|
||||||
build_module
|
build_module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum AssertFailureMode {
|
||||||
|
default
|
||||||
|
aborts
|
||||||
|
backtraces
|
||||||
|
}
|
||||||
|
|
||||||
pub enum GarbageCollectionMode {
|
pub enum GarbageCollectionMode {
|
||||||
no_gc
|
no_gc
|
||||||
boehm_full // full garbage collection mode
|
boehm_full // full garbage collection mode
|
||||||
|
@ -167,6 +173,7 @@ pub mut:
|
||||||
is_help bool // -h, -help or --help was passed
|
is_help bool // -h, -help or --help was passed
|
||||||
gc_mode GarbageCollectionMode = .no_gc // .no_gc, .boehm, .boehm_leak, ...
|
gc_mode GarbageCollectionMode = .no_gc // .no_gc, .boehm, .boehm_leak, ...
|
||||||
is_cstrict bool // turn on more C warnings; slightly slower
|
is_cstrict bool // turn on more C warnings; slightly slower
|
||||||
|
assert_failure_mode AssertFailureMode // whether to call abort() or print_backtrace() after an assertion failure
|
||||||
// checker settings:
|
// checker settings:
|
||||||
checker_match_exhaustive_cutoff_limit int = 10
|
checker_match_exhaustive_cutoff_limit int = 10
|
||||||
}
|
}
|
||||||
|
@ -197,6 +204,23 @@ pub fn parse_args(known_external_commands []string, args []string) (&Preferences
|
||||||
res.arch = target_arch_kind
|
res.arch = target_arch_kind
|
||||||
res.build_options << '$arg $target_arch'
|
res.build_options << '$arg $target_arch'
|
||||||
}
|
}
|
||||||
|
'-assert' {
|
||||||
|
assert_mode := cmdline.option(current_args, '-assert', '')
|
||||||
|
match assert_mode {
|
||||||
|
'aborts' {
|
||||||
|
res.assert_failure_mode = .aborts
|
||||||
|
}
|
||||||
|
'backtraces' {
|
||||||
|
res.assert_failure_mode = .backtraces
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
eprintln('unknown assert mode `-gc $assert_mode`, supported modes are:`')
|
||||||
|
eprintln(' `-assert aborts` .... calls abort() after assertion failure')
|
||||||
|
eprintln(' `-assert backtraces` .... calls print_backtrace() after assertion failure')
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
'-show-timings' {
|
'-show-timings' {
|
||||||
res.show_timings = true
|
res.show_timings = true
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue