290 lines
7.9 KiB
Perl
290 lines
7.9 KiB
Perl
#!/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"
|
|
|
|
# "-Wf,--full-trace",
|
|
# "-Wf,--check-bounds",
|
|
)
|
|
);
|
|
}
|
|
|
|
sub import_trace {
|
|
my ($experiment) = @_;
|
|
|
|
Util::notify("Importing $experiment trace...");
|
|
|
|
# Benchmark: ip
|
|
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", # Don't inject general purpose registers
|
|
"--ip" # Inject instruction pointer
|
|
)
|
|
);
|
|
|
|
# Benchmark: mem
|
|
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"
|
|
)
|
|
);
|
|
|
|
# Benchmark: regs
|
|
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" # Inject flags register
|
|
)
|
|
);
|
|
|
|
# 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 objdump disassembly + source files
|
|
system(
|
|
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",
|
|
)
|
|
);
|
|
system(
|
|
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",
|
|
)
|
|
);
|
|
system(
|
|
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",
|
|
)
|
|
);
|
|
|
|
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...");
|
|
|
|
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_root/server.log"
|
|
);
|
|
say "Server command: $server_command";
|
|
|
|
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",
|
|
"-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"
|
|
">$remote_root/client.log"
|
|
);
|
|
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 = 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 );
|
|
}
|
|
}
|
|
|
|
# system("rm $remote_root/runner.log");
|
|
system("rm $remote_root/server.log");
|
|
system("rm $remote_root/client.log");
|
|
|
|
# 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);
|
|
|
|
# system(
|
|
# "mv $remote_root/runner.log $remote_builds_dir/$experiment/runner.log");
|
|
system(
|
|
"mv $remote_root/server.log $remote_builds_dir/$experiment/server.log");
|
|
system(
|
|
"mv $remote_root/client.log $remote_builds_dir/$experiment/client.log");
|
|
}
|
|
|
|
Util::notify("Finished all experiments");
|