#!/usr/bin/env perl use strict; use warnings; use diagnostics; use FindBin; use lib $FindBin::Bin; use Util; use feature 'say'; my $remote_root = '/home/lab/smchurla/Documents/failnix'; my $remote_db_conf = "$remote_root/db.conf"; my $remote_builds_dir = "$remote_root/builds"; my $remote_runner = "$remote_root/scripts/runner.pl"; my $db_user = "smchurla"; my $db_prefix = "$db_user"; my $fail_server_port = '22941'; my $resultbrowser_port = '22941'; my $fail_bin = "$remote_root/fail/bin"; my $fail_share = "$remote_root/fail/share"; my $bochs_runner = "$fail_bin/bochs-experiment-runner.py"; my $fail_trace = "$fail_bin/fail-x86-tracing"; my $fail_dump = "$fail_bin/dump-trace"; my $fail_import = "$fail_bin/import-trace"; my $fail_prune = "$fail_bin/prune-trace"; my $fail_server = "$fail_bin/generic-experiment-server"; my $fail_inject = "$fail_bin/generic-experiment-client"; my $result_browser = "$fail_bin/resultbrowser.py"; sub trace { my ($experiment) = @_; Util::notify("Tracing $experiment..."); system( join " ", ( "$bochs_runner", "-V $fail_share/vgabios.bin", "-b $fail_share/BIOS-bochs-latest", "-1", "-f $fail_trace", "-e $remote_builds_dir/$experiment/system.elf", "-i $remote_builds_dir/$experiment/system.iso", "--", "-Wf,--start-symbol=fail_start_trace", "-Wf,--save-symbol=fail_start_trace", "-Wf,--end-symbol=fail_stop_trace", "-Wf,--state-file=$remote_builds_dir/$experiment/state", "-Wf,--trace-file=$remote_builds_dir/$experiment/trace.pb", "-Wf,--elf-file=$remote_builds_dir/$experiment/system.elf" ) ); } sub import_trace { my ($experiment) = @_; Util::notify("Importing $experiment trace..."); system( join " ", ( "$fail_import", "--database-option-file $remote_db_conf", "-t $remote_builds_dir/$experiment/trace.pb", "-i MemoryImporter", "-e $remote_builds_dir/$experiment/system.elf", "-v $experiment", "-b mem" ) ); system( join " ", ( "$fail_import", "--database-option-file $remote_db_conf", "-t $remote_builds_dir/$experiment/trace.pb", "-i RegisterImporter", "-e $remote_builds_dir/$experiment/system.elf", "-v $experiment", "-b regs", "--flags" ) ); system( join " ", ( "$fail_import", "--database-option-file $remote_db_conf", "-t $remote_builds_dir/$experiment/trace.pb", "-i RegisterImporter", "-e $remote_builds_dir/$experiment/system.elf", "-v $experiment", "-b ip", "--no-gp", "--ip" ) ); system( join " ", ( "$fail_import", "--database-option-file $remote_db_conf", "-t $remote_builds_dir/$experiment/trace.pb", "-i ElfImporter", "--objdump objdump", "-e $remote_builds_dir/$experiment/system.elf", "-v $experiment", "-b ip" ) ); system( join " ", ( "$fail_import", "--database-option-file $remote_db_conf", "-t $remote_builds_dir/$experiment/trace.pb", "-i ElfImporter", "--objdump objdump", "-e $remote_builds_dir/$experiment/system.elf", "-v $experiment", "-b mem" ) ); system( join " ", ( "$fail_import", "--database-option-file $remote_db_conf", "-t $remote_builds_dir/$experiment/trace.pb", "-i ElfImporter", "--objdump objdump", "-e $remote_builds_dir/$experiment/system.elf", "-v $experiment", "-b regs" ) ); system( join " ", ( "$fail_prune", "--database-option-file $remote_db_conf", "-v $experiment", "-b %%", "--overwrite" ) ); } sub inject { my ($experiment) = @_; my $count = Util::cpu_count(); Util::notify("Injecting $experiment using $count cores..."); say "Forking..."; my $pid = fork(); die "fork failed: $!" unless defined $pid; if ( $pid == 0 ) { # child -> server say "Running server in child process..."; exec( join " ", ( "$fail_server", "--port $fail_server_port", "--database-option-file $remote_db_conf", "-v $experiment", "-b %", "--inject-single-bit", "--inject-registers" ) ) == 0 or die "exec server failed: $!"; } # parent -> client say "Waiting for server..."; sleep(10); say "Running client with $count cores in parent process"; system( join " ", ( "nice $bochs_runner", "-V $fail_share/vgabios.bin", "-b $fail_share/BIOS-bochs-latest", "-f $fail_inject", "-e $remote_builds_dir/$experiment/system.elf", "-i $remote_builds_dir/$experiment/system.iso", "-j $count", "--", "-Wf,--server-port=$fail_server_port", "-Wf,--state-dir=$remote_builds_dir/$experiment/state", "-Wf,--trap", "-Wf,--catch-outerspace", # "-Wf,--catch-write-textsegment", "-Wf,--timeout=500000", "-Wf,--ok-marker=fail_marker_positive", "-Wf,--fail-marker=fail_marker_negative", "-Wf,--detected-marker=fail_marker_detected", ">/dev/null" ) ) == 0 or die "client failed: $?"; say "Killing server with pid $pid..."; kill 'TERM', $pid; waitpid( $pid, 0 ); } sub results { my ($experiment) = @_; my @queries = Util::find_files("$remote_root/scripts/Queries"); foreach (@queries) { my $query = $_; $query =~ s/\.pm//g; # Util::notify("Running query $query for $experiment..."); Util::execute_query( $experiment, $query, $remote_db_conf, $remote_builds_dir, 1 ); } } # Run experiments my @experiments = Util::find_subdirs($remote_builds_dir); for my $experiment (@experiments) { Util::rewrite_file( $remote_db_conf, "database=", "database=${db_prefix}_$experiment\n" ); trace($experiment); import_trace($experiment); inject($experiment); results($experiment); }