From 4085356bd489c420d8beed17208117293d4edde6 Mon Sep 17 00:00:00 2001 From: Pierre Curto Date: Sun, 28 Jan 2024 15:39:50 +0100 Subject: [PATCH] v.gen.c: write the profile file out, even upon CTRL-C or kill (#20677) --- vlib/v/gen/c/cgen.v | 2 +- vlib/v/gen/c/cmain.v | 2 + vlib/v/gen/c/profile.v | 5 ++ vlib/v/slow_tests/profile/profile_test.v | 57 +++++++++++++++++++ .../profile/profile_test_interrupted.v | 7 +++ 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 vlib/v/slow_tests/profile/profile_test_interrupted.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index eaae142b1..863df5936 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -520,7 +520,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref_ &pref.Preferences) (string mut b := strings.new_builder(640000) b.write_string(g.hashes()) - if g.use_segfault_handler { + if g.use_segfault_handler || g.pref.is_prof { b.writeln('\n#define V_USE_SIGNAL_H') } b.writeln('\n// V comptime_definitions:') diff --git a/vlib/v/gen/c/cmain.v b/vlib/v/gen/c/cmain.v index 967c9280f..e6f25e69c 100644 --- a/vlib/v/gen/c/cmain.v +++ b/vlib/v/gen/c/cmain.v @@ -220,6 +220,8 @@ pub fn (mut g Gen) gen_failing_return_error_for_test_fn(return_stmt ast.Return, pub fn (mut g Gen) gen_c_main_profile_hook() { if g.pref.is_prof { g.writeln('') + g.writeln('\tsignal(SIGINT, vprint_profile_stats_on_signal);') + g.writeln('\tsignal(SIGTERM, vprint_profile_stats_on_signal);') g.writeln('\tatexit(vprint_profile_stats);') g.writeln('') } diff --git a/vlib/v/gen/c/profile.v b/vlib/v/gen/c/profile.v index 0aeeb1510..b2104abb3 100644 --- a/vlib/v/gen/c/profile.v +++ b/vlib/v/gen/c/profile.v @@ -71,4 +71,9 @@ pub fn (mut g Gen) gen_vprint_profile_stats() { } g.pcs_declarations.writeln('}') g.pcs_declarations.writeln('') + + g.pcs_declarations.writeln('void vprint_profile_stats_on_signal(int sig){') + g.pcs_declarations.writeln('\texit(130);') + g.pcs_declarations.writeln('}') + g.pcs_declarations.writeln('') } diff --git a/vlib/v/slow_tests/profile/profile_test.v b/vlib/v/slow_tests/profile/profile_test.v index 5ed2df9ac..439157d8f 100644 --- a/vlib/v/slow_tests/profile/profile_test.v +++ b/vlib/v/slow_tests/profile/profile_test.v @@ -1,4 +1,5 @@ import os +import time const vexe = os.getenv('VEXE') @@ -9,7 +10,61 @@ fn test_vexe_exists() { assert os.is_file(vexe) } +fn test_v_profile_works_when_interrupted() { + println(@FN) + $if windows { + if os.getenv('VTEST_RUN_PROFILE_INTERRUPTION').int() == 0 { + eprintln('> skipping ${@FN} on windows for now, since reading the output blocks currently') + return + } + } + sfile := 'vlib/v/slow_tests/profile/profile_test_interrupted.v' + program_source := os.join_path(vroot, sfile) + pid := os.getpid() + program_exe := os.join_path(os.cache_dir(), 'profile_test_interrupted_pid_${pid}.exe') + program_profile := os.join_path(os.cache_dir(), 'profile_test_interrupted_pid_${pid}.profile') + os.rm(program_exe) or {} + os.rm(program_profile) or {} + os.chdir(vroot) or {} + compile_cmd := '${os.quoted_path(vexe)} -skip-unused -o ${os.quoted_path(program_exe)} -profile ${os.quoted_path(program_profile)} ${os.quoted_path(program_source)}' + eprintln('> compiling cmd: ${compile_cmd}') + compilation_result := os.execute(compile_cmd) + assert compilation_result.exit_code == 0, compilation_result.output + eprintln('> compiled ${program_exe}') + mut p := os.new_process(program_exe) + p.set_redirect_stdio() + p.run() + eprintln('> started ${program_exe} at: ${time.now().format_ss_micro()}') + mut lines := []string{} + for p.is_alive() && lines.len < 5 { + if data := p.pipe_read(.stdout) { + lines << data.trim_space().split_into_lines() + } + time.sleep(10 * time.millisecond) + } + dump(lines) + assert lines.len > 4, lines.str() + assert lines.contains('0003 iteration'), lines.str() + eprintln('> stopping ${program_exe} at: ${time.now().format_ss_micro()}...') + p.signal_term() + eprintln('> waiting ${program_exe}') + p.wait() + eprintln('> closing ${program_exe}') + p.close() + assert p.code == 130 + assert p.status == .closed + eprintln('> reading profile_content from ${program_profile} ...') + profile_content := os.read_file(program_profile)! + assert profile_content.contains('str_intp') + assert profile_content.contains('println') + assert profile_content.contains('time__sleep') + assert profile_content.contains('main__main') + // dump(profile_content) + eprintln('-'.repeat(120)) +} + fn test_v_profile_works() { + println(@FN) sfile := 'vlib/v/slow_tests/profile/profile_test_1.v' validate_output(@FN, '', sfile, { 'os__init_os_args': 1 @@ -20,6 +75,7 @@ fn test_v_profile_works() { } fn test_v_profile_on_off_api_works() { + println(@FN) sfile := 'vlib/v/slow_tests/profile/profile_test_2.v' res_lines := validate_output(@FN, '', sfile, { 'builtin_init': 1 @@ -37,6 +93,7 @@ fn test_v_profile_on_off_api_works() { } fn test_v_profile_fns_option_works() { + println(@FN) sfile := 'vlib/v/slow_tests/profile/profile_test_3.v' validate_output(@FN, '-profile-fns println', sfile, { 'main__main': -1 diff --git a/vlib/v/slow_tests/profile/profile_test_interrupted.v b/vlib/v/slow_tests/profile/profile_test_interrupted.v new file mode 100644 index 000000000..c30630f11 --- /dev/null +++ b/vlib/v/slow_tests/profile/profile_test_interrupted.v @@ -0,0 +1,7 @@ +import time + +unbuffer_stdout() +for i in 1 .. 9999 { + time.sleep(10 * time.millisecond) + println('${i:04} iteration') +} -- 2.39.5