Files
failnix/scripts/runner.pl

305 lines
9.2 KiB
Perl

#!/usr/bin/env perl
use strict;
use warnings;
use diagnostics;
use FindBin;
# runner.pl is executed from the build dir
use lib "$FindBin::Bin/../../scripts/Modules";
use lib "$FindBin::Bin/Modules";
use Filters;
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...");
my $trace_command = 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",
# "-Wf,--full-trace",
# "-Wf,--check-bounds",
">$remote_builds_dir/$experiment/1_trace.log 2>&1"
);
say "Trace command: $trace_command";
system($trace_command);
}
sub import_trace {
my ($experiment) = @_;
# Util::notify("Importing $experiment trace...");
# Benchmark: ip
my $import_ip_command = 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", # Don't inject general purpose registers
"--ip", # Inject instruction pointer
">$remote_builds_dir/$experiment/2_import_ip.log 2>&1"
);
say "Import IP command: $import_ip_command";
system($import_ip_command);
# Benchmark: mem
my $import_mem_command = 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",
">$remote_builds_dir/$experiment/2_import_mem.log 2>&1"
);
say "Import MEM command: $import_mem_command";
system($import_mem_command);
# Benchmark: regs
my $import_regs_command = 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", # Inject flags register
">$remote_builds_dir/$experiment/2_import_regs.log 2>&1"
);
say "Import REGS command: $import_regs_command";
system($import_regs_command);
# Import fulltrace for VisualFAIL
# system(
# join " ",
# (
# "$fail_import",
# "--database-option-file $remote_db_conf",
# "-t $remote_builds_dir/$experiment/trace.pb",
# "-i FullTraceImporter",
# "-e $remote_builds_dir/$experiment/system.elf",
# "-v $experiment",
# )
# );
# Import disassembly/sources
my $import_ip_asm_command = join " ", (
"$fail_import",
"--database-option-file $remote_db_conf",
"-t $remote_builds_dir/$experiment/trace.pb",
"-i ElfImporter",
"-e $remote_builds_dir/$experiment/system.elf",
"-v $experiment",
"-b ip",
"--objdump objdump",
# "--sources",
">$remote_builds_dir/$experiment/2_import_ip_asm.log 2>&1"
);
say "Import IP Asm command: $import_ip_asm_command";
system($import_ip_asm_command);
my $import_mem_asm_command = join " ", (
"$fail_import",
"--database-option-file $remote_db_conf",
"-t $remote_builds_dir/$experiment/trace.pb",
"-i ElfImporter",
"-e $remote_builds_dir/$experiment/system.elf",
"-v $experiment",
"-b mem",
"--objdump objdump",
# "--sources",
">$remote_builds_dir/$experiment/2_import_mem_asm.log 2>&1"
);
say "Import Mem Asm command: $import_mem_asm_command";
system($import_mem_asm_command);
my $import_regs_asm_command = join " ", (
"$fail_import",
"--database-option-file $remote_db_conf",
"-t $remote_builds_dir/$experiment/trace.pb",
"-i ElfImporter",
"-e $remote_builds_dir/$experiment/system.elf",
"-v $experiment",
"-b regs",
"--objdump objdump",
# "--sources",
">$remote_builds_dir/$experiment/2_import_regs_asm.log 2>&1"
);
say "Import Regs Asm command: $import_regs_asm_command";
system($import_regs_asm_command);
my $prune_command = join " ", (
"$fail_prune", "--database-option-file $remote_db_conf",
"-v $experiment", "-b %%",
# '-p NoPruner',
'-p BasicPruner',
"--overwrite", ">$remote_builds_dir/$experiment/2_prune.log 2>&1"
);
say "Prune command: $prune_command";
system($prune_command);
}
sub inject {
my ($experiment) = @_;
my $count = Util::cpu_count();
Util::notify("Injecting $experiment using $count cores...");
my $server_command = join " ", (
"$fail_server",
# "--port $fail_server_port",
"--database-option-file $remote_db_conf", "-v $experiment",
"-b %", "--inject-single-bit",
"--inject-registers",
">$remote_builds_dir/$experiment/3_server.log 2>&1"
);
say "Server command: $server_command";
# Read catch flags written by build.pl into the experiment directory
my $runner_flags_file = "$remote_builds_dir/$experiment/runner_flags";
my @catch_flags = ();
if ( -e $runner_flags_file ) {
open( my $rfh, '<', $runner_flags_file )
or die "Cannot open $runner_flags_file: $!";
@catch_flags = map { chomp; "-Wf,$_" } grep { /\S/ } <$rfh>;
close($rfh);
}
my $client_command = 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",
@catch_flags,
"-Wf,--timeout=500000",
"-Wf,--ok-marker=fail_marker_positive",
"-Wf,--fail-marker=fail_marker_negative",
"-Wf,--detected-marker=fail_marker_detected",
# Called in WAMR exception handler (disable for C compilation target!)
# "-Wf,--group1-marker=fail_marker_group1",
">/dev/null 2>&1"
# ">$remote_builds_dir/$experiment/4_client.log 2>&1"
);
say "Client command: $client_command";
say "Forking...";
my $pid = fork();
die "fork failed: $!" unless defined $pid;
if ( $pid == 0 ) {
# child -> server
say "Running server in child process...";
exec($server_command) == 0 or die "exec server failed: $!";
}
# parent -> client
say "Waiting for server...";
sleep(10);
say "Running client with $count cores in parent process";
system($client_command) == 0 or die "client failed: $?";
say "Killing server with pid $pid...";
kill 'TERM', $pid;
waitpid( $pid, 0 );
}
sub results {
my ($experiment) = @_;
my @queries =
map { s/\.pm//gr } Util::find_files("$remote_root/scripts/Queries");
my @configs = ( '', Filters::get_default_configs() );
for my $query (@queries) {
for my $config (@configs) {
Util::execute_query( $experiment, $query,
$remote_db_conf, $remote_builds_dir, 1, $config );
}
}
}
# Run single experiment passed as argument
my $experiment = $ARGV[0] or die "Usage: runner.pl <experiment>\n";
Util::rewrite_file( $remote_db_conf, "database=",
"database=${db_prefix}_$experiment\n" );
say "Killing generic-experiment-server process if it's running...";
system( "pkill", "-u", $db_user, "-f", "generic-experiment-server" );
sleep(10);
trace($experiment);
import_trace($experiment);
inject($experiment);
results($experiment);
Util::notify("Finished experiment $experiment");