Compare commits
29 Commits
551335bf53
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
9ca8e88ec0
|
|||
|
be2c4b7bf2
|
|||
|
644603fb8b
|
|||
|
0dccd1df46
|
|||
|
9db4cb8bb1
|
|||
| 10fe608a90 | |||
|
2de6e20675
|
|||
|
bc98e2af5c
|
|||
|
3819e84acb
|
|||
|
6ce8987ebd
|
|||
|
6859402483
|
|||
|
32b1f3fa31
|
|||
|
a6f33f1960
|
|||
|
1bf4886c64
|
|||
|
e33fed9b8d
|
|||
|
c87409dd5c
|
|||
|
5f6537b7ea
|
|||
|
5bfe1a366b
|
|||
|
f2559c8445
|
|||
|
4d0693dd30
|
|||
|
bba9ced348
|
|||
|
a8aa0bbb07
|
|||
|
1257534a64
|
|||
|
5aab319424
|
|||
|
348aac20ae
|
|||
|
5da8fffed0
|
|||
|
2b554a22ad
|
|||
|
c76b0b8a8e
|
|||
|
5f42323ccb
|
80
charts/combined_sankey.r
Normal file
80
charts/combined_sankey.r
Normal file
@ -0,0 +1,80 @@
|
||||
library(ggplot2)
|
||||
library(ggalluvial)
|
||||
|
||||
# Usage: Rscript combined_comparion.r exp_abspath1 exp_abspath2 ...
|
||||
|
||||
args <- commandArgs(trailingOnly = TRUE)
|
||||
argc <- length(args)
|
||||
|
||||
if (argc != 2) {
|
||||
print("Expecting two input files")
|
||||
stop()
|
||||
}
|
||||
|
||||
for (experiment in args) {
|
||||
datafile <- paste(experiment, "/faults.csv", sep = "")
|
||||
if (!file.exists(datafile)) {
|
||||
print(paste("Input file", datafile, "is missing"))
|
||||
stop()
|
||||
}
|
||||
}
|
||||
|
||||
resulttype_labels <- c(
|
||||
OK_MARKER = "OK",
|
||||
FAIL_MARKER = "FAIL",
|
||||
DETECTED_MARKER = "DETECTED",
|
||||
TIMEOUT = "TIMEOUT",
|
||||
TRAP = "TRAP",
|
||||
ACCESS_OUTERSPACE = "OUTERSPC",
|
||||
WRITE_TEXTSEGMENT = "WRITETXT"
|
||||
)
|
||||
|
||||
# Read data
|
||||
datafile1 <- paste(args[1], "/faults.csv", sep = "")
|
||||
data1 <- readr::read_csv(datafile1)
|
||||
data1$fault_address <- strtoi(data1$fault_address)
|
||||
data1$resulttype <- resulttype_labels[data1$resulttype]
|
||||
# tibble::glimpse(data1)
|
||||
|
||||
datafile2 <- paste(args[2], "/faults.csv", sep = "")
|
||||
data2 <- readr::read_csv(datafile2)
|
||||
data2$fault_address <- strtoi(data2$fault_address)
|
||||
data2$resulttype <- resulttype_labels[data2$resulttype]
|
||||
# tibble::glimpse(data2)
|
||||
|
||||
# https://corybrunson.github.io/ggalluvial/
|
||||
joined <- merge(
|
||||
data1[, c("fault_address", "resulttype", "faults")],
|
||||
data2[, c("fault_address", "resulttype", "faults")],
|
||||
by = "fault_address",
|
||||
suffixes = c("_bench1", "_bench2")
|
||||
)
|
||||
|
||||
streams <- aggregate(
|
||||
faults_bench2 ~ resulttype_bench1 + resulttype_bench2,
|
||||
data = joined,
|
||||
sum
|
||||
)
|
||||
names(streams) <- c("bench1", "bench2", "faults")
|
||||
|
||||
plot <- ggplot(
|
||||
data = streams,
|
||||
aes(axis1 = bench1, axis2 = bench2, y = faults)
|
||||
) +
|
||||
scale_x_discrete(
|
||||
# TODO: Name the benchmarks
|
||||
# limits = c(args[1], args[2])
|
||||
limits = c("Bench A", "Bench B")
|
||||
) +
|
||||
labs(x = "Benchmark", y = "Faults") +
|
||||
geom_alluvium(aes(fill = bench1)) +
|
||||
geom_stratum() +
|
||||
geom_text(stat = "stratum", aes(label = after_stat(stratum))) +
|
||||
theme_minimal() +
|
||||
theme(legend.position = "none")
|
||||
|
||||
# TODO: Name the file according to the benchmarks
|
||||
ggsave(
|
||||
paste(args[2], "/../sankey.svg", sep = ""),
|
||||
plot = plot,
|
||||
)
|
||||
BIN
fail/bin/fail-x86-tracing
(Stored with Git LFS)
BIN
fail/bin/fail-x86-tracing
(Stored with Git LFS)
Binary file not shown.
BIN
fail/bin/generic-experiment-client
(Stored with Git LFS)
BIN
fail/bin/generic-experiment-client
(Stored with Git LFS)
Binary file not shown.
BIN
fail/bin/generic-experiment-server
(Stored with Git LFS)
BIN
fail/bin/generic-experiment-server
(Stored with Git LFS)
Binary file not shown.
BIN
fail/bin/import-trace
(Stored with Git LFS)
BIN
fail/bin/import-trace
(Stored with Git LFS)
Binary file not shown.
BIN
fail/bin/prune-trace
(Stored with Git LFS)
BIN
fail/bin/prune-trace
(Stored with Git LFS)
Binary file not shown.
6
flake.lock
generated
6
flake.lock
generated
@ -20,11 +20,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1773110118,
|
||||
"narHash": "sha256-mPAG8phMbCReKSiKAijjjd3v7uVcJOQ75gSjGJjt/Rk=",
|
||||
"lastModified": 1776329215,
|
||||
"narHash": "sha256-a8BYi3mzoJ/AcJP8UldOx8emoPRLeWqALZWu4ZvjPXw=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e607cb5360ff1234862ac9f8839522becb853bb9",
|
||||
"rev": "b86751bc4085f48661017fa226dee99fab6c651b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
34
flake.nix
34
flake.nix
@ -321,10 +321,12 @@ rec {
|
||||
src = pkgs.fetchFromGitea {
|
||||
domain = "gitea.local.chriphost.de";
|
||||
owner = "christoph";
|
||||
# domain = "git.cs.tu-dortmund.de";
|
||||
# owner = "christoph.urlacher";
|
||||
repo = "wamr";
|
||||
|
||||
# With mmap_space in .text.wamr_aot
|
||||
rev = "cda2008deb85511089b04b0ac736ad4da2d07e58";
|
||||
rev = "cda2009deb85511089b04b0ac736ad4da2d07e58";
|
||||
hash = "sha256-CN6xTiwzF4Jbrpf21TF5c/C03Xb3urwkibRuIXjoU/w=";
|
||||
|
||||
# Without mmap_space in .text.wamr_aot
|
||||
@ -413,7 +415,10 @@ rec {
|
||||
grub2
|
||||
xorriso
|
||||
mariadb.client
|
||||
dbeaver-bin
|
||||
# dbeaver-bin
|
||||
# beekeeper-studio
|
||||
# tableplus
|
||||
lazysql
|
||||
iwasm
|
||||
wamrc
|
||||
fail-bin
|
||||
@ -448,17 +453,28 @@ rec {
|
||||
buildInputs = with pkgs; [
|
||||
# FAIL runtime dependencies
|
||||
python # bochs-experiment-runner.py, resultbrowser.py
|
||||
alsa-lib # libasound.so.2
|
||||
boost_pkgs.boost174 # libboost_coroutine.so.1.74.0, libboost_regex.so.1.74.0, libboost_thread.so.1.74.0
|
||||
capstone_4 # libcapstone.so.4
|
||||
|
||||
# For old VSS FAIL
|
||||
# alsa-lib # libasound.so.2
|
||||
# boost_pkgs.boost174 # libboost_coroutine.so.1.74.0, libboost_regex.so.1.74.0, libboost_thread.so.1.74.0
|
||||
# capstone_4 # libcapstone.so.4
|
||||
# libdwarf_pkgs.libdwarf # libdwarf.so.1
|
||||
# elfutils # libelf.so.1
|
||||
# mariadb # libmariadb.so.3
|
||||
# libpcl # libpcl.so.1
|
||||
# protobuf_21 # libprotobuf.so.32
|
||||
# SDL # libSDL-1.2.so.0
|
||||
# libx11 # libX11.so.6
|
||||
# libxrandr # libXrandr.so.2
|
||||
# libz # libz.so.1
|
||||
|
||||
# For current FAIL
|
||||
boost183
|
||||
capstone # libcapstone.so.5
|
||||
libdwarf_pkgs.libdwarf # libdwarf.so.1
|
||||
elfutils # libelf.so.1
|
||||
mariadb # libmariadb.so.3
|
||||
libpcl # libpcl.so.1
|
||||
protobuf_21 # libprotobuf.so.32
|
||||
SDL # libSDL-1.2.so.0
|
||||
libx11 # libX11.so.6
|
||||
libxrandr # libXrandr.so.2
|
||||
libz # libz.so.1
|
||||
];
|
||||
|
||||
|
||||
@ -12,12 +12,12 @@ benchmark, resulttype, SUM(t.time2 - t.time1 + 1) AS faults,
|
||||
CONCAT('0x', HEX(p.injection_instr_absolute)) AS fault_address
|
||||
FROM variant v
|
||||
JOIN trace t ON v.id = t.variant_id
|
||||
JOIN fspgroup g ON g.variant_id = t.variant_id AND g.instr2 = t.instr2 AND g.data_address = t.data_address
|
||||
JOIN fspgroup g ON g.variant_id = t.variant_id AND g.instr2 = t.instr2 AND g.data_physical_address = t.data_physical_address
|
||||
JOIN result_GenericExperimentMessage r ON r.pilot_id = g.pilot_id
|
||||
JOIN fsppilot p ON r.pilot_id = p.id
|
||||
WHERE v.variant = '$experiment'
|
||||
GROUP BY benchmark, resulttype, p.injection_instr_absolute
|
||||
ORDER BY benchmark, resulttype, SUM(t.time2 - t.time1 + 1) DESC;"
|
||||
ORDER BY benchmark, resulttype, SUM(t.time2 - t.time1 + 1) DESC;";
|
||||
}
|
||||
|
||||
sub args { return "--batch --raw"; }
|
||||
|
||||
@ -11,7 +11,7 @@ sub query {
|
||||
benchmark, resulttype, sum(t.time2 - t.time1 + 1) AS faults
|
||||
FROM variant v
|
||||
JOIN trace t ON v.id = t.variant_id
|
||||
JOIN fspgroup g ON g.variant_id = t.variant_id AND g.instr2 = t.instr2 AND g.data_address = t.data_address
|
||||
JOIN fspgroup g ON g.variant_id = t.variant_id AND g.instr2 = t.instr2 AND g.data_physical_address = t.data_physical_address
|
||||
JOIN result_GenericExperimentMessage r ON r.pilot_id = g.pilot_id
|
||||
JOIN fsppilot p ON r.pilot_id = p.id
|
||||
WHERE v.variant = '$experiment'
|
||||
|
||||
@ -11,7 +11,7 @@ sub query {
|
||||
benchmark, resulttype, sum(t.time2 - t.time1 + 1) AS faults
|
||||
FROM variant v
|
||||
JOIN trace t ON v.id = t.variant_id
|
||||
JOIN fspgroup g ON g.variant_id = t.variant_id AND g.instr2 = t.instr2 AND g.data_address = t.data_address
|
||||
JOIN fspgroup g ON g.variant_id = t.variant_id AND g.instr2 = t.instr2 AND g.data_physical_address = t.data_physical_address
|
||||
JOIN result_GenericExperimentMessage r ON r.pilot_id = g.pilot_id
|
||||
JOIN fsppilot p ON r.pilot_id = p.id
|
||||
WHERE v.variant = '$experiment'
|
||||
|
||||
126
scripts/Util.pm
126
scripts/Util.pm
@ -8,6 +8,9 @@ use DateTime;
|
||||
|
||||
use feature 'say';
|
||||
|
||||
my $local_root = '/home/christoph/Notes/TU/MastersThesis/FailNix';
|
||||
my $local_archive_dir = "$local_root/injections";
|
||||
|
||||
my $ntfy_url = 'https://ntfy.vps.chriphost.de';
|
||||
my $ntfy_token = 'tk_rx8fd6hojuz4ekcb72j7juugkbmga'; # May be public
|
||||
my $ntfy_topic = 'fail-alerts';
|
||||
@ -139,4 +142,127 @@ sub execute_query {
|
||||
return $result;
|
||||
}
|
||||
|
||||
sub format_number_sep {
|
||||
my ($number) = @_;
|
||||
1 while $number =~ s/^(-?\d+)(\d{3})/$1.$2/;
|
||||
return $number;
|
||||
}
|
||||
|
||||
sub elf_read_sections {
|
||||
my ($elffile) = @_;
|
||||
|
||||
my $readelf_out = qx{readelf -S $elffile};
|
||||
my @lines = split "\n", $readelf_out;
|
||||
|
||||
my @sections;
|
||||
foreach my $line (@lines) {
|
||||
|
||||
# [ 1] .text PROGBITS 00100000 001000 0000f0 00 AX 0 0 4
|
||||
next
|
||||
unless $line =~
|
||||
/^\s*\[\s*\d+\]\s+(\..+?)\s+([A-Z]+)\s+([0-9a-f]+)\s+([0-9a-f]+)\s+([0-9a-f]+)\s+.*$/;
|
||||
|
||||
push @sections, {
|
||||
name => $1,
|
||||
type => $2,
|
||||
address => $3, # Memory location
|
||||
offset => $4, # File location
|
||||
size => $5,
|
||||
};
|
||||
}
|
||||
|
||||
return @sections;
|
||||
}
|
||||
|
||||
sub get_section_name {
|
||||
my ( $address, @sections ) = @_;
|
||||
|
||||
my $name;
|
||||
my $last_address = 0;
|
||||
foreach my $section (@sections) {
|
||||
my $cur_address = hex( $section->{address} );
|
||||
if ( hex($address) >= $cur_address && $cur_address > $last_address ) {
|
||||
$name = $section->{name};
|
||||
$last_address = $cur_address;
|
||||
}
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
sub read_experiment_info {
|
||||
my ($exp) = @_;
|
||||
|
||||
return unless ( -f "$local_archive_dir/$exp/0.info" );
|
||||
|
||||
open( my $fhandle, '<', "$local_archive_dir/$exp/0.info" )
|
||||
or die "Failed to open 0.info: $!";
|
||||
my $info = <$fhandle>;
|
||||
chomp $info if defined $info;
|
||||
close($fhandle);
|
||||
|
||||
return defined $info ? $info : "";
|
||||
}
|
||||
|
||||
sub read_marker_info {
|
||||
my ( $experiment, $benchmark, $address ) = @_;
|
||||
|
||||
return ""
|
||||
unless (
|
||||
-f "$local_archive_dir/$experiment/markers/$benchmark-$address.info" );
|
||||
|
||||
open( my $fhandle, '<',
|
||||
"$local_archive_dir/$experiment/markers/$benchmark-$address.info" )
|
||||
or die "Failed to open $benchmark-$address.info: $!";
|
||||
local $/;
|
||||
my $info = <$fhandle>;
|
||||
chomp $info;
|
||||
close($fhandle);
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
sub overwrite_marker_info {
|
||||
my ( $experiment, $benchmark, $address, $info ) = @_;
|
||||
|
||||
system( 'mkdir', '-p', "$local_archive_dir/$experiment/markers" );
|
||||
|
||||
open( my $fhandle, '>',
|
||||
"$local_archive_dir/$experiment/markers/$benchmark-$address.info" )
|
||||
or die "Failed to open $benchmark-$address.info: $!";
|
||||
print $fhandle $info;
|
||||
close($fhandle);
|
||||
}
|
||||
|
||||
sub delete_marker_info {
|
||||
my ( $experiment, $benchmark, $address ) = @_;
|
||||
|
||||
system( 'rm',
|
||||
"$local_archive_dir/$experiment/markers/$benchmark-$address.info" );
|
||||
}
|
||||
|
||||
sub select_experiment {
|
||||
my ($multi) = @_;
|
||||
|
||||
my @experiments = find_subdirs($local_archive_dir);
|
||||
|
||||
my @exp_with_notes;
|
||||
foreach my $exp (@experiments) {
|
||||
my $info = read_experiment_info($exp);
|
||||
|
||||
push @exp_with_notes,
|
||||
( defined $info && length($info) > 0 )
|
||||
? sprintf( "%-50s (%s)", $exp, $info )
|
||||
: $exp;
|
||||
}
|
||||
|
||||
my @selected_experiments =
|
||||
TUI::select_from_list( "Select Experiment", $multi, @exp_with_notes );
|
||||
die "No experiment selected" unless @selected_experiments;
|
||||
|
||||
map { s/(.*?)\s+\(.+\)$/$1/ } @selected_experiments;
|
||||
|
||||
return $multi == 1 ? @selected_experiments : $selected_experiments[0];
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@ -21,12 +21,7 @@ my $local_root = '/home/christoph/Notes/TU/MastersThesis/FailNix';
|
||||
my $local_archive_dir = "$local_root/injections";
|
||||
|
||||
# Select experiment to open
|
||||
my @experiments = Util::find_subdirs($local_archive_dir);
|
||||
my @selected_experiments =
|
||||
TUI::select_from_list( "Select Archived Experiment to Open", 0,
|
||||
@experiments );
|
||||
die "No experiment selected" unless @selected_experiments;
|
||||
my $selected_experiment = $selected_experiments[0];
|
||||
my $selected_experiment = Util::select_experiment(0);
|
||||
|
||||
my $cui = TUI::init_cui();
|
||||
|
||||
@ -75,7 +70,25 @@ my %index_of_markers;
|
||||
|
||||
my $selected_threshold = 0;
|
||||
|
||||
# TODO: Display the segment the addresses belong to
|
||||
my @sections;
|
||||
|
||||
sub marker_label {
|
||||
my ($marker) = @_;
|
||||
|
||||
return sprintf(
|
||||
"%4s %8s %5s %17s %12sx %-40s",
|
||||
$marker->{benchmark},
|
||||
$marker->{fault_address},
|
||||
Util::get_section_name( $marker->{fault_address}, @sections ),
|
||||
$marker->{resulttype},
|
||||
Util::format_number_sep( $marker->{faults} ),
|
||||
Util::read_marker_info(
|
||||
$selected_experiment, $marker->{benchmark},
|
||||
$marker->{fault_address}
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
sub load_faults_csv {
|
||||
@marker_values = ();
|
||||
%marker_labels = ();
|
||||
@ -86,11 +99,8 @@ sub load_faults_csv {
|
||||
headers => 'auto'
|
||||
);
|
||||
|
||||
sub format_number_sep {
|
||||
my ($number) = @_;
|
||||
1 while $number =~ s/^(-?\d+)(\d{3})/$1.$2/;
|
||||
return $number;
|
||||
}
|
||||
@sections = Util::elf_read_sections(
|
||||
"$local_archive_dir/$selected_experiment/system.elf");
|
||||
|
||||
# Result:
|
||||
# [ { benchmark => "ip", resulttype => "OK_MARKER",
|
||||
@ -99,13 +109,7 @@ sub load_faults_csv {
|
||||
@marker_values = @$data;
|
||||
@filtered_marker_values = @marker_values;
|
||||
%marker_labels =
|
||||
map {
|
||||
$_ => sprintf(
|
||||
"%5s %10s %20s %15sx",
|
||||
$_->{benchmark}, $_->{fault_address},
|
||||
$_->{resulttype}, format_number_sep( $_->{faults} ),
|
||||
);
|
||||
} @marker_values;
|
||||
map { $_ => marker_label($_); } @marker_values;
|
||||
}
|
||||
|
||||
sub filter_marker_values {
|
||||
@ -361,7 +365,7 @@ $win->add(
|
||||
'info', 'Label',
|
||||
-y => -1,
|
||||
-text =>
|
||||
"Space = toggle, F = filter markers, S = open source, A = open assembly, R = resize, Q = quit",
|
||||
"Space = toggle, F = filter markers, S = open source, A = open assembly, N = edit notes, R = resize, Q = quit",
|
||||
);
|
||||
|
||||
sub set_geometry {
|
||||
@ -379,8 +383,8 @@ sub layout_resize {
|
||||
my $w = $win->width();
|
||||
my $h = $win->height();
|
||||
|
||||
my $w1 = int( $w * 0.2 );
|
||||
my $w2 = int( $w * 0.4 );
|
||||
my $w1 = int( $w * 0.3 );
|
||||
my $w2 = int( $w * 0.3 );
|
||||
my $w3 = int( $w - $w1 - $w2 );
|
||||
|
||||
set_geometry( $left, 0, 1, $w1, $h - 2 );
|
||||
@ -466,6 +470,7 @@ sub markers_filter_popup {
|
||||
-title => "By Count Threshold",
|
||||
-border => 1,
|
||||
-text => $selected_threshold,
|
||||
-pos => length($selected_threshold),
|
||||
-regexp => '/^\d*$/',
|
||||
);
|
||||
|
||||
@ -534,6 +539,79 @@ sub markers_filter_popup {
|
||||
$focus->();
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# Notes Popup
|
||||
# =============================================================================
|
||||
|
||||
sub edit_notes_popup {
|
||||
my $w = 60;
|
||||
my $h = 24;
|
||||
|
||||
my $marker = $markers_panel->get_active_value();
|
||||
my $marker_text =
|
||||
Util::read_marker_info( $selected_experiment, $marker->{benchmark},
|
||||
$marker->{fault_address} );
|
||||
|
||||
my $popup = $cui->add(
|
||||
'popup', 'Window',
|
||||
-x => int( $cui->width() / 2 - $w / 2 ),
|
||||
-y => int( $cui->height() / 2 - $h / 2 ),
|
||||
-width => $w,
|
||||
-height => $h,
|
||||
-border => 1,
|
||||
-title => "Edit Notes",
|
||||
);
|
||||
|
||||
my $notes = $popup->add(
|
||||
'marker_notes',
|
||||
'TextEditor',
|
||||
-height => $h - 3,
|
||||
-border => 1,
|
||||
-text => $marker_text,
|
||||
-pos => length($marker_text),
|
||||
);
|
||||
|
||||
$popup->add(
|
||||
'popup_info', 'Label',
|
||||
-y => -1,
|
||||
-text => "^S/^C = save, ^Q = quit",
|
||||
);
|
||||
|
||||
$popup->set_binding(
|
||||
sub {
|
||||
my $text = $notes->get();
|
||||
|
||||
if ( length($text) > 0 ) {
|
||||
Util::overwrite_marker_info( $selected_experiment,
|
||||
$marker->{benchmark}, $marker->{fault_address}, $text, );
|
||||
}
|
||||
else {
|
||||
Util::delete_marker_info( $selected_experiment,
|
||||
$marker->{benchmark}, $marker->{fault_address} );
|
||||
}
|
||||
|
||||
$marker_labels{$marker} = marker_label($marker);
|
||||
|
||||
$cui->delete('popup');
|
||||
$cui->layout();
|
||||
$markers_panel->draw();
|
||||
},
|
||||
"\cS",
|
||||
"\cC",
|
||||
);
|
||||
|
||||
$popup->set_binding(
|
||||
sub {
|
||||
$cui->delete('popup');
|
||||
$cui->layout();
|
||||
},
|
||||
"\cQ"
|
||||
);
|
||||
|
||||
$cui->layout();
|
||||
$notes->focus();
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# Bindings
|
||||
# =============================================================================
|
||||
@ -545,6 +623,13 @@ $win->set_binding(
|
||||
'f',
|
||||
);
|
||||
|
||||
$win->set_binding(
|
||||
sub {
|
||||
edit_notes_popup();
|
||||
},
|
||||
'n',
|
||||
);
|
||||
|
||||
$win->set_binding(
|
||||
sub {
|
||||
layout_resize();
|
||||
|
||||
281
scripts/menu.pl
281
scripts/menu.pl
@ -41,6 +41,10 @@ my $resultbrowser = 'resultbrowser.py';
|
||||
my $remote_root = '/home/lab/smchurla/Documents/failnix';
|
||||
my $remote_builds_dir = "$remote_root/builds";
|
||||
|
||||
my $db_host = "127.0.0.1";
|
||||
my $db_port = "3306";
|
||||
my $db_user = "smchurla";
|
||||
|
||||
my %handlers = (
|
||||
'01. Build Experiments' => sub { do "$local_scripts_dir/build.pl"; },
|
||||
|
||||
@ -68,6 +72,9 @@ my %handlers = (
|
||||
Mars::download_dir( "$remote_builds_dir/$_",
|
||||
"$local_archive_dir/" . $_ =~ s/:/-/gr )
|
||||
for @selected_dirs;
|
||||
|
||||
system( 'touch', "$local_archive_dir/" . $_ =~ s/:/-/gr . "/0.info" )
|
||||
for @selected_dirs;
|
||||
},
|
||||
|
||||
'04. Query Databases (Mars)' => sub {
|
||||
@ -194,70 +201,9 @@ my %handlers = (
|
||||
'10. Open Experiment In Explorer' =>
|
||||
sub { do "$local_scripts_dir/explore.pl" },
|
||||
|
||||
'11. Open Experiment in Ghidra' => sub {
|
||||
'11. Compare Experiment Results' => sub {
|
||||
|
||||
my @projects =
|
||||
map { s/\.gpr//r } Util::find_files($local_ghidra_projects);
|
||||
my @selected_projects =
|
||||
TUI::select_from_list( "Select Project to Open in Ghidra",
|
||||
0, @projects );
|
||||
die "No project selected" unless @selected_projects;
|
||||
my $project = $selected_projects[0];
|
||||
system(
|
||||
join " ",
|
||||
(
|
||||
"_JAVA_AWT_WM_NONREPARENTING=1", "ghidra",
|
||||
"$local_ghidra_projects/$project.gpr",
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
'12. Open Experiment in Binsider' => sub {
|
||||
my @experiments = Util::find_subdirs($local_archive_dir);
|
||||
my @selected_experiments =
|
||||
TUI::select_from_list( "Select Experiments to Open in Binsider",
|
||||
0, @experiments );
|
||||
die "No experiment selected" unless @selected_experiments;
|
||||
my $selected_experiment = $selected_experiments[0];
|
||||
|
||||
system( 'binsider',
|
||||
"$local_archive_dir/$selected_experiment/system.elf" );
|
||||
},
|
||||
|
||||
'13. Open Experiment in ResultBrowser' => sub {
|
||||
|
||||
my @db_names = Mars::db_list();
|
||||
my @selected_dbs =
|
||||
TUI::select_from_list( "Select Database for ResultBrowser",
|
||||
0, @db_names );
|
||||
die "No database selected" unless @selected_dbs;
|
||||
my $selected_db = $selected_dbs[0];
|
||||
|
||||
Util::rewrite_file( $local_db_conf, "database=",
|
||||
"database=$selected_db\n" );
|
||||
|
||||
system( $resultbrowser, '-c', $local_db_conf, '--host=0.0.0.0',
|
||||
"--port=$resultbrowser_port" );
|
||||
},
|
||||
|
||||
'14. Compare Experiment Results' => sub {
|
||||
|
||||
# TODO: To util function (select_experiments,
|
||||
# could also include the file-existance filter)
|
||||
my @experiments = Util::find_subdirs($local_archive_dir);
|
||||
|
||||
# Only include experiments with resultsdata.csv
|
||||
my @viable_experiments;
|
||||
foreach my $experiment (@experiments) {
|
||||
push @viable_experiments, $experiment
|
||||
if ( -f "$local_archive_dir/$experiment/resultsdata.csv" );
|
||||
}
|
||||
|
||||
# Select experiments
|
||||
my @selected_experiments =
|
||||
TUI::select_from_list( "Select Experiments to Compare",
|
||||
1, @viable_experiments );
|
||||
die "No experiments selected" unless @selected_experiments;
|
||||
my @selected_experiments = Util::select_experiment(1);
|
||||
|
||||
# Read results
|
||||
my %all_results;
|
||||
@ -275,13 +221,6 @@ my %handlers = (
|
||||
}
|
||||
}
|
||||
|
||||
# TODO: To util function
|
||||
sub format_number_sep {
|
||||
my ($number) = @_;
|
||||
1 while $number =~ s/^(-?\d+)(\d{3})/$1.$2/;
|
||||
return $number;
|
||||
}
|
||||
|
||||
my @benchs = ( 'ip', 'mem', 'regs' );
|
||||
my @markers = (
|
||||
'OK_MARKER', 'FAIL_MARKER',
|
||||
@ -290,12 +229,15 @@ my %handlers = (
|
||||
'ACCESS_OUTERSPACE'
|
||||
);
|
||||
|
||||
my $heading = sprintf( "%5s %20s ", "BENCH", "TYPE" );
|
||||
my $heading = sprintf( "%5s %20s ", "BENCH", "TYPE" );
|
||||
my $subheading = sprintf( "%5s %20s ", "", "" );
|
||||
foreach my $experiment (@selected_experiments) {
|
||||
$heading .= sprintf( "%50s ", $experiment );
|
||||
$subheading .=
|
||||
sprintf( "%50s ", Util::read_experiment_info($experiment) );
|
||||
}
|
||||
|
||||
my @entries = ( $heading, "" );
|
||||
my @entries = ( $heading, $subheading, "" );
|
||||
foreach my $benchmark (@benchs) {
|
||||
foreach my $marker (@markers) {
|
||||
my $entry = sprintf( "%5s %20s ", $benchmark, $marker );
|
||||
@ -305,7 +247,7 @@ my %handlers = (
|
||||
{
|
||||
$entry .= sprintf(
|
||||
"%50s ",
|
||||
format_number_sep(
|
||||
Util::format_number_sep(
|
||||
$all_results{$experiment}{$benchmark}{$marker}
|
||||
)
|
||||
);
|
||||
@ -325,48 +267,129 @@ my %handlers = (
|
||||
0, @entries );
|
||||
},
|
||||
|
||||
'15. Plot Results' => sub {
|
||||
'12. Open Experiment in BinaryNinja' => sub {
|
||||
my @selected_experiments = Util::select_experiment(1);
|
||||
my @paths =
|
||||
map { "$local_archive_dir/$_/system.elf" } @selected_experiments;
|
||||
|
||||
# Generate R ggplot2 charts
|
||||
my @experiments = Util::find_subdirs($local_archive_dir);
|
||||
my @selected_experiments =
|
||||
TUI::select_from_list( "Select Experiments to Plot", 1,
|
||||
@experiments );
|
||||
die "No experiment selected" unless @selected_experiments;
|
||||
|
||||
my @charts = map { s/\.r//r } Util::find_files($local_charts_dir);
|
||||
my @selected_charts =
|
||||
TUI::select_from_list( "Select Plots to Generate", 1, @charts );
|
||||
die "No plot selected" unless @selected_charts;
|
||||
|
||||
my @single_charts = grep { /single/ } @selected_charts;
|
||||
foreach my $experiment (@selected_experiments) {
|
||||
foreach my $chart (@single_charts) {
|
||||
say " - Generating plot $chart for $experiment...";
|
||||
system(
|
||||
'Rscript',
|
||||
"$local_charts_dir/$chart.r",
|
||||
"$local_archive_dir/$experiment"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
my @combined_charts = grep { /combined/ } @selected_charts;
|
||||
my $print_experiments = join " ", @selected_experiments;
|
||||
my @path_experiments =
|
||||
map { "$local_archive_dir/$_" } @selected_experiments;
|
||||
foreach my $chart (@combined_charts) {
|
||||
say " - Generating plot $chart for ($print_experiments)...";
|
||||
system( 'Rscript', "$local_charts_dir/$chart.r",
|
||||
@path_experiments );
|
||||
}
|
||||
system( 'binaryninja', @paths );
|
||||
},
|
||||
|
||||
'16. Run Build in GDB' => sub {
|
||||
'13. Open Experiment in Binsider' => sub {
|
||||
my $selected_experiment = Util::select_experiment(0);
|
||||
|
||||
system( 'binsider',
|
||||
"$local_archive_dir/$selected_experiment/system.elf" );
|
||||
},
|
||||
|
||||
'14. Open Experiment in Ghidra' => sub {
|
||||
|
||||
my @projects =
|
||||
map { s/\.gpr//r } Util::find_files($local_ghidra_projects);
|
||||
my @selected_projects =
|
||||
TUI::select_from_list( "Select Project to Open in Ghidra",
|
||||
0, @projects );
|
||||
die "No project selected" unless @selected_projects;
|
||||
my $project = $selected_projects[0];
|
||||
system(
|
||||
join " ",
|
||||
(
|
||||
"_JAVA_AWT_WM_NONREPARENTING=1", "ghidra",
|
||||
"$local_ghidra_projects/$project.gpr",
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
'15. Run Objdump on Experiment' => sub {
|
||||
my $selected_experiment = Util::select_experiment(0);
|
||||
|
||||
system(
|
||||
"objdump $local_archive_dir/$selected_experiment/system.elf -D -M intel -S | bat --color never"
|
||||
);
|
||||
},
|
||||
|
||||
'16. Run Wasm-Objdump on Experiment' => sub {
|
||||
my $selected_experiment = Util::select_experiment(0);
|
||||
|
||||
system(
|
||||
"wasm-objdump -d $local_archive_dir/$selected_experiment/wasm_module.wasm | bat --color never"
|
||||
);
|
||||
},
|
||||
|
||||
'17. Run Radare2 on Experiment' => sub {
|
||||
my $selected_experiment = Util::select_experiment(0);
|
||||
|
||||
say "Radare help:";
|
||||
say "s <address> - Seek to address";
|
||||
say "pd <n> - Disassemble n instructions";
|
||||
say "pdf - Disassemble current function";
|
||||
say "pdf @ <function> - Disassemble function";
|
||||
say "pdr - Disassemble recursively";
|
||||
say "V - Switch view";
|
||||
say "p - Switch print mode";
|
||||
say "P - Switch layout";
|
||||
system(
|
||||
'radare2', '-AA',
|
||||
'-c', '"-s dbg.os_main"',
|
||||
'-e', 'scr.color=3',
|
||||
'-e', 'scr.scrollbar=0',
|
||||
'-e', 'scr.responsive=true',
|
||||
'-e', 'scr.interactive=true',
|
||||
'-e', 'scr.utf8=true',
|
||||
'-e', 'scr.utf8.curvy=true',
|
||||
'-e', 'asm.syntax=intel',
|
||||
'-e', 'asm.lines=false',
|
||||
'-e', 'asm.xrefs=true',
|
||||
'-e', 'asm.flags=true',
|
||||
'-e', 'asm.comments=true',
|
||||
'-e', 'asm.functions=true',
|
||||
'-e', 'asm.var=true',
|
||||
'-e', 'asm.cmt.right=true',
|
||||
'-e', 'asm.dwarf=true',
|
||||
'-e', 'asm.pseudo=false',
|
||||
'-e', 'asm.describe=false',
|
||||
'-e', 'bin.relocs.apply=true',
|
||||
"$local_archive_dir/$selected_experiment/system.elf",
|
||||
|
||||
);
|
||||
},
|
||||
|
||||
'18. Open Database in ResultBrowser (Mars)' => sub {
|
||||
|
||||
my @db_names = Mars::db_list();
|
||||
my @selected_dbs =
|
||||
TUI::select_from_list( "Select Database for ResultBrowser",
|
||||
0, @db_names );
|
||||
die "No database selected" unless @selected_dbs;
|
||||
my $selected_db = $selected_dbs[0];
|
||||
|
||||
Util::rewrite_file( $local_db_conf, "database=",
|
||||
"database=$selected_db\n" );
|
||||
|
||||
system( $resultbrowser, '-c', $local_db_conf, '--host=0.0.0.0',
|
||||
"--port=$resultbrowser_port" );
|
||||
},
|
||||
|
||||
'19. Open Database in LazySQL (Mars)' => sub {
|
||||
my $experiment =
|
||||
Util::select_experiment(0) =~ s/T(\d\d)-(\d\d)-(\d\d)/T$1:$2:$3/r;
|
||||
my $ssh = Mars::ssh_connect();
|
||||
my $db_password = Mars::read_db_password_file();
|
||||
|
||||
system( 'lazysql', '-read-only',
|
||||
"mariadb://$db_user:$db_password\@$db_host:$db_port/${db_user}_$experiment"
|
||||
);
|
||||
},
|
||||
|
||||
'20. Open TablePlus (Mars)' => sub {
|
||||
system('tableplus');
|
||||
},
|
||||
|
||||
'21. Run Build in GDB' => sub {
|
||||
my @builds = grep { /linux/ } Util::find_subdirs($local_builds_dir);
|
||||
my @selected_builds =
|
||||
TUI::select_from_list( "Select Build to Run in GDB", 0, @builds );
|
||||
die "No experiment selected" unless @selected_builds;
|
||||
die "No build selected" unless @selected_builds;
|
||||
my $selected_build = $selected_builds[0];
|
||||
|
||||
my $build_dir = "$local_builds_dir/$selected_build";
|
||||
@ -399,6 +422,39 @@ my %handlers = (
|
||||
);
|
||||
},
|
||||
|
||||
'30. Plot Results' => sub {
|
||||
|
||||
# Generate R ggplot2 charts
|
||||
my @selected_experiments = Util::select_experiment(1);
|
||||
|
||||
my @charts = map { s/\.r//r } Util::find_files($local_charts_dir);
|
||||
my @selected_charts =
|
||||
TUI::select_from_list( "Select Plots to Generate", 1, @charts );
|
||||
die "No plot selected" unless @selected_charts;
|
||||
|
||||
my @single_charts = grep { /single/ } @selected_charts;
|
||||
foreach my $experiment (@selected_experiments) {
|
||||
foreach my $chart (@single_charts) {
|
||||
say " - Generating plot $chart for $experiment...";
|
||||
system(
|
||||
'Rscript',
|
||||
"$local_charts_dir/$chart.r",
|
||||
"$local_archive_dir/$experiment"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
my @combined_charts = grep { /combined/ } @selected_charts;
|
||||
my $print_experiments = join " ", @selected_experiments;
|
||||
my @path_experiments =
|
||||
map { "$local_archive_dir/$_" } @selected_experiments;
|
||||
foreach my $chart (@combined_charts) {
|
||||
say " - Generating plot $chart for ($print_experiments)...";
|
||||
system( 'Rscript', "$local_charts_dir/$chart.r",
|
||||
@path_experiments );
|
||||
}
|
||||
},
|
||||
|
||||
'95. Delete Builds' => sub {
|
||||
|
||||
# Delete old build files
|
||||
@ -439,11 +495,8 @@ my %handlers = (
|
||||
'98. Delete Archived Experiments' => sub {
|
||||
|
||||
# Delete archived experiments
|
||||
my @experiments = Util::find_subdirs($local_archive_dir);
|
||||
my @selected_experiments =
|
||||
TUI::select_from_list( "Select Archived Experiments to Delete",
|
||||
1, @experiments );
|
||||
die "No experiment selected" unless @selected_experiments;
|
||||
my @selected_experiments = Util::select_experiment(1);
|
||||
|
||||
system( 'rm', '-rf', "$local_archive_dir/$_" )
|
||||
for @selected_experiments;
|
||||
},
|
||||
|
||||
@ -35,145 +35,156 @@ my $result_browser = "$fail_bin/resultbrowser.py";
|
||||
sub trace {
|
||||
my ($experiment) = @_;
|
||||
|
||||
Util::notify("Tracing $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"
|
||||
)
|
||||
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"
|
||||
);
|
||||
say "Trace command: $trace_command";
|
||||
|
||||
system($trace_command);
|
||||
}
|
||||
|
||||
sub import_trace {
|
||||
my ($experiment) = @_;
|
||||
|
||||
Util::notify("Importing $experiment trace...");
|
||||
# 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
|
||||
)
|
||||
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"
|
||||
);
|
||||
say "Import IP command: $import_ip_command";
|
||||
|
||||
system($import_ip_command);
|
||||
|
||||
# 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"
|
||||
)
|
||||
);
|
||||
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"
|
||||
);
|
||||
say "Import MEM command: $import_mem_command";
|
||||
|
||||
system($import_mem_command);
|
||||
|
||||
# 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
|
||||
)
|
||||
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"
|
||||
);
|
||||
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",
|
||||
)
|
||||
);
|
||||
# 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_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"
|
||||
)
|
||||
);
|
||||
my $prune_command = join " ",
|
||||
(
|
||||
"$fail_prune", "--database-option-file $remote_db_conf",
|
||||
"-v $experiment", "-b %%",
|
||||
"--overwrite", ">$remote_builds_dir/$experiment/2_prune.log"
|
||||
);
|
||||
say "Prune command: $prune_command";
|
||||
|
||||
system($prune_command);
|
||||
}
|
||||
|
||||
sub inject {
|
||||
@ -183,6 +194,43 @@ sub inject {
|
||||
|
||||
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"
|
||||
);
|
||||
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_builds_dir/$experiment/4_client.log"
|
||||
);
|
||||
say "Client command: $client_command";
|
||||
|
||||
say "Forking...";
|
||||
my $pid = fork();
|
||||
die "fork failed: $!" unless defined $pid;
|
||||
@ -190,52 +238,16 @@ sub inject {
|
||||
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: $!";
|
||||
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(
|
||||
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: $?";
|
||||
system($client_command) == 0 or die "client failed: $?";
|
||||
|
||||
say "Killing server with pid $pid...";
|
||||
kill 'TERM', $pid;
|
||||
|
||||
@ -15,7 +15,6 @@ WASI_CFLAGS := "\
|
||||
-Wl,--initial-memory=65536 \
|
||||
-Wl,--export=__heap_base \
|
||||
-Wl,--export=__data_end \
|
||||
-Wl,--allow-undefined \
|
||||
"
|
||||
CROSS_CFLAGS_NOWASM := "\
|
||||
-O0 \
|
||||
|
||||
@ -60,12 +60,17 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
// Those functions are defined in the host program
|
||||
void NOINLINE fail_start_trace(void); // Mark start of injection
|
||||
void NOINLINE fail_stop_trace(void); // Mark end of injection
|
||||
void NOINLINE fail_marker_positive(void); // Everything ok
|
||||
void NOINLINE fail_marker_detected(void); // Everything ok
|
||||
void NOINLINE fail_marker_negative(void); // Invalid code
|
||||
void NOINLINE print(const char *msg);
|
||||
void NOINLINE IMPORT("fail_start_trace")
|
||||
fail_start_trace(void); // Mark start of injection
|
||||
void NOINLINE IMPORT("fail_stop_trace")
|
||||
fail_stop_trace(void); // Mark end of injection
|
||||
void NOINLINE IMPORT("fail_marker_positive")
|
||||
fail_marker_positive(void); // Everything ok
|
||||
void NOINLINE IMPORT("fail_marker_detected")
|
||||
fail_marker_detected(void); // Everything ok
|
||||
void NOINLINE IMPORT("fail_marker_negative")
|
||||
fail_marker_negative(void); // Invalid code
|
||||
void NOINLINE IMPORT("print") print(const char *msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
63
targets/wasm-module/matrix0_base.cpp
Normal file
63
targets/wasm-module/matrix0_base.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#include "../lib.h"
|
||||
|
||||
#define REPLICA_COUNT 1
|
||||
#define MAT_SIZE 3
|
||||
|
||||
static uint32_t X[MAT_SIZE * MAT_SIZE] = {
|
||||
0, 1, 2, //
|
||||
3, 4, 5, //
|
||||
6, 7, 8 //
|
||||
};
|
||||
static uint32_t Y[MAT_SIZE * MAT_SIZE] = {
|
||||
8, 7, 6, //
|
||||
5, 4, 3, //
|
||||
2, 1, 0 //
|
||||
};
|
||||
static uint32_t Calculated[MAT_SIZE * MAT_SIZE] = {0};
|
||||
|
||||
static INLINE uint32_t *idx(uint32_t *matrix, uint8_t x, uint8_t y) {
|
||||
return &matrix[y * MAT_SIZE + x];
|
||||
}
|
||||
|
||||
template <const unsigned int N> static INLINE void matrix(void) {
|
||||
for (uint8_t y = 0; y < MAT_SIZE; ++y) {
|
||||
for (uint8_t x = 0; x < MAT_SIZE; ++x) {
|
||||
for (uint8_t k = 0; k < MAT_SIZE; ++k) {
|
||||
*idx(Calculated, x, y) += (*idx(X, k, y)) * (*idx(Y, x, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int cmp(uint32_t *A, uint32_t *B) {
|
||||
for (uint8_t i = 0; i < MAT_SIZE * MAT_SIZE; ++i) {
|
||||
if (A[i] != B[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern "C" EXPORT("wasm_module") int wasm_module(void) {
|
||||
fail_start_trace();
|
||||
|
||||
matrix<0>();
|
||||
|
||||
fail_stop_trace();
|
||||
|
||||
uint32_t Expected[MAT_SIZE * MAT_SIZE] = {
|
||||
9, 6, 3, //
|
||||
54, 42, 30, //
|
||||
99, 78, 57 //
|
||||
};
|
||||
|
||||
if (cmp(Calculated, Expected)) {
|
||||
HOST_PRINT("result correct.\n");
|
||||
fail_marker_positive();
|
||||
return 0;
|
||||
} else {
|
||||
HOST_PRINT("result incorrect.\n");
|
||||
fail_marker_negative();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user