From 751ba48bf56cf081b62a53ce093488eecaa25fb8 Mon Sep 17 00:00:00 2001 From: bogen85 <52499484+bogen85@users.noreply.github.com> Date: Sat, 7 Dec 2019 13:25:19 -0600 Subject: [PATCH] freestanding improvements (exit, function checks) Fixed exit for freestanding (as assert now uses it). Running each function check now in a forked process so they can be killed or return other exit codes (and so each function runs, even if others crash) --- vlib/builtin/bare/.checks/checks.v | 6 +- vlib/builtin/bare/.checks/consts/consts.v | 25 +++-- .../bare/.checks/forkedtest/forkedtest.v | 58 ++++++++++++ vlib/builtin/bare/.checks/linuxsys/linuxsys.v | 93 ++++++------------- vlib/builtin/bare/.checks/string/string.v | 17 ++-- vlib/builtin/bare/linuxsys_bare.v | 5 +- vlib/builtin/bare/mm_bare.v | 3 +- vlib/compiler/cheaders.v | 5 + 8 files changed, 127 insertions(+), 85 deletions(-) create mode 100644 vlib/builtin/bare/.checks/forkedtest/forkedtest.v diff --git a/vlib/builtin/bare/.checks/checks.v b/vlib/builtin/bare/.checks/checks.v index b9a900353d..25c7618259 100644 --- a/vlib/builtin/bare/.checks/checks.v +++ b/vlib/builtin/bare/.checks/checks.v @@ -12,7 +12,8 @@ fn passed (msg string) { fn vcheck(vfile string) { - run_check := "v -show_c_cmd -freestanding --enable-globals run " + //os.system("ln -s ../forkedtest $vfile/forkedtest") + run_check := "v -user_mod_path . -freestanding --enable-globals run " if 0 == os.system("$run_check $vfile/${vfile}.v") { passed(run_check) } else { @@ -20,11 +21,12 @@ fn vcheck(vfile string) { } os.system("ls -lh $vfile/$vfile") os.system("rm -f $vfile/$vfile") + //os.system("rm -f $vfile/forkedtest") } fn main() { - vcheck("string") vcheck("linuxsys") + vcheck("string") vcheck("consts") exit(0) } diff --git a/vlib/builtin/bare/.checks/consts/consts.v b/vlib/builtin/bare/.checks/consts/consts.v index a34f7d5f98..eee2c61484 100644 --- a/vlib/builtin/bare/.checks/consts/consts.v +++ b/vlib/builtin/bare/.checks/consts/consts.v @@ -1,15 +1,22 @@ module main +import forkedtest const ( - integer1 = 111 - integer2 = 222 - integer3 = 333 - integer9 = integer3 * 3 - abc = "123" + integer1 = 111 + integer2 = 222 + integer3 = integer1+integer2 + integer9 = integer3 * 3 + abc = "123" ) -fn main(){ - assert abc == "123" - assert integer9 == 999 - println("constants are properly initialized") +fn check_const_initialization() { + assert abc == "123" + assert integer9 == 999 +} + +fn main(){ + mut fails := 0 + fails += forkedtest.normal_run(check_const_initialization, "check_const_initialization") + assert fails == 0 + sys_exit(0) } diff --git a/vlib/builtin/bare/.checks/forkedtest/forkedtest.v b/vlib/builtin/bare/.checks/forkedtest/forkedtest.v new file mode 100644 index 0000000000..9d1d27d895 --- /dev/null +++ b/vlib/builtin/bare/.checks/forkedtest/forkedtest.v @@ -0,0 +1,58 @@ +module forkedtest + +__global buffer [128]byte + +pub fn run (op fn(), label string, code wi_si_code, status int) int { + child := sys_fork() + if child == 0 { + op() + sys_exit(0) + } + siginfo := [ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0] + + e := sys_waitid(.p_pid, child, intptr(siginfo.data) , .wexited, 0) + + assert e == .enoerror + assert siginfo[sig_index.si_pid] == child + assert siginfo[sig_index.si_signo] == int(signo.sigchld) + assert siginfo[sig_index.si_uid] == sys_getuid() + + r_code := siginfo[sig_index.si_code] + r_status := siginfo[sig_index.si_status] + + print(label) + if (int(code) == r_code) && (status == r_status) { + println(" PASSED") + return 0 + } + println(" FAILED") + + if int(code) != r_code { + print(">> Expecting si_code 0x") + println(i64_tos(buffer,80,int(code),16)) + print(">> Got 0x") + println(i64_tos(buffer,80,r_code,16)) + } + + if status != r_status { + print(">> Expecting status 0x") + println(i64_tos(buffer,80,status,16)) + print(">> Got 0x") + println(i64_tos(buffer,80,r_status,16)) + } + + return 1 +} + +pub fn normal_run (op fn(), label string) int { + return run (op, label, .cld_exited, 0) +} + diff --git a/vlib/builtin/bare/.checks/linuxsys/linuxsys.v b/vlib/builtin/bare/.checks/linuxsys/linuxsys.v index bb7fccaf9a..dd72c6268d 100644 --- a/vlib/builtin/bare/.checks/linuxsys/linuxsys.v +++ b/vlib/builtin/bare/.checks/linuxsys/linuxsys.v @@ -1,7 +1,5 @@ module main - -__global fd [2]int -__global buffer [128]byte +import forkedtest const ( sample_text_file1 = "" @@ -15,7 +13,7 @@ fn check_fork_minimal () { sys_exit(ec) } siginfo := [ - int(0), 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -27,14 +25,12 @@ fn check_fork_minimal () { e := sys_waitid(.p_pid, child, intptr(siginfo.data) , .wexited, 0) assert e == .enoerror - //println(i64_tos(buffer,80,siginfo[sig_index.si_code],16)) + //println(i64_tos(buffer0,80,siginfo[sig_index.si_code],16)) assert siginfo[sig_index.si_code] == int(wi_si_code.cld_exited) assert siginfo[sig_index.si_pid] == child assert siginfo[sig_index.si_status] == ec assert siginfo[sig_index.si_signo] == int(signo.sigchld) assert siginfo[sig_index.si_uid] == sys_getuid() - - println("fork minimal check passed") } fn check_read_write_pipe() { @@ -44,14 +40,15 @@ fn check_read_write_pipe() { // sys_read // sys_close // - println ("checking pipe read/write") - fd[0] = -1 - fd[1] = -1 + buffer, e := mm_alloc(128) + assert e == .enoerror + + fd := [-1, -1] assert fd[0] == -1 assert fd[1] == -1 - a := sys_pipe(intptr(fd)) + a := sys_pipe(intptr(fd.data)) assert a == .enoerror @@ -81,7 +78,7 @@ fn check_read_write_pipe() { assert sys_close(-1) == .ebadf - println ("pipe read/write passed") + assert mm_free(buffer) == .enoerror } fn check_read_file() { @@ -92,9 +89,11 @@ fn check_read_file() { sys_close sys_open */ + buffer, mae := mm_alloc(128) + assert mae == .enoerror + test_file := "sample_text1.txt" sample_text := "Do not change this text.\n" - println ("checking read file") fd, ec := sys_open(test_file.str, .o_rdonly, 0) assert fd > 0 assert ec == .enoerror @@ -106,16 +105,13 @@ fn check_read_file() { assert sample_text[i] == buffer[i] } assert sys_close(fd) == .enoerror - - println("read file passed") + assert mm_free(buffer) == .enoerror } fn check_open_file_fail() { - println ("checking 'open file fail'") fd1, ec1 := sys_open("./nofilehere".str, .o_rdonly, 0) assert fd1 == -1 assert ec1 == .enoent - println ("'open file fail' check passed") } /* @@ -133,19 +129,11 @@ fn check_print() { */ fn check_munmap_fail() { - println ("checking 'munmap fail'") - ec := sys_munmap(-16384,8192) assert ec == .einval - //es := i64_tos(buffer2,80,int(ec),16) - //println(es) - - println ("'munmap fail' check passed") } fn check_mmap_one_page() { - println ("checking check_mmap_one_page") - mp := int(mm_prot.prot_read) | int(mm_prot.prot_write) mf := int(map_flags.map_private) | int(map_flags.map_anonymous) mut a, e := sys_mmap(0, u64(linux_mem.page_size), mm_prot(mp), map_flags(mf), -1, 0) @@ -161,12 +149,9 @@ fn check_mmap_one_page() { ec := sys_munmap(a, u64(linux_mem.page_size)) assert ec == .enoerror - - println ("check_mmap_one_page passed") } fn check_mm_pages() { - println ("checking check_mm_pages") for i in 0 .. int(linux_mem.page_size)-4 { assert u32(1) == mm_pages(u64(i)) } @@ -176,24 +161,16 @@ fn check_mm_pages() { for i in (int(linux_mem.page_size)*2)-3 .. (int(linux_mem.page_size)*3)-4 { assert u32(3) == mm_pages(u64(i)) } - println ("check_mm_pages passed") } //pub fn mm_alloc(size u64) (voidptr, errno) fn check_mm_alloc() { - println ("checking mm_alloc") - for i in 1 .. 2000 { size := u64(i*1000) pages := mm_pages(size) mut a, e := mm_alloc(size) - //ads := i64_tos(buffer,80,i64(a),16) - //println(ads) - //es := i64_tos(buffer,80,i64(e),16) - //println(es) - assert e == .enoerror ap := intptr(a-4) assert *ap == int(pages) @@ -210,27 +187,20 @@ fn check_mm_alloc() { mfa := mm_free(a) - //mfas := i64_tos(buffer,80,i64(mfa),16) - //println(mfas) - assert mfa == .enoerror } - println ("mm_alloc passed") } fn check_int_array_ro() { - println ("trying check_int_array_ro") a := [100,110,120,130] assert a.len == 4 assert a[0] == 100 assert a[1] == 110 assert a[2] == 120 assert a[3] == 130 - println ("check_int_array_ro passed") } fn check_int_array_rw() { - println ("trying check_int_array_rw") mut a := [-10,-11,-12,-13] assert a.len == 4 assert a[0] == -10 @@ -243,12 +213,9 @@ fn check_int_array_rw() { assert a[i] == b } assert a[3] == 130 - - println ("check_int_array_rw passed") } fn check_int64_array_ro() { - println ("trying check_int64_array_ro") a := [i64(1000),1100,1200,1300,1400] assert a.len == 5 assert a[0] == 1000 @@ -256,11 +223,9 @@ fn check_int64_array_ro() { assert a[2] == 1200 assert a[3] == 1300 assert a[4] == 1400 - println ("check_int64_array_ro passed") } fn check_voidptr_array_ro() { - println ("trying check_voidptr_array_ro") a := [ voidptr(10000), voidptr(11000), @@ -276,11 +241,9 @@ fn check_voidptr_array_ro() { assert a[3] == voidptr(13000) assert a[4] == voidptr(14000) assert a[5] == voidptr(15000) - println ("check_voidptr_array_ro passed") } fn check_voidptr_array_rw() { - println ("trying check_voidptr_array_rw") mut a := [ voidptr(-1), voidptr(-1), @@ -315,24 +278,26 @@ fn check_voidptr_array_rw() { a[5] = voidptr(150000) assert a[5] == voidptr(150000) - println ("check_voidptr_array_rw passed") } fn main() { - check_read_write_pipe() - check_read_file() + mut fails := 0 + fails += forkedtest.normal_run(check_fork_minimal, "check_fork_minimal") + fails += forkedtest.normal_run(check_munmap_fail, "check_munmap_fail") + fails += forkedtest.normal_run(check_mmap_one_page, "check_mmap_one_page") + fails += forkedtest.normal_run(check_mm_pages, "check_mm_pages") + fails += forkedtest.normal_run(check_mm_alloc, "check_mm_alloc") + fails += forkedtest.normal_run(check_read_write_pipe, "check_read_write_pipe") + fails += forkedtest.normal_run(check_read_file, "check_read_file") // check_print() - check_open_file_fail() - check_munmap_fail() - check_mmap_one_page() - check_mm_pages() - check_mm_alloc() - check_int_array_ro() - check_int_array_rw() - check_int64_array_ro() - check_voidptr_array_ro() - check_voidptr_array_rw() - check_fork_minimal() + fails += forkedtest.normal_run(check_open_file_fail, "check_open_file_fail") + fails += forkedtest.normal_run(check_int_array_ro, "check_int_array_ro") + fails += forkedtest.normal_run(check_int_array_rw, "check_int_array_rw") + fails += forkedtest.normal_run(check_int64_array_ro, "check_int64_array_ro") + fails += forkedtest.normal_run(check_voidptr_array_ro, "check_voidptr_array_ro") + fails += forkedtest.normal_run(check_voidptr_array_rw, "check_voidptr_array_rw") + + assert fails == 0 sys_exit(0) } diff --git a/vlib/builtin/bare/.checks/string/string.v b/vlib/builtin/bare/.checks/string/string.v index b4614097ce..5da867c6c6 100644 --- a/vlib/builtin/bare/.checks/string/string.v +++ b/vlib/builtin/bare/.checks/string/string.v @@ -1,16 +1,17 @@ module main - -__global buffer [128]byte +import forkedtest fn check_string_eq () { - println ("checking string_eq") assert "monkey" != "rat" some_animal := "a bird" assert some_animal == "a bird" - println ("string_eq passed") } fn check_i64_tos() { + buffer, e := mm_alloc(128) + assert e == .enoerror + assert !isnil(buffer) + s0 := i64_tos(buffer, 70, 140, 10) assert s0 == "140" @@ -22,11 +23,15 @@ fn check_i64_tos() { s3 := i64_tos(buffer, 70, -160000, 10) assert s3 == "-160000" + + assert mm_free(buffer) == .enoerror } fn main () { - check_string_eq () - check_i64_tos() + mut fails := 0 + fails += forkedtest.normal_run(check_string_eq, "check_string_eq") + fails += forkedtest.normal_run(check_i64_tos, "check_i64_tos") + assert fails == 0 sys_exit(0) } diff --git a/vlib/builtin/bare/linuxsys_bare.v b/vlib/builtin/bare/linuxsys_bare.v index 369b74b27a..29670e38dc 100644 --- a/vlib/builtin/bare/linuxsys_bare.v +++ b/vlib/builtin/bare/linuxsys_bare.v @@ -89,7 +89,6 @@ pub enum signo { sigttin = 21 // Background read from control terminal. sigttou = 22 // Background write to control terminal. - sigpoll = 23 // Pollable event occurred (System V). sigxcpu = 24 // CPU time limit exceeded. sigxfsz = 25 // File size limit exceeded. sigvtalrm = 26 // Virtual timer expired. @@ -427,7 +426,7 @@ https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/ >0 sys_read unsigned int fd char *buf size_t count >1 sys_write unsigned int fd const char *buf size_t count -2 sys_open const char *filename int flags int mode +>2 sys_open const char *filename int flags int mode >3 sys_close unsigned int fd 4 sys_stat const char *filename struct stat *statbuf 5 sys_fstat unsigned int fd struct stat *statbuf @@ -527,7 +526,7 @@ https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/ 99 sys_sysinfo struct sysinfo *info 100 sys_times struct sysinfo *info 101 sys_ptrace long request long pid unsigned long addr unsigned long data -102 sys_getuid +>102 sys_getuid 103 sys_syslog int type char *buf int len 104 sys_getgid 105 sys_setuid uid_t uid diff --git a/vlib/builtin/bare/mm_bare.v b/vlib/builtin/bare/mm_bare.v index d551a1b189..a97607916d 100644 --- a/vlib/builtin/bare/mm_bare.v +++ b/vlib/builtin/bare/mm_bare.v @@ -3,10 +3,11 @@ module builtin const ( mem_prot = mm_prot(int(mm_prot.prot_read) | int(mm_prot.prot_write)) mem_flags = map_flags(int(map_flags.map_private) | int(map_flags.map_anonymous)) + page_size = u64(linux_mem.page_size) ) pub fn mm_pages(size u64) u32 { - pages := (u64(size+u64(4))+u64(linux_mem.page_size))/u64(linux_mem.page_size) + pages := (size+u64(4)+page_size)/page_size return u32(pages) } diff --git a/vlib/compiler/cheaders.v b/vlib/compiler/cheaders.v index f0dcaa94cd..0146781cc5 100644 --- a/vlib/compiler/cheaders.v +++ b/vlib/compiler/cheaders.v @@ -218,5 +218,10 @@ bare_c_headers = ' #undef TCCSKIP #define TCCSKIP(x) #endif + +#ifndef exit +#define exit(rc) sys_exit(rc) +void sys_exit (int); +#endif ' )