| # ********************************************************** |
| # Copyright (c) 2006 VMware, Inc. All rights reserved. |
| # ********************************************************** |
| |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions are met: |
| # |
| # * Redistributions of source code must retain the above copyright notice, |
| # this list of conditions and the following disclaimer. |
| # |
| # * Redistributions in binary form must reproduce the above copyright notice, |
| # this list of conditions and the following disclaimer in the documentation |
| # and/or other materials provided with the distribution. |
| # |
| # * Neither the name of VMware, Inc. nor the names of its contributors may be |
| # used to endorse or promote products derived from this software without |
| # specific prior written permission. |
| # |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| # ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE |
| # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
| # DAMAGE. |
| |
| # measure_options.pl |
| # |
| # NOTE: ASSUMES drview, drcontrol, svccntrl and perl are in path |
| # NOTE: ASSUMES c:\desktop-nightly\boot_data_scripts and |
| # c:\desktop-nightly\boot_data exist #TODO do a mkdir |
| # NOTE: ASSUMES this script is in c:\desktop-nightly\boot_data_scripts #XXX |
| # |
| # NOTE: USES: BOOTNUM_FILE, uptime.vbs |
| # |
| # NOTE: Set up BOOTNUM_FILE (see below) to 0 (when done it will set it up to |
| # 0 and should be ready to use, but if runs were interrupted you'd |
| # need to do this manually) |
| # |
| # NOTE: Appends options specified in @dropts to current options provided by |
| # nodemgr |
| # |
| # To run: |
| # 1. Just write 0 to BOOTNUM_FILE |
| # 2. Setup @dropts array with option to be run |
| # 3. Setup $RESULTS_DIR and $SUMMARY_FILE to your liking |
| # 4. run the script: perl measure_options.pl |
| # or |
| # call it from a batch file |
| # [NOTE: put batch file in Programs->Startup to run at reboot/login] |
| # |
| |
| use strict; |
| use Getopt::Long; |
| |
| my $PROG = "measure_options.pl"; # TODO: use cwd? basename etc. |
| |
| # calculate boot time and log it |
| # |
| # disable/enable node manager |
| # |
| # run drtop every boot every 30s |
| # sum all cols from -showmem o/p |
| # if cpu utilization hits <= 2% |
| # write all sums to log file |
| # |
| # for each boot do |
| # set up registry keys for each app with |
| # appropriate options for this run |
| # do the run |
| # |
| # different runs |
| # reset from 1 to nth thread |
| # set -hotp_nudge_is_reset |
| # -C |
| # -E |
| # -F |
| # shared bbs |
| # shared traces |
| # private traces with diff cache sizes |
| # different set of services loaded |
| # default set |
| # medium set |
| # all set |
| # |
| # move all logfiles to \\fileserver\g_shares\desktop_nightly\results |
| # |
| # enable node manager |
| # some other script installs latest core |
| |
| my $ROOT = qq(C:\\desktop-nightly); |
| my $SCRIPTDIR = qq($ROOT\\boot_data_scripts); |
| my $OUTDIR = qq($ROOT\\boot_data); |
| |
| # get the boot time before doing anything else |
| my ($boot_time, @ignore) = grep s/uptime in seconds: //i, |
| `cscript -nologo $SCRIPTDIR\\uptime.vbs`; |
| |
| my %opt; |
| &GetOptions(\%opt, |
| "debug", |
| "default", |
| "help", |
| "usage", |
| ); |
| #TODO: print usage, verify options |
| |
| my $DRVER = &get_build(); |
| |
| system("net use m: \\\\10.1.5.85\\g_shares\\desktop-benchmarks \"\" /USER:guest") unless (-e "m:"); |
| |
| my $date = &datestamp(); |
| my $RESULTS_DIR = qq(m:\\results\\boot_data\\qatest_$DRVER).qq(_mem_$date); |
| mkdir $RESULTS_DIR unless -e $RESULTS_DIR; |
| |
| my $SUMMARY_FILE = qq(qatest_$DRVER).qq(_mem_$date.txt); |
| |
| # List of options for each run. |
| # Just enable/put the options you want run here. |
| my @dropts = ( |
| "", # dont change this, let this be boot 0 |
| |
| # "", # default |
| # "", # default |
| # "", # default |
| # "-no_enable_reset", |
| # "-no_enable_reset", |
| # "-no_enable_reset", |
| # "-hotp_nudge_is_reset", |
| # "-hotp_nudge_is_reset", |
| # "-hotp_nudge_is_reset", |
| # "-C -hotp_nudge_is_reset", |
| # "-C -hotp_nudge_is_reset", |
| # "-C -hotp_nudge_is_reset", |
| # "-E -hotp_nudge_is_reset", |
| # "-E -hotp_nudge_is_reset", |
| # "-E -hotp_nudge_is_reset", |
| # "-F -hotp_nudge_is_reset", |
| # "-F -hotp_nudge_is_reset", |
| # "-F -hotp_nudge_is_reset", |
| # "-C -E -F -hotp_nudge_is_reset", |
| # "-C -E -F -hotp_nudge_is_reset", |
| # "-C -E -F -hotp_nudge_is_reset", |
| # -reset_at_nth_thread is added to this list in a loop (see below) |
| |
| # # see memory impact of two new features I added: |
| # "-no_remove_shared_trace_heads", |
| # "-remove_trace_components", |
| # |
| # # shared ibt tables experimental |
| # "-shared_ibt_tables", |
| # |
| # # shared bbs, no traces |
| # "-shared_bbs_only", |
| # "-shared_bbs_only", |
| # "-shared_bbs_only", |
| # |
| # # shared bbs, private traces |
| # "-no_shared_traces", |
| # "-no_shared_traces -cache_trace_regen 20", |
| # "-no_shared_traces -cache_trace_regen 30", |
| # "-no_shared_traces -cache_trace_regen 40", |
| # "-no_shared_traces -no_finite_trace_cache", |
| # |
| # # private bbs, no traces |
| # "-disable_traces -no_shared_bbs", |
| # "-disable_traces -no_shared_bbs -cache_bb_regen 20", |
| # "-disable_traces -no_shared_bbs -cache_bb_regen 30", |
| # "-disable_traces -no_shared_bbs -cache_bb_regen 40", |
| # "-disable_traces -no_shared_bbs -no_finite_bb_cache", |
| # |
| # # private bbs, shared traces |
| # "-no_shared_bbs", |
| # "-no_shared_bbs -cache_bb_regen 20", |
| # "-no_shared_bbs -cache_bb_regen 30", |
| # "-no_shared_bbs -cache_bb_regen 40", |
| # "-no_shared_bbs -no_finite_bb_cache", |
| # |
| # # all private |
| # # bb regen 10 (default), vary trace regen 10,20,30,40,infinite |
| # "-no_shared_traces -no_shared_bbs", |
| # "-no_shared_traces -no_shared_bbs -cache_trace_regen 20", |
| # "-no_shared_traces -no_shared_bbs -cache_trace_regen 30", |
| # "-no_shared_traces -no_shared_bbs -cache_trace_regen 40", |
| # "-no_shared_traces -no_shared_bbs -no_finite_trace_cache", |
| # # bb regen 20, vary trace regen 10,20,30,40,infinite |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 20", |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 20 -cache_trace_regen 20", |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 20 -cache_trace_regen 30", |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 20 -cache_trace_regen 40", |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 20 -no_finite_trace_cache", |
| # # bb regen 30, vary trace regen 10,20,30,40,infinite |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 30", |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 30 -cache_trace_regen 20", |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 30 -cache_trace_regen 30", |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 30 -cache_trace_regen 40l", |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 30 -no_finite_trace_cache", |
| # # bb regen 40, vary trace regen 10,20,30,40,infinite |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 40", |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 40 -cache_trace_regen 20", |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 40 -cache_trace_regen 30", |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 40 -cache_trace_regen 40", |
| # "-no_shared_traces -no_shared_bbs -cache_bb_regen 40 -no_finite_trace_cache", |
| # # bb infinite, vary trace regen 10,20,30,40,infinite |
| # "-no_shared_traces -no_shared_bbs -no_finite_bb_cache", |
| # "-no_shared_traces -no_shared_bbs -no_finite_bb_cache -cache_trace_regen 20", |
| # "-no_shared_traces -no_shared_bbs -no_finite_bb_cache -cache_trace_regen 30", |
| # "-no_shared_traces -no_shared_bbs -no_finite_bb_cache -cache_trace_regen 40", |
| # "-no_shared_traces -no_shared_bbs -no_finite_bb_cache -no_finite_trace_cache", |
| |
| ); |
| |
| # enable to run reset_at_nth_thread 1..20 |
| #for (my $thr = 1; $thr < 21; $thr++) { |
| # push @dropts, "reset_at_nth_thread $thr"; |
| #} |
| |
| |
| # run with just the default set of options |
| @dropts = ( "" ) if defined $opt{'default'}; |
| |
| # file to save registry settings |
| my $SAVE_CFG = qq($SCRIPTDIR\\qatest_determina_keys.cfg); |
| |
| # file that holds the boot number |
| my $BOOTNUM_FILE = qq($SCRIPTDIR\\bootnum); |
| my $bootnum = &get_bootnum(); |
| print "$PROG: Boot number: $bootnum\n"; |
| |
| # at each boot, pick a set of options to run with |
| |
| &disable_node_manager(); |
| |
| # writes 0 to BOOTNUM_FILE |
| &cleanup_and_exit() if ($bootnum >= scalar @dropts); |
| |
| print "$PROG: running options: $dropts[$bootnum+1]\n"; |
| |
| # save the registry settings the first time |
| system("drcontrol -save $SAVE_CFG") if ($bootnum == 0); |
| system("drcontrol -dump > $RESULTS_DIR\\drcontrol-dump.$bootnum"); |
| |
| my $MEASURE_MEM_CMD = qq($SCRIPTDIR\\measure_mem.pl -tillidle --name "$DRVER-$bootnum" --nightly $RESULTS_DIR --summary $SUMMARY_FILE --b $boot_time); |
| |
| print "$PROG: $MEASURE_MEM_CMD\n"; |
| system("perl $MEASURE_MEM_CMD"); |
| |
| &do_hotp_nudge() if ($dropts[$bootnum] =~ m/hotp_nudge_is_reset/i); |
| |
| # now set up registry keys for next measurement |
| # restore the registry settings for our agent |
| system("drcontrol -detachall"); |
| system("drcontrol -load $SAVE_CFG"); |
| &resetreg($dropts[$bootnum+1]); |
| |
| print "$PROG: rebooting..\n"; |
| |
| reboot($bootnum); |
| |
| |
| |
| #----------------------------------------------------------------------------- |
| |
| sub resetreg { |
| my $append_dropt = shift; |
| |
| #TODO: use %PROGRAM FILES% ? |
| my $DETERMINA = qq("$ENV{'PROGRAMFILES'}\\Determina\\Determina Agent"); |
| my $DRHOME = $DETERMINA; |
| #my $DRHOME = qq("C:\\Program Files\\Determina\\Determina Agent"); |
| my $LIBDIR = "lib"; |
| my $LOGDIR = "logs"; |
| |
| my $prev_dropt = ""; |
| my $dropt = ""; |
| |
| my @ignore; |
| |
| # disable node manager if needed |
| &disable_node_manager() unless |
| scalar grep m/scnodemgr.*disabled/i, `svccntrl scnodemgr -show`; |
| |
| my $drdll = qq($DRHOME\\$LIBDIR\\$DRVER\\dynamorio.dll); |
| |
| # may as well set global key though we're setting every app key below |
| system("drcontrol -drlib $drdll"); |
| system("drcontrol -logdir $DRHOME\\$LOGDIR"); |
| |
| ($prev_dropt, @ignore) = |
| grep s/\s*DYNAMORIO_OPTIONS=\s*//, `drcontrol -dump`; |
| chomp($prev_dropt); |
| print "$PROG: global dropt: $prev_dropt\n"; |
| |
| $dropt = qq("$prev_dropt $append_dropt"); |
| system("drcontrol -options $dropt"); |
| |
| # drcontrol -load not implemented, and no way to remove a string value, |
| # so our only options are to reproduce the slist parsing and get the |
| # right rununder values, or set the values we want for each app, which |
| # is a pain to edit manually later but oh well: |
| my @apps = grep s/\s*Config\s*Group\s*: \s*//, `drcontrol -dump`; |
| my $app; |
| foreach $app (@apps) { |
| system("drcontrol -app $app -drlib $drdll"); |
| system("drcontrol -app $app -logdir $DRHOME\\$LOGDIR"); |
| ($prev_dropt, @ignore) = |
| grep s/\s*DYNAMORIO_OPTIONS=\s*//, `drcontrol -appdump $app`; |
| next unless $prev_dropt; |
| chomp($prev_dropt); |
| $dropt = qq("$prev_dropt $append_dropt"); |
| system("drcontrol -app $app -options $dropt"); |
| } |
| |
| ### if ignore RUNUNDER this will re-make reg keys from scc file: |
| ### # now re-build reg setup |
| ### drcontrol -reset; |
| ### for i in `grep -i exe /c/Program\ Files/Determina/SecureCore/config/default.scc`; do |
| ### # pull exe name out of [HKEY_LOCAL_MACHINE\<...>\inetinfo.exe] |
| ### j=${i##*\\}; |
| ### drcontrol -add ${j/]/}; |
| ### done; |
| system("drcontrol -preinject ON"); |
| } |
| |
| sub do_hotp_nudge { |
| # should be idle now, so nudge |
| system("drcontrol -hot_patch_nudge_all"); |
| # sleep for 10 more minutes to see what happens to memory |
| sleep 600; |
| } |
| |
| sub cleanup_and_exit { |
| # clean up after all runs |
| system("drcontrol -load $SAVE_CFG"); |
| system("echo 0 > $BOOTNUM_FILE"); |
| |
| &enable_node_manager(); |
| |
| exit 0; |
| } |
| |
| sub disable_node_manager { |
| #TODO: manual is fine or do we need to disable |
| system("svccntrl scnodemgr -disabled"); |
| system("net stop scnodemgr"); |
| } |
| |
| sub enable_node_manager { |
| system("svccntrl scnodemgr -auto"); |
| system("net start scnodemgr"); |
| } |
| |
| sub get_bootnum { |
| open FD, "<$BOOTNUM_FILE" or die "Cannot open $BOOTNUM_FILE: $!"; |
| chomp(my $num = <FD>); |
| close FD; |
| return $num; |
| } |
| |
| sub reboot { |
| my $bootnum = shift; |
| $bootnum++; |
| system("echo $bootnum > $BOOTNUM_FILE"); |
| system("shutdown -r -t 0 -f"); |
| } |
| |
| |
| #-------------------------------------------------------------------------- |
| sub get_build() { |
| my @dump = `drcontrol -dump 2> $OUTDIR\\drcontrol_err.txt`; |
| |
| # drcontrol -dump prints |
| # error message, if core is not installed |
| # data for SC config, if disabled from DMC |
| # if we have any app instrumented, then we care about under DR |
| my ($ignore_sc, $build, @ignore_rest) = |
| grep s/DYNAMORIO_AUTOINJECT.*Agent.lib.//i, @dump; |
| |
| chomp($build); |
| |
| $build = "native" unless ($build); |
| $build =~ s/\s*([0-9]+[a-z]).dynamorio.dll/$1/i; |
| |
| return $build; |
| } |
| |
| sub datestamp() { |
| # ignore wday - day of the week, $yday - day of the year, and |
| # $is_dst - is daylight savings time |
| my ($sec, $min, $hour, |
| $mday, $mon, $year, |
| $wday, $yday, $is_dst) = localtime(time); |
| |
| # last 2 digits of year |
| $year = ($year + 1900) % 100; |
| my $stamp = sprintf("%02d%02d%02d", |
| $year,$mon+1,$mday); |
| return $stamp; |
| } |