js/src/devtools/rootAnalysis/run_complete

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rwxr-xr-x

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 #!/usr/bin/perl
     3 # Sixgill: Static assertion checker for C/C++ programs.
     4 # Copyright (C) 2009-2010  Stanford University
     5 # Author: Brian Hackett
     6 #
     7 # This program is free software: you can redistribute it and/or modify
     8 # it under the terms of the GNU General Public License as published by
     9 # the Free Software Foundation, either version 3 of the License, or
    10 # (at your option) any later version.
    11 #
    12 # This program is distributed in the hope that it will be useful,
    13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15 # GNU General Public License for more details.
    16 #
    17 # You should have received a copy of the GNU General Public License
    18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
    20 # do a complete run of the system from raw source to reports. this requires
    21 # various run_monitor processes to be running in the background (maybe on other
    22 # machines) and watching a shared poll_file for jobs. if the output directory
    23 # for this script already exists then an incremental analysis will be performed
    24 # and the reports will only reflect the changes since the earlier run.
    26 use strict;
    27 use warnings;
    28 use IO::Handle;
    29 use File::Basename qw(dirname);
    30 use Getopt::Long;
    31 use Cwd;
    33 #################################
    34 # environment specific settings #
    35 #################################
    37 my $WORKDIR;
    38 my $SIXGILL_BIN;
    40 # poll file shared with the run_monitor script.
    41 my $poll_file;
    43 # root directory of the project.
    44 my $build_dir;
    46 # directory containing gcc wrapper scripts.
    47 my $wrap_dir;
    49 # optional file with annotations from the web interface.
    50 my $ann_file = "";
    52 # optional output directory to do a diff against.
    53 my $old_dir = "";
    55 # run in the foreground
    56 my $foreground;
    58 my $builder = "make -j4";
    60 my $suppress_logs;
    61 GetOptions("build-root|b=s" => \$build_dir,
    62            "poll-file=s" => \$poll_file,
    63            "no-logs!" => \$suppress_logs,
    64            "work-dir=s" => \$WORKDIR,
    65            "sixgill-binaries|binaries|b=s" => \$SIXGILL_BIN,
    66            "wrap-dir=s" => \$wrap_dir,
    67            "annotations-file|annotations|a=s" => \$ann_file,
    68            "old-dir|old=s" => \$old_dir,
    69            "foreground!" => \$foreground,
    70            "buildcommand=s" => \$builder,
    71            )
    72     or die;
    74 if (not -d $build_dir) {
    75     mkdir($build_dir);
    76 }
    77 if ($old_dir ne "" && not -d $old_dir) {
    78     die "Old directory '$old_dir' does not exist\n";
    79 }
    81 $WORKDIR ||= "sixgill-work";
    82 mkdir($WORKDIR, 0755) if ! -d $WORKDIR;
    83 $poll_file ||= "$WORKDIR/poll.file";
    84 $build_dir ||= "$WORKDIR/js-inbound-xgill";
    86 if (!defined $SIXGILL_BIN) {
    87     chomp(my $path = `which xmanager`);
    88     if ($path) {
    89         use File::Basename qw(dirname);
    90         $SIXGILL_BIN = dirname($path);
    91     } else {
    92         die "Cannot find sixgill binaries. Use the -b option.";
    93     }
    94 }
    96 $wrap_dir ||= "$WORKDIR/xgill-inbound/wrap_gcc";
    97 $wrap_dir = "$SIXGILL_BIN/../scripts/wrap_gcc" if not (-e "$wrap_dir/basecc");
    98 die "Bad wrapper directory: $wrap_dir" if not (-e "$wrap_dir/basecc");
   100 # code to clean the project from $build_dir.
   101 sub clean_project {
   102     system("make clean");
   103 }
   105 # code to build the project from $build_dir.
   106 sub build_project {
   107     return system($builder) >> 8;
   108 }
   110 our %kill_on_exit;
   111 END {
   112     for my $pid (keys %kill_on_exit) {
   113         kill($pid);
   114     }
   115 }
   117 # commands to start the various xgill binaries. timeouts can be specified
   118 # for the backend analyses here, and a memory limit can be specified for
   119 # xmanager if desired (and USE_COUNT_ALLOCATOR is defined in util/alloc.h).
   120 my $xmanager = "$SIXGILL_BIN/xmanager";
   121 my $xsource = "$SIXGILL_BIN/xsource";
   122 my $xmemlocal = "$SIXGILL_BIN/xmemlocal -timeout=20";
   123 my $xinfer = "$SIXGILL_BIN/xinfer -timeout=60";
   124 my $xcheck = "$SIXGILL_BIN/xcheck -timeout=30";
   126 # prefix directory to strip off source files.
   127 my $prefix_dir = $build_dir;
   129 ##########################
   130 # general purpose script #
   131 ##########################
   133 # Prevent ccache from being used. I don't think this does any good. The problem
   134 # I'm struggling with is that if autoconf.mk still has 'ccache gcc' in it, the
   135 # builds fail in a mysterious way.
   136 $ENV{CCACHE_COMPILERCHECK} = 'date +%s.%N';
   137 delete $ENV{CCACHE_PREFIX};
   139 my $usage = "USAGE: run_complete result-dir\n";
   140 my $result_dir = shift or die $usage;
   142 if (not $foreground) {
   143     my $pid = fork();
   144     if ($pid != 0) {
   145         print "Forked, exiting...\n";
   146         exit(0);
   147     }
   148 }
   150 # if the result directory does not already exist, mark for a clean build.
   151 my $do_clean = 0;
   152 if (not (-d $result_dir)) {
   153     $do_clean = 1;
   154     mkdir $result_dir;
   155 }
   157 if (!$suppress_logs) {
   158     my $log_file = "$result_dir/complete.log";
   159     open(OUT, ">>", $log_file) or die "append to $log_file: $!";
   160     OUT->autoflush(1);  # don't buffer writes to the main log.
   162     # redirect stdout and stderr to the log.
   163     STDOUT->fdopen(\*OUT, "w");
   164     STDERR->fdopen(\*OUT, "w");
   165 }
   167 # pids to wait on before exiting. these are collating worker output.
   168 my @waitpids;
   170 chdir $result_dir;
   172 # to do a partial run, comment out the commands here you don't want to do.
   174 my $status = run_build();
   176 # end of run commands.
   178 for my $pid (@waitpids) {
   179     waitpid($pid, 0);
   180     $status ||= $? >> 8;
   181 }
   183 print "Exiting run_complete with status $status\n";
   184 exit $status;
   186 # get the IP address which a freshly created manager is listening on.
   187 sub get_manager_address
   188 {
   189     my $log_file = shift or die;
   191     # give the manager one second to start, any longer and something's broken.
   192     sleep(1);
   194     my $log_data = `cat $log_file`;
   195     my ($port) = $log_data =~ /Listening on ([\.\:0-9]*)/
   196       or die "no manager found";
   197     print OUT "Connecting to manager on port $port\n" unless $suppress_logs;
   198     print "Connecting to manager on port $port.\n";
   199     return $1;
   200 }
   202 sub run_build
   203 {
   204     print "build started: ";
   205     print scalar(localtime());
   206     print "\n";
   208     # fork off a process to run the build.
   209     defined(my $pid = fork) or die;
   211     # log file for the manager.
   212     my $manager_log_file = "$result_dir/build_manager.log";
   214     if (!$pid) {
   215         # this is the child process, fork another process to run a manager.
   216         defined(my $pid = fork) or die;
   217         exec("$xmanager -terminate-on-assert > $manager_log_file 2>&1") if (!$pid);
   218         $kill_on_exit{$pid} = 1;
   220         if (!$suppress_logs) {
   221             # open new streams to redirect stdout and stderr.
   222             open(LOGOUT, "> $result_dir/build.log");
   223             open(LOGERR, "> $result_dir/build_err.log");
   224             STDOUT->fdopen(\*LOGOUT, "w");
   225             STDERR->fdopen(\*LOGERR, "w");
   226         }
   228         my $address = get_manager_address($manager_log_file);
   230         # write the configuration file for the wrapper script.
   231         my $config_file = "$WORKDIR/xgill.config";
   232         open(CONFIG, ">", $config_file) or die "create $config_file: $!";
   233         print CONFIG "$prefix_dir\n";
   234         print CONFIG Cwd::abs_path("$result_dir/build_xgill.log")."\n";
   235         print CONFIG "$address\n";
   236         my @extra = ("-fplugin-arg-xgill-mangle=1");
   237         push(@extra, "-fplugin-arg-xgill-annfile=$ann_file")
   238             if ($ann_file ne "" && -e $ann_file);
   239         print CONFIG join(" ", @extra) . "\n";
   240         close(CONFIG);
   242 	# Tell the wrapper where to find the config
   243 	$ENV{"XGILL_CONFIG"} = Cwd::abs_path($config_file);
   245         # update the PATH so that the build will see the wrappers.
   246         $ENV{"PATH"} = "$wrap_dir:" . $ENV{"PATH"};
   248         # do the build, cleaning if necessary.
   249         chdir $build_dir;
   250         clean_project() if ($do_clean);
   251         my $exit_status = build_project();
   253         # signal the manager that it's over.
   254         system("$xsource -remote=$address -end-manager");
   256         # wait for the manager to clean up and terminate.
   257         print "Waiting for manager to finish (build status $exit_status)...\n";
   258         waitpid($pid, 0);
   259         my $manager_status = $?;
   260         delete $kill_on_exit{$pid};
   262         # build is finished, the complete run can resume.
   263         # return value only useful if --foreground
   264         print "Exiting with status " . ($manager_status || $exit_status) . "\n";
   265         exit($manager_status || $exit_status);
   266     }
   268     # this is the complete process, wait for the build to finish.
   269     waitpid($pid, 0);
   270     my $status = $? >> 8;
   271     print "build finished (status $status): ";
   272     print scalar(localtime());
   273     print "\n";
   275     return $status;
   276 }
   278 sub run_pass
   279 {
   280     my ($name, $command) = @_;
   281     my $log_file = "$result_dir/manager.$name.log";
   283     # extra commands to pass to the manager.
   284     my $manager_extra = "";
   285     $manager_extra .= "-modset-wait=10" if ($name eq "xmemlocal");
   287     # fork off a manager process for the analysis.
   288     defined(my $pid = fork) or die;
   289     exec("$xmanager $manager_extra > $log_file 2>&1") if (!$pid);
   291     my $address = get_manager_address($log_file);
   293     # write the poll file for this pass.
   294     if (! -d dirname($poll_file)) {
   295         system("mkdir", "-p", dirname($poll_file));
   296     }
   297     open(POLL, "> $poll_file");
   298     print POLL "$command\n";
   299     print POLL "$result_dir/$name\n";
   300     print POLL "$address\n";
   301     close(POLL);
   303     print "$name started: ";
   304     print scalar(localtime());
   305     print "\n";
   307     waitpid($pid, 0);
   308     unlink($poll_file);
   310     print "$name finished: ";
   311     print scalar(localtime());
   312     print "\n";
   314     # collate the worker's output into a single file. make this asynchronous
   315     # so we can wait a bit and make sure we get all worker output.
   316     defined($pid = fork) or die;
   318     if (!$pid) {
   319         sleep(20);
   320         exec("cat $name.*.log > $name.log");
   321     }
   323     push(@waitpids, $pid);
   324 }
   326 # the names of all directories containing reports to archive.
   327 my $indexes;
   329 sub run_index
   330 {
   331     my ($name, $kind) = @_;
   333     return if (not (-e "report_$kind.xdb"));
   335     print "$name started: ";
   336     print scalar(localtime());
   337     print "\n";
   339     # make an index for the report diff if applicable.
   340     if ($old_dir ne "") {
   341         system("make_index $kind $old_dir > $name.diff.log");
   342         system("mv $kind diff_$kind");
   343         $indexes .= " diff_$kind";
   344     }
   346     # make an index for the full set of reports.
   347     system("make_index $kind > $name.log");
   348     $indexes .= " $kind";
   350     print "$name finished: ";
   351     print scalar(localtime());
   352     print "\n";
   353 }
   355 sub archive_indexes
   356 {
   357     print "archive started: ";
   358     print scalar(localtime());
   359     print "\n";
   361     system("tar -czf reports.tgz $indexes");
   362     system("rm -rf $indexes");
   364     print "archive finished: ";
   365     print scalar(localtime());
   366     print "\n";
   367 }

mercurial