From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2041) id 71CBD38582AE; Wed, 29 Nov 2023 18:45:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 71CBD38582AE Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Vladimir Mezentsev To: bfd-cvs@sourceware.org, gdb-cvs@sourceware.org Subject: [binutils-gdb] gprofng: support GNU option syntax in gp-display-html, plus various fixes X-Act-Checkin: binutils-gdb X-Git-Author: Vladimir Mezentsev X-Git-Refname: refs/heads/master X-Git-Oldrev: 46c5675798276f880ae62d5cff58ce19d4c855c9 X-Git-Newrev: a0dc1f9a12a4394463b9dbf5927166f2ab8518a6 Message-Id: <20231129184530.71CBD38582AE@sourceware.org> Date: Wed, 29 Nov 2023 18:45:30 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Nov 2023 18:45:30 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Da0dc1f9a12a4= 394463b9dbf5927166f2ab8518a6 commit a0dc1f9a12a4394463b9dbf5927166f2ab8518a6 Author: Vladimir Mezentsev Date: Tue Nov 28 12:05:15 2023 -0800 gprofng: support GNU option syntax in gp-display-html, plus various fix= es =20 This is a major update of gp-display-html. The option handling has been modified to support the GNU style long option syntax. Compatibility wi= th the previous syntax has been preserved. If still used, a warning is iss= ued. Through the --nowarnings option, this can be suppressed. In addition to this, various lay-out changes have been implemented. In particular to reduce the number of lines that extend beyond column 79. Several bugs have been fixed, for example in the handling of directory = names. =20 gprofng/ChangeLog 2023-11-28 Ruud van der Pas =20 * gp-display-html/gp-display-html.in: Change option syntax plus= fixes. Diff: --- gprofng/gp-display-html/gp-display-html.in | 7125 +++++++++++++++++-------= ---- 1 file changed, 4226 insertions(+), 2899 deletions(-) diff --git a/gprofng/gp-display-html/gp-display-html.in b/gprofng/gp-displa= y-html/gp-display-html.in index dc310f836af..4973297db2a 100644 --- a/gprofng/gp-display-html/gp-display-html.in +++ b/gprofng/gp-display-html/gp-display-html.in @@ -18,11 +18,21 @@ # along with this program; if not, write to the Free Software # Foundation, 51 Franklin Street - Fifth Floor, Boston, # MA 02110-1301, USA. -=20 + use strict; use warnings; -use feature qw (state); + +# Disable before release +# use Perl::Critic; + +use bignum; +use List::Util qw (max); +use Cwd qw (abs_path cwd); +use File::Basename; use File::stat; +use feature qw (state); +use POSIX; +use Getopt::Long qw (Configure); =20 #-------------------------------------------------------------------------= ----- # Check as early as possible if the version of Perl used is supported. @@ -64,14 +74,14 @@ my $g_max_length_first_metric; #-------------------------------------------------------------------------= ----- my $g_path_to_tools; =20 -#-------------------------------------------------------------------------= ------ +#-------------------------------------------------------------------------= ----- # Code debugging flag -#-------------------------------------------------------------------------= ------ +#-------------------------------------------------------------------------= ----- my $g_test_code =3D $FALSE; =20 -#-------------------------------------------------------------------------= ------ +#-------------------------------------------------------------------------= ----- # GPROFNG commands and files used. -#-------------------------------------------------------------------------= ------ +#-------------------------------------------------------------------------= ----- my $GP_DISPLAY_TEXT =3D "gp-display-text"; =20 my $g_gp_output_file =3D $GP_DISPLAY_TEXT.".stdout.log"; @@ -91,6 +101,11 @@ my $g_addressing_mode =3D "64 bit"; my $g_html_less_than_regex =3D '<'; my $g_endbr_inst_regex =3D 'endbr[32|64]'; =20 +#-------------------------------------------------------------------------= ----- +# For consistency, use a global variable. +#-------------------------------------------------------------------------= ----- + my $g_html_new_line =3D "
"; + #-------------------------------------------------------------------------= ----- # These are the regex's used. #-------------------------------------------------------------------------= ----- @@ -99,18 +114,10 @@ my $g_addressing_mode =3D "64 bit"; #-------------------------------------------------------------------------= ----- my $g_branch_regex =3D '\.*([0-9a-fA-F]*):\s+(j).*\s*0x([0-9a-fA-F]+)'; my $g_endbr_regex =3D '\.*([0-9a-fA-F]*):\s+(endbr[32|64])'; - my $g_function_call_v2_regex =3D '(.*)\s+([0-9a-fA-F]*):\s+(call)\s*0x([= 0-9a-fA-F]+)\s*'; - -#-------------------------------------------------------------------------= ----- -# Convenience. These map the on/off value to $TRUE/$FALSE to make the code -# easier to read. For example: "if ($g_verbose)" as opposed to the follow= ing: -# "if ($verbose_setting eq "on"). -#-------------------------------------------------------------------------= ----- -my $g_verbose; -my $g_warnings; -my $g_quiet; + my $g_function_call_v2_regex =3D + '(.*)\s+([0-9a-fA-F]*):\s+(call)\s*0x([0-9a-fA-F]+)\s*'; =20 -my $g_first_metric;=20 +my $g_first_metric; =20 my $binutils_version; my $driver_cmd; @@ -120,10 +127,23 @@ my $version_info; my %g_mapped_cmds =3D (); =20 #-------------------------------------------------------------------------= ----- -# TBD All warning messages are collected and are accessible through the ma= in -# page. +# Variables dealing with warnings and errors. Since a message may span +# multiple lines (for readability reasons), the number of entries in the +# array may not reflect the total number of messages. This is why we use +# separate variables for the counts. +#-------------------------------------------------------------------------= ----- +my @g_error_msgs =3D (); +my @g_warning_msgs =3D (); +my $g_total_error_count =3D 0; #-------------------------------------------------------------------------= ----- -my @g_warning_messages =3D (); +# This count is used in the html_create_warnings_page HTML page to show how +# many warning messages there are. Warnings are printed through gp_messag= e(), +# but since one warning may span multiple lines, we update a separate coun= ter +# that contains the total number of warning messages issued so far. +#-------------------------------------------------------------------------= ----- +my $g_total_warning_count =3D 0; +my $g_options_printed =3D $FALSE; +my $g_abort_msg =3D "cannot recover from the error(s)"; =20 #-------------------------------------------------------------------------= ----- # Contains the names that have already been tagged. This is a global @@ -140,12 +160,10 @@ my $g_context =3D 5; # Defines the range of scan my $g_default_setting_lang =3D "en-US.UTF-8"; my %g_exp_dir_meta_data; =20 -my @g_user_input_errors =3D (); - my $g_html_credits_line; =20 -my $g_warn_keyword =3D "Input warning: "; -my $g_error_keyword =3D "Input error: "; +my $g_warn_keyword =3D "[Warning]"; +my $g_error_keyword =3D "[Error]"; =20 my %g_function_occurrences =3D (); my %g_map_function_to_index =3D (); @@ -155,49 +173,128 @@ my @g_full_function_view_table =3D (); =20 my @g_html_experiment_stats =3D (); =20 -#-------------------------------------------------------------------------= ------ +#-------------------------------------------------------------------------= ----- # These structures contain the information printed in the function views. -#-------------------------------------------------------------------------= ------ +#-------------------------------------------------------------------------= ----- my $g_header_lines; =20 my @g_html_function_name =3D (); =20 -#-------------------------------------------------------------------------= ------ +#-------------------------------------------------------------------------= ----- # TBD: This variable may not be needed and replaced by tp_value my $thresh =3D 0; -#-------------------------------------------------------------------------= ------ +#-------------------------------------------------------------------------= ----- =20 -#-------------------------------------------------------------------------= ------ +#-------------------------------------------------------------------------= ----- # Define the driver command, tool name and version number. -#-------------------------------------------------------------------------= ------ +#-------------------------------------------------------------------------= ----- $driver_cmd =3D "gprofng display html"; $tool_name =3D "gp-display-html"; #$binutils_version =3D "2.38.50"; $binutils_version =3D "BINUTILS_VERSION"; $version_info =3D $tool_name . " GNU binutils version " . $binutils_ve= rsion; =20 -#-------------------------------------------------------------------------= ------ +#-------------------------------------------------------------------------= ----- =20 -#-------------------------------------------------------------------------= ------ +#-------------------------------------------------------------------------= ----- +#-------------------------------------------------------------------------= ----- # Define several key data structures. -#-------------------------------------------------------------------------= ------ -my %g_user_settings =3D=20 +#-------------------------------------------------------------------------= ----- +#-------------------------------------------------------------------------= ----- + +#-------------------------------------------------------------------------= ----- +# This table has the settings of the variables the user may set. +#-------------------------------------------------------------------------= ----- +my %g_user_settings =3D ( - output =3D> { option =3D> "-o" , no_of_arguments =3D> 1, dat= a_type =3D> "path" , current_value =3D> undef, defined =3D> $FALSE}, - overwrite =3D> { option =3D> "-O" , no_of_arguments =3D> 1, dat= a_type =3D> "path" , current_value =3D> undef, defined =3D> $FALSE}, - calltree =3D> { option =3D> "-ct", no_of_arguments =3D> 1, dat= a_type =3D> "onoff" , current_value =3D> "off" , defined =3D> $FALSE= }, - func_limit =3D> { option =3D> "-fl", no_of_arguments =3D> 1, dat= a_type =3D> "pinteger", current_value =3D> 500 , defined =3D> $FALSE= }, - highlight_percentage =3D> { option =3D> "-hp", no_of_arguments =3D> 1,= data_type =3D> "pfloat" , current_value =3D> 90.0 , defined =3D> $F= ALSE}, - threshold_percentage =3D> { option =3D> "-tp", no_of_arguments =3D> 1,= data_type =3D> "pfloat" , current_value =3D> 100.0 , defined =3D> $F= ALSE}, - default_metrics =3D> { option =3D> "-dm", no_of_arguments =3D> 1, dat= a_type =3D> "onoff" , current_value =3D> "off" , defined =3D> $FALSE= }, - ignore_metrics =3D> { option =3D> "-im", no_of_arguments =3D> 1, dat= a_type =3D> "metric_names", current_value =3D> undef, defined =3D> $FALSE}, - verbose =3D> { option =3D> "--verbose" , no_of_arguments =3D>= 1, data_type =3D> "onoff" , current_value =3D> "off" , defined =3D> $FALS= E}, - warnings =3D> { option =3D> "--warnings" , no_of_arguments =3D= > 1, data_type =3D> "onoff" , current_value =3D> "on" , defined =3D> $FALS= E}, - debug =3D> { option =3D> "--debug" , no_of_arguments =3D> 1= , data_type =3D> "size" , current_value =3D> "off" , defined =3D> $FALSE}, - quiet =3D> { option =3D> "--quiet" , no_of_arguments =3D> 1= , data_type =3D> "onoff" , current_value =3D> "off" , defined =3D> $= FALSE}, + verbose =3D> { option =3D> "--verbose", + no_of_arguments =3D> 1, + data_type =3D> "onoff", + current_value =3D> "off", defined =3D> $FALSE}, + + debug =3D> { option =3D> "--debug", + no_of_arguments =3D> 1, + data_type =3D> "size", + current_value =3D> "off", defined =3D> $FALSE}, + + warnings =3D> { option =3D> "--warnings", + no_of_arguments =3D> 1, + data_type =3D> "onoff" , + current_value =3D> "off", defined =3D> $FALSE}, + + nowarnings =3D> { option =3D> "--nowarnings", + no_of_arguments =3D> 1, + data_type =3D> "onoff", + current_value =3D> "off", defined =3D> $FALSE}, + + quiet =3D> { option =3D> "--quiet", + no_of_arguments =3D> 1, + data_type =3D> "onoff", + current_value =3D> "off", defined =3D> $FALSE}, + + output =3D> { option =3D> "-o", + no_of_arguments =3D> 1, + data_type =3D> "path", + current_value =3D> undef, defined =3D> $FALSE}, + + overwrite =3D> { option =3D> "-O", + no_of_arguments =3D> 1, + data_type =3D> "path", + current_value =3D> undef, defined =3D> $FALSE}, + + calltree =3D> { option =3D> "-ct", + no_of_arguments =3D> 1, + data_type =3D> "onoff", + current_value =3D> "off", defined =3D> $FALSE}, + + func_limit =3D> { option =3D> "-fl", + no_of_arguments =3D> 1, + data_type =3D> "pinteger", + current_value =3D> 500, defined =3D> $FALSE}, + + highlight_percentage =3D> { option =3D> "--highlight-percentage", + no_of_arguments =3D> 1, + data_type =3D> "pfloat", + current_value =3D> 90.0, defined =3D> $FALSE}, + + hp =3D> { option =3D> "-hp", + no_of_arguments =3D> 1, + data_type =3D> "pfloat", + current_value =3D> 90.0, defined =3D> $FALSE}, + + threshold_percentage =3D> { option =3D> "-tp", + no_of_arguments =3D> 1, + data_type =3D> "pfloat", + current_value =3D> 100.0, defined =3D> $FALSE}, + + default_metrics =3D> { option =3D> "-dm", + no_of_arguments =3D> 1, + data_type =3D> "onoff", + current_value =3D> "off", defined =3D> $FALSE}, + + ignore_metrics =3D> { option =3D> "-im", + no_of_arguments =3D> 1, + data_type =3D> "metric_names", + current_value =3D> undef, defined =3D> $FALSE}, ); =20 -my %g_debug_size =3D=20 +#-------------------------------------------------------------------------= ----- +# Convenience. These map the on/off value to $TRUE/$FALSE to make the code +# easier to read. For example: "if ($g_verbose)" as opposed to the follow= ing: +# "if ($verbose_setting eq "on"). +#-------------------------------------------------------------------------= ----- +my $g_verbose =3D $FALSE; +my $g_debug =3D $FALSE; +my $g_warnings =3D $TRUE; +my $g_quiet =3D $FALSE; + +#-------------------------------------------------------------------------= ----- +# Since ARGV is modified when parsing the options, a clean copy is used to +# print the original ARGV values in case of a warning, or error. +#-------------------------------------------------------------------------= ----- +my @CopyOfARGV =3D (); + +my %g_debug_size =3D ( "on" =3D> $FALSE, "s" =3D> $FALSE, @@ -219,7 +316,10 @@ my %local_system_config =3D hostname_current =3D> "undefined", ); =20 -# Note that we use single quotes here, because regular expressions wreak h= avoc otherwise. +#-------------------------------------------------------------------------= ----- +# Note that we use single quotes here, because regular expressions wreak +# havoc otherwise. +#-------------------------------------------------------------------------= ----- =20 my %g_arch_specific_settings =3D ( @@ -269,7 +369,7 @@ my %g_html_base_file_name =3D ( ); =20 #-------------------------------------------------------------------------= ----- -# This is cosmetic, but helps with the scoping of variables. +# Introducing main() is cosmetic, but helps with the scoping of variables. #-------------------------------------------------------------------------= ----- main (); =20 @@ -282,6 +382,8 @@ sub main { my $subr_name =3D get_my_name (); =20 + @CopyOfARGV =3D @ARGV; + #-------------------------------------------------------------------------= ----- # The name of the configuration file. #-------------------------------------------------------------------------= ----- @@ -289,9 +391,12 @@ sub main =20 #-------------------------------------------------------------------------= ----- # OS commands executed and search paths. +# +# TBD: check if elfdump should be here too (most likely not though) #-------------------------------------------------------------------------= ----- - my @selected_os_cmds =3D qw (rm mv cat hostname locale which printenv ls - uname readelf mkdir); + my @selected_os_cmds =3D qw (rm cat hostname locale which printenv uname + readelf mkdir); + my @search_paths_os_cmds =3D qw ( /usr/bin /bin @@ -310,11 +415,11 @@ sub main #-------------------------------------------------------------------------= ----- # Local structures (hashes and arrays). #-------------------------------------------------------------------------= ----- - my @exp_dir_list; # List with experiment directories + my @exp_dir_list =3D (); my @metrics_data; =20 my %function_address_info =3D (); - my $function_address_info_ref;=20 + my $function_address_info_ref; =20 my @function_info =3D (); my $function_info_ref; @@ -340,22 +445,19 @@ sub main #-------------------------------------------------------------------------= ----- # Local variables. #-------------------------------------------------------------------------= ----- - my $abs_path_outputdir;=20 + my $abs_path_outputdir; my $archive_dir_not_empty; - my $base_va_executable;=20 + my $base_va_executable; my $executable_name; - my $exp_dir_list_ref; my $found_exp_dir; my $ignore_value; - my $message; + my $msg; my $number_of_metrics; my $va_executable_in_hex; =20 - my $failed_command_mappings;=20 - my $option_errors; - my $total_user_errors; + my $failed_command_mappings; =20 - my $script_pc_metrics;=20 + my $script_pc_metrics; my $dir_check_errors; my $consistency_errors; my $outputdir; @@ -367,7 +469,7 @@ sub main my $elf_arch; my $elf_support; my $home_dir; - my $elf_loadobjects_found;=20 + my $elf_loadobjects_found; =20 my $rc_file_paths_ref; my @rc_file_paths =3D (); @@ -380,9 +482,15 @@ sub main my $system_metrics; my $wall_metrics; my $detail_metrics; - my $detail_metrics_system;=20 + my $detail_metrics_system; + + my $html_test; + my @experiment_data; + my $exp_info_file; + my $exp_info_ref; + my @exp_info; =20 - my $pretty_dir_list;=20 + my $pretty_dir_list; =20 my %metric_value =3D (); my %metric_description =3D (); @@ -416,12 +524,12 @@ sub main #-------------------------------------------------------------------------= ----- if ($#ARGV =3D=3D -1) { - $ignore_value =3D print_help_info ();=20 + $ignore_value =3D print_help_info (); return (0); } =20 #-------------------------------------------------------------------------= ----- -# This part is like a preamble. Before we continue we need to figure out = some=20 +# This part is like a preamble. Before we continue we need to figure out = some # things that are needed later on. #-------------------------------------------------------------------------= ----- =20 @@ -431,214 +539,157 @@ sub main my $location_gp_command =3D $0; =20 #-------------------------------------------------------------------------= ----- -# The very first thing to do is to quickly determine if the user has enabl= ed=20 -# one of the following options and take action accordingly: -# --version, --verbose, --debug, --quiet +# Get the ball rolling. Parse and interpret the options. Some first checks +# are performed. # -# This avoids that there is a gap between the start of the execution and t= he -# moment the options are parsed, checked, and interpreted. +# Instead of bailing out on the first user error, we capture all warnings = and +# errors. The warnings, if any, will be printed once the command line has +# been parsed and verified. Execution continues. # -# When parsing the full command line, these options will be more extensive= ly -# checked and also updated in %g_user_settings - -# Note that a confirmation message, if any, is printed here and not when t= he=20 -# options are parsed and processed. -#-------------------------------------------------------------------------= ----- - - $g_verbose =3D $g_user_settings{"verbose"}{"current_value"} eq "on" ? $= TRUE : $FALSE; - $g_warnings =3D $g_user_settings{"warnings"}{"current_value"} eq "on" ? = $TRUE : $FALSE; - $g_quiet =3D $g_user_settings{"quiet"}{"current_value"} eq "on" ? $TR= UE : $FALSE; - - $ignore_value =3D early_scan_specific_options (); - -#-------------------------------------------------------------------------= ----- -# The next subroutine is executed early to ensure the OS commands we need = are=20 -# available. +# Any error(s) accumulated in this phase will be printed after the command +# line has been parsed and verified. Execution is then terminated. # -# This subroutine stores the commands and the full path names as an associ= ative -# array called "g_mapped_cmds". The command is the key and the value is t= he full=20 -# path. For example: ("uname", /usr/bin/uname). +# In the remainder, any error encountered will immediately terminate the +# execution because we can't guarantee the remaining code will work up to +# some point. #-------------------------------------------------------------------------= ----- - $failed_command_mappings =3D check_and_define_cmds (\@selected_os_cmds, = \@search_paths_os_cmds); + my ($found_exp_dir_ref, $exp_dir_list_ref) =3D parse_and_check_user_opti= ons (); =20 - if ($failed_command_mappings =3D=3D 0) + $found_exp_dir =3D ${ $found_exp_dir_ref }; + + if ($found_exp_dir) { - gp_message ("debug", $subr_name, "verified the OS commands"); + @exp_dir_list =3D @{ $exp_dir_list_ref }; } else { - my $msg =3D "failure in the verification of the OS commands"; - gp_message ("assertion", $subr_name, $msg); + $msg =3D "the list with experiments is either missing, or incorrect"; + gp_message ("debug", $subr_name, $msg); } =20 #-------------------------------------------------------------------------= ----- -# Get the home directory and the locations for the configuration file on t= he=20 -# current system. -#-------------------------------------------------------------------------= ----- - ($home_dir, $rc_file_paths_ref) =3D get_home_dir_and_rc_path ($rc_file_n= ame); - - @rc_file_paths =3D @{ $rc_file_paths_ref }; - gp_message ("debug", $subr_name, "the home directory is $home_dir"); - gp_message ("debugXL", $subr_name, "the search path for the rc file is @= rc_file_paths"); - - $pretty_dir_list =3D build_pretty_dir_list (\@rc_file_paths); - -#-------------------------------------------------------------------------= ----- -# Get the ball rolling. Parse and interpret the configuration file (if an= y) -# and the command line options. -# -# If either $rc_file_errors or $total_user_errors, or both, are non-zero it -# means a fatal error has occured. In this case, all error messages are=20 -# printed and execution is terminated. -# -# Note that the verbose, debug, and quiet options can be set in this file. -# It is a deliberate choice to ignore these for now. The assumption is th= at -# the user will not be happy if we ignore the command line settings for a -# while. +# The final settings for verbose, debug, warnings and quiet are known and = the +# gp_message() subroutine is aware of these. #-------------------------------------------------------------------------= ----- - - gp_message ("debugXL", $subr_name, "processing of the rc file disabled f= or now"); - -# Temporarily disabled print_table_user_settings ("debugXL", "before func= tion process_rc_file"); -# Temporarily disabled -# Temporarily disabled $rc_file_errors =3D process_rc_file ($rc_file_name= , $rc_file_paths_ref); -# Temporarily disabled =20 -# Temporarily disabled if ($rc_file_errors !=3D 0) -# Temporarily disabled { -# Temporarily disabled $message =3D "fatal errors in file $rc_file_na= me encountered"; -# Temporarily disabled gp_message ("debugXL", $subr_name, $message); -# Temporarily disabled } -# Temporarily disabled -# Temporarily disabled print_table_user_settings ("debugXL", "after funct= ion process_rc_file"); + $msg =3D "parsing of the user options completed"; + gp_message ("verbose", $subr_name, $msg); =20 #-------------------------------------------------------------------------= ----- -# Get the ball rolling. Parse and interpret the options. Some first checks -# are performed. -# -# Instead of bailing out on the first user error, we capture all errors, p= rint -# messages and then bail out. This is more user friendly. +# The user options have been taken in. Check for validity and consistency. #-------------------------------------------------------------------------= ----- - gp_message ("verbose", $subr_name, "Parse the user options"); + $msg =3D "process user options"; + gp_message ("verbose", $subr_name, $msg); =20 - $total_user_errors =3D 0; + ($ignored_metrics_ref, $outputdir, + $time_percentage_multiplier, $process_all_functions, $exp_dir_list_ref)= =3D + process_user_options (\@exp_dir_list); =20 - ($option_errors, $found_exp_dir, $exp_dir_list_ref) =3D parse_and_check_= user_options ( - \$#ARGV,=20 - \@ARGV); - $total_user_errors +=3D $option_errors; + @exp_dir_list =3D @{ $exp_dir_list_ref }; + %ignored_metrics =3D %{$ignored_metrics_ref}; =20 #-------------------------------------------------------------------------= ----- -# Dynamically load the modules needed. If a module is not available, prin= t=20 -# an error message and bail out. -# -# This call replaces the following: -# -# use feature qw (state); -# use List::Util qw (min max); -# use Cwd; -# use File::Basename; -# use File::stat; -# use POSIX; -# use bignum; +# The next subroutine is executed early to ensure the OS commands we need = are +# available. # -# Note that this check cannot be done earlier, because in case of a missin= g=20 -# module, the man page would not be generated if the code ends prematurely -# in case the --help and --version options are used.. +# This subroutine stores the commands and the full path names as an +# associative array called "g_mapped_cmds". The command is the key and the +# value is the full path. For example: ("uname", /usr/bin/uname). #-------------------------------------------------------------------------= ----- - my ($module_errors_ref, $missing_modules_ref) =3D handle_module_availabi= lity (); -=20 - my $module_errors =3D ${ $module_errors_ref }; + gp_message ("debug", $subr_name, "verify the OS commands"); + $failed_command_mappings =3D check_and_define_cmds (\@selected_os_cmds, + \@search_paths_os_cmds); =20 - if ($module_errors > 0) + if ($failed_command_mappings =3D=3D 0) { - my $msg; - - my $plural_or_single =3D ($module_errors > 1) ? "modules are" : "mod= ule is"; - my @missing_modules =3D @{ $missing_modules_ref }; - - for my $i (0 .. $#missing_modules) - { - $msg =3D "module $missing_modules[$i] is missing"; - gp_message ("error", $subr_name, $msg); - } - =20 - $msg =3D $module_errors . " " . $plural_or_single . - "missing - execution is terminated"; - gp_message ("abort", $subr_name, $msg); + $msg =3D "successfully verified the OS commands"; + gp_message ("debug", $subr_name, $msg); } =20 #-------------------------------------------------------------------------= ----- -# The user options have been taken in. Check for validity and consistency. #-------------------------------------------------------------------------= ----- - gp_message ("verbose", $subr_name, "Process user options"); - - ($option_errors, $ignored_metrics_ref, $outputdir,=20 - $time_percentage_multiplier, $process_all_functions, - $exp_dir_list_ref) =3D process_user_options ($exp_dir_list_ref); - - @exp_dir_list =3D @{ $exp_dir_list_ref }; - %ignored_metrics =3D %{$ignored_metrics_ref}; - - $total_user_errors +=3D $option_errors; - +# Time to check if any warnings and/or errors have been generated. #-------------------------------------------------------------------------= ----- -# If no option is given for the output directory, pick a default. Otherwi= se, -# if the output directory exists, wipe it clean in case the -O option is u= sed. -# If not, flag an error because the -o option does not overwrite an existi= ng -# directory. #-------------------------------------------------------------------------= ----- - if ($total_user_errors =3D=3D 0) - { - ($option_errors, $outputdir) =3D set_up_output_directory (); - $abs_path_outputdir =3D cwd () . "/" . $outputdir; - $total_user_errors +=3D $option_errors; - } =20 - if ($total_user_errors =3D=3D 0) - { - gp_message ("debug", $subr_name, "the output directory is $outputdir= "); - } - else - { #-------------------------------------------------------------------------= ----- -# All command line errors and warnings are printed here. +# We have completed all the upfront checks. Print any warnings and errors. +# If there are already any errors, execution is terminated. As execution +# continues, errors may occur and they are typically fatal. #-------------------------------------------------------------------------= ----- - my $plural_or_single =3D ($total_user_errors > 1) ? "errors have" : = "error has"; - $message =3D $g_error_keyword; - $message .=3D $total_user_errors; - if ($rc_file_errors > 0) - { - $message .=3D " additional"; - } - $message .=3D " fatal input $plural_or_single been detected:"; - gp_message ("error", $subr_name, $message); - for my $key (keys @g_user_input_errors) - { - gp_message ("error", $subr_name, "$g_error_keyword $g_user_inpu= t_errors[$key]"); - } + if ($g_debug) + { + $msg =3D "internal settings after option processing"; + $ignore_value =3D print_table_user_settings ("diag", $msg); } =20 #-------------------------------------------------------------------------= ----- -# Bail out in case fatal errors have occurred. +# Terminate execution in case fatal errors have occurred. #-------------------------------------------------------------------------= ----- - if ( ($rc_file_errors + $total_user_errors) > 0) + if ( $g_total_error_count > 0) { my $msg =3D "the current values for the user controllable settings"; print_user_settings ("debug", $msg); =20 - gp_message ("abort", $subr_name, "execution terminated"); + gp_message ("abort", $subr_name, $g_abort_msg); } else { my $msg =3D "after parsing the user options, the final values are"; print_user_settings ("debug", $msg); + } + +#-------------------------------------------------------------------------= ----- +# If no option is given for the output directory, pick a default. Otherwi= se, +# if the output directory exists, wipe it clean in case the -O option is u= sed. +# If not, raise an error because the -o option does not overwrite an exist= ing +# directory. +# Also in case of other errors, the execution is terminated. +#-------------------------------------------------------------------------= ----- + $outputdir =3D set_up_output_directory (); + $abs_path_outputdir =3D Cwd::cwd () . "/" . $outputdir; + + $msg =3D "the output directory is $outputdir"; + gp_message ("debug", $subr_name, $msg); =20 #-------------------------------------------------------------------------= ----- -# TBD: Enable once all planned features have been implemented and tested. +# Get the home directory and the locations for the configuration file on t= he +# current system. #-------------------------------------------------------------------------= ----- -# Temporarily disabled $msg =3D "the final values for the user contro= llable settings"; -# Temporarily disabled print_table_user_settings ("verbose", $msg); - } + ($home_dir, $rc_file_paths_ref) =3D get_home_dir_and_rc_path ($rc_file_n= ame); + + @rc_file_paths =3D @{ $rc_file_paths_ref }; + + $msg =3D "the home directory is $home_dir"; + gp_message ("debug", $subr_name, $msg); + +#-------------------------------------------------------------------------= ----- +# TBD: de-activated until this feature has been fully implemented. +#-------------------------------------------------------------------------= ----- +## $msg =3D "the search path for the rc file is @rc_file_paths"; +## gp_message ("debug", $subr_name, $msg); +## $pretty_dir_list =3D build_pretty_dir_list (\@rc_file_paths); + +#-------------------------------------------------------------------------= ----- +# Get the ball rolling. Parse and interpret the configuration file (if an= y) +# and the command line options. +# +# Note that the verbose, debug, and quiet options can be set in this file. +# It is a deliberate choice to ignore these for now. The assumption is th= at +# the user will not be happy if we ignore the command line settings for a +# while. +#-------------------------------------------------------------------------= ----- + $msg =3D "processing of the rc file has been disabled for now"; + gp_message ("debugXL", $subr_name, $msg); + +# Temporarily disabled +# print_table_user_settings ("debugXL", "before function process_rc_file"); +# $rc_file_errors =3D process_rc_file ($rc_file_name, $rc_file_paths_ref); +# if ($rc_file_errors !=3D 0) +# { +# $message =3D "fatal errors in file $rc_file_name encountered"; +# gp_message ("debugXL", $subr_name, $message); +# } +# print_table_user_settings ("debugXL", "after function process_rc_file"); =20 #-------------------------------------------------------------------------= ----- # Print a list with the experiment directory names @@ -647,7 +698,8 @@ sub main =20 my $plural =3D ($#exp_dir_list > 0) ? "directories are" : "directory is"; =20 - gp_message ("verbose", $subr_name, "The experiment " . $plural . ":"); + $msg =3D "the experiment " . $plural . ":"; + gp_message ("verbose", $subr_name, $msg); gp_message ("verbose", $subr_name, $pretty_dir_list); =20 #-------------------------------------------------------------------------= ----- @@ -657,73 +709,77 @@ sub main for my $exp_dir (@exp_dir_list) { my ($filename, $directory_path, $ignore_suffix) =3D fileparse ($exp_d= ir); - gp_message ("debug", $subr_name, "exp_dir =3D $exp_dir");=20 - gp_message ("debug", $subr_name, "filename =3D $filename");=20 - gp_message ("debug", $subr_name, "directory_path =3D $directory_path"= );=20 - $g_exp_dir_meta_data{$filename}{"directory_path"} =3D $directory_path= ;=20 + gp_message ("debug", $subr_name, "exp_dir =3D $exp_dir"); + gp_message ("debug", $subr_name, "filename =3D $filename"); + gp_message ("debug", $subr_name, "directory_path =3D $directory_path"= ); + $g_exp_dir_meta_data{$filename}{"directory_path"} =3D $directory_path; } =20 #-------------------------------------------------------------------------= ----- -# Check whether the experiment directories are valid. If not, it is a fat= al -# error. -# Upon successful return, one directory has been selected to be used in the -# remainder. This is not always the correct thing to do, but is the same = as -# the original code. In due time this should be addressed though. +# TBD: +# This subroutine may be overkill. See what is really needed here and rem= ove +# everything else. +# +# Upon return, one directory has been selected to be used in the remainder. +# This is not always the correct thing to do, but is the same as the origi= nal +# code. In due time this should be addressed though. #-------------------------------------------------------------------------= ----- - ($dir_check_errors, $archive_dir_not_empty, $selected_archive,=20 - $elf_rats_ref) =3D check_validity_exp_dirs ($exp_dir_list_ref); - - if ($dir_check_errors) - { - gp_message ("abort", $subr_name, "execution terminated"); - } - else - { - gp_message ("verbose", $subr_name, "The experiment directories have = been verified and are valid"); - } + ($archive_dir_not_empty, $selected_archive, $elf_rats_ref) =3D + check_validity_exp_dirs (\@exp_dir_list); =20 %elf_rats =3D %{$elf_rats_ref}; =20 -#-------------------------------------------------------------------------= ------ + $msg =3D "the experiment directories have been verified and are valid"; + gp_message ("verbose", $subr_name, $msg); + +#-------------------------------------------------------------------------= ----- # Now that we know the map.xml file(s) are present, we can scan these and = get # the required information. This includes setting the base virtual addres= s. -#-------------------------------------------------------------------------= ------ +#-------------------------------------------------------------------------= ----- $ignore_value =3D determine_base_virtual_address ($exp_dir_list_ref); =20 #-------------------------------------------------------------------------= ----- # Check whether the experiment directories are consistent. #-------------------------------------------------------------------------= ----- - ($consistency_errors, $executable_name) =3D verify_consistency_experimen= ts ($exp_dir_list_ref); + ($consistency_errors, $executable_name) =3D + verify_consistency_experiments ($exp_dir_list_ref); =20 if ($consistency_errors =3D=3D 0) { - gp_message ("verbose", $subr_name, "The experiment directories are c= onsistent"); + $msg =3D "the experiment directories are consistent"; + gp_message ("verbose", $subr_name, $msg); } else { - gp_message ("abort", $subr_name, "number of consistency errors detec= ted: $consistency_errors");=20 + $msg =3D "the number of consistency errors detected: $consistency_e= rrors"; + gp_message ("abort", $subr_name, $msg); } =20 #-------------------------------------------------------------------------= ----- # The directories are consistent. We can now set the base virtual address= of # the executable. #-------------------------------------------------------------------------= ----- - $base_va_executable =3D $g_exp_dir_meta_data{$selected_archive}{"va_base= _in_hex"};=20 + $base_va_executable =3D + $g_exp_dir_meta_data{$selected_archive}{"va_base_in_hex"}; =20 - gp_message ("debug", $subr_name, "executable_name =3D $executable_nam= e"); - gp_message ("debug", $subr_name, "selected_archive =3D $selected_archive= "); - gp_message ("debug", $subr_name, "base_va_executable =3D $base_va_execut= able"); + $msg =3D "executable_name =3D " . $executable_name; + gp_message ("debug", $subr_name, $msg); + $msg =3D "selected_archive =3D " . $selected_archive; + gp_message ("debug", $subr_name, $msg); + $msg =3D "base_va_executable =3D " . $base_va_executable; + gp_message ("debug", $subr_name, $msg); =20 #-------------------------------------------------------------------------= ----- -# The $GP_DISPLAY_TEXT tool is critical and has to be available in order=20 -# to proceed. -# This subroutine only returns a value if the tool can be found." +# The $GP_DISPLAY_TEXT tool is critical and has to be available in order to +# proceed. +# This subroutine only returns a value if the tool can be found. #-------------------------------------------------------------------------= ----- $g_path_to_tools =3D ${ check_availability_tool (\$location_gp_command)}; =20 $GP_DISPLAY_TEXT =3D $g_path_to_tools . $GP_DISPLAY_TEXT; =20 - gp_message ("debug", $subr_name, "updated GP_DISPLAY_TEXT =3D $GP_DISPLA= Y_TEXT"); + $msg =3D "updated GP_DISPLAY_TEXT =3D $GP_DISPLAY_TEXT"; + gp_message ("debug", $subr_name, $msg); =20 #-------------------------------------------------------------------------= ----- # Check if $GP_DISPLAY_TEXT is executable for user, group, and other. @@ -732,35 +788,38 @@ sub main #-------------------------------------------------------------------------= ----- if (not is_file_executable ($GP_DISPLAY_TEXT)) { - my $msg =3D "file $GP_DISPLAY_TEXT is not executable for user, group= , and other"; + $msg =3D "file $GP_DISPLAY_TEXT is not executable for user, group, = and"; + $msg .=3D " other"; gp_message ("warning", $subr_name, $msg); } =20 #-------------------------------------------------------------------------= ----- # Find out what the decimal separator is, as set by the user. #-------------------------------------------------------------------------= ----- - ($return_code, $decimal_separator, $convert_to_dot) =3D=20 + ($return_code, $decimal_separator, $convert_to_dot) =3D determine_decimal_separato= r (); =20 if ($return_code =3D=3D 0) { - my $txt =3D "decimal separator is $decimal_separator " .=20 - "(conversion to dot is " . - ($convert_to_dot =3D=3D $TRUE ? "enabled" : "disabled")."= )"; - gp_message ("debugXL", $subr_name, $txt); + $msg =3D "decimal separator is $decimal_separator"; + $msg .=3D " (conversion to dot is "; + $msg .=3D ($convert_to_dot =3D=3D $TRUE ? "enabled" : "disabled") . = ")"; + gp_message ("debugXL", $subr_name, $msg); } else { - my $msg =3D "the decimal separator cannot be determined - set to $de= cimal_separator"; + $msg =3D "the decimal separator cannot be determined -"; + $msg .=3D " set to $decimal_separator"; gp_message ("warning", $subr_name, $msg); } =20 #-------------------------------------------------------------------------= ----- # Collect and store the system information. #-------------------------------------------------------------------------= ----- - gp_message ("verbose", $subr_name, "Collect system information and adapt= settings"); + $msg =3D "collect system information and adapt settings"; + gp_message ("verbose", $subr_name, $msg); =20 - $return_code =3D get_system_config_info ();=20 + $return_code =3D get_system_config_info (); =20 #-------------------------------------------------------------------------= ----- # The 3 variables below are used in the remainder. @@ -775,20 +834,25 @@ sub main gp_message ("debug", $subr_name, "set arch_uname_s =3D $arch_uname_s= "); gp_message ("debug", $subr_name, "set arch_uname =3D $arch_uname"); =20 -#-------------------------------------------------------------------------= ------ -# This function also sets the values in "g_arch_specific_settings". This = +#-------------------------------------------------------------------------= ----- +# This function also sets the values in "g_arch_specific_settings". This # includes several definitions of regular expressions. -#-------------------------------------------------------------------------= ------ - ($architecture_supported, $elf_arch, $elf_support) =3D=20 - set_system_specific_variables ($arch_uname, $arch_una= me_s); +#-------------------------------------------------------------------------= ----- + ($architecture_supported, $elf_arch, $elf_support) =3D + set_system_specific_variables ($arch_uname, $arch_uname_s); =20 - gp_message ("debug", $subr_name, "architecture_supported =3D $architectu= re_supported"); - gp_message ("debug", $subr_name, "elf_arch =3D $elf_arch"); - gp_message ("debug", $subr_name, "elf_support =3D ".($elf_arc= h ? "TRUE" : "FALSE")); + $msg =3D "architecture_supported =3D $architecture_supported"; + gp_message ("debug", $subr_name, $msg); + $msg =3D "elf_arch =3D $elf_arch"; + gp_message ("debug", $subr_name, $msg); + $msg =3D "elf_support =3D ".($elf_arch ? "TRUE" : "FALSE"); + gp_message ("debug", $subr_name, $msg); =20 for my $feature (sort keys %g_arch_specific_settings) { - gp_message ("debug", $subr_name, "g_arch_specific_settings{$feature}= =3D $g_arch_specific_settings{$feature}"); + $msg =3D "g_arch_specific_settings{$feature} =3D "; + $msg .=3D $g_arch_specific_settings{$feature}; + gp_message ("debug", $subr_name, $msg); } =20 $arch =3D $g_arch_specific_settings{"arch"}; @@ -797,7 +861,8 @@ sub main =20 $g_locale_settings{"LANG"} =3D get_LANG_setting (); =20 - gp_message ("debugXL", $subr_name, "after get_LANG_setting: LANG =3D $g_= locale_settings{'LANG'}"); + $msg =3D "after get_LANG_setting: LANG =3D $g_locale_settings{'LANG'}"; + gp_message ("debugXL", $subr_name, $msg); =20 #-------------------------------------------------------------------------= ----- # Temporarily reset selected settings since these are not yet implemented. @@ -808,19 +873,28 @@ sub main # TBD: Revisit. Is this really necessary? #-------------------------------------------------------------------------= ----- =20 - ($executable_name, $va_executable_in_hex) =3D check_loadobjects_are_elf = ($selected_archive); + ($executable_name, $va_executable_in_hex) =3D + check_loadobjects_are_elf ($selected_archive); $elf_loadobjects_found =3D $TRUE; =20 # TBD: Hack and those ARCHIVES_ names can be eliminated $ARCHIVES_MAP_NAME =3D $executable_name; $ARCHIVES_MAP_VADDR =3D $va_executable_in_hex; - gp_message ("debugXL", $subr_name, "hack ARCHIVES_MAP_NAME =3D $ARCHIVE= S_MAP_NAME"); - gp_message ("debugXL", $subr_name, "hack ARCHIVES_MAP_VADDR =3D $ARCHIVE= S_MAP_VADDR"); =20 - gp_message ("debugXL", $subr_name, "after call to check_loadobjects_are_= elf forced elf_loadobjects_found =3D $elf_loadobjects_found"); - =20 + $msg =3D "hack ARCHIVES_MAP_NAME =3D $ARCHIVES_MAP_NAME"; + gp_message ("debugXL", $subr_name, $msg); + $msg =3D "hack ARCHIVES_MAP_VADDR =3D $ARCHIVES_MAP_VADDR"; + gp_message ("debugXL", $subr_name, $msg); + + $msg =3D "after call to check_loadobjects_are_elf forced"; + $msg .=3D " elf_loadobjects_found =3D $elf_loadobjects_found"; + gp_message ("debugXL", $subr_name, $msg); + $g_html_credits_line =3D ${ create_html_credits () }; - gp_message ("debugXL", $subr_name, "g_html_credits_line =3D $g_html_cred= its_line"); + + $msg =3D "g_html_credits_line =3D $g_html_credits_line"; + gp_message ("debugXL", $subr_name, $msg); + #-------------------------------------------------------------------------= ----- # Add a "/" to simplify the construction of path names in the remainder. # @@ -841,7 +915,7 @@ sub main $detail_metrics_system =3D 'e.totalcpu:e.system'; $call_metrics =3D 'a.totalcpu'; =20 - my $cmd_options;=20 + my $cmd_options; my $metrics_cmd; =20 my $outfile1 =3D $outputdir ."metrics"; @@ -853,9 +927,11 @@ sub main # to get all the output in files $outfile1 and $outfile2. These are then # parsed. #-------------------------------------------------------------------------= ----- - gp_message ("verbose", $subr_name, "Gather the metrics data from the exp= eriments"); + $msg =3D "gather the metrics data from the experiments"; + gp_message ("verbose", $subr_name, $msg); =20 - $return_code =3D get_metrics_data (\@exp_dir_list, $outputdir, $outfile1= , $outfile2, $gp_error_file); + $return_code =3D get_metrics_data (\@exp_dir_list, $outputdir, $outfile1, + $outfile2, $gp_error_file); =20 if ($return_code !=3D 0) { @@ -865,8 +941,11 @@ sub main #-------------------------------------------------------------------------= ----- # TBD: Test this code #-------------------------------------------------------------------------= ----- - open (METRICS, "<", $outfile1)=20 - or die ("$subr_name - unable to open metric value data file $outfile1 = for reading: '$!'"); + $msg =3D "unable to open metric value data file $outfile1 for reading:"; + open (METRICS, "<", $outfile1) + or die ($subr_name . " - " . $msg . " " . $!); + + $msg =3D "opened file $outfile1 for reading"; gp_message ("debug", $subr_name, "opened file $outfile1 for reading"); =20 chomp (@metrics_data =3D ); @@ -874,7 +953,8 @@ sub main =20 for my $i (keys @metrics_data) { - gp_message ("debugXL", $subr_name, "metrics_data[$i] =3D $metrics_da= ta[$i]"); + $msg =3D "metrics_data[$i] =3D " . $metrics_data[$i]; + gp_message ("debugXL", $subr_name, $msg); } =20 #-------------------------------------------------------------------------= ----- @@ -888,7 +968,7 @@ sub main { gp_message ("verbose", $subr_name, "Process the metrics data"); =20 - ($metric_value_ref, $metric_description_ref, $metric_found_ref,=20 + ($metric_value_ref, $metric_description_ref, $metric_found_ref, $user_metrics, $system_metrics, $wall_metrics, $summary_metrics, $detail_metrics, $detail_metrics_system, $call_me= trics ) =3D process_metrics_data ($outfile1, $outfile2, \%ignored_metrics= ); @@ -898,14 +978,19 @@ sub main %metric_found =3D %{ $metric_found_ref }; %metric_description_reversed =3D reverse %metric_description; =20 - gp_message ("debugXL", $subr_name, "after the call to process_metric= s_data"); + $msg =3D "after the call to process_metrics_data"; + gp_message ("debugXL", $subr_name, $msg); + for my $metric (sort keys %metric_value) { - gp_message ("debugXL", $subr_name, "metric_value{$metric} =3D $m= etric_value{$metric}"); + $msg =3D "metric_value{$metric} =3D " . $metric_value{$metric}; + gp_message ("debugXL", $subr_name, $msg); } for my $metric (sort keys %metric_description) { - gp_message ("debugXL", $subr_name, "metric_description{$metric} = =3D $metric_description{$metric}"); + $msg =3D "metric_description{$metric} =3D"; + $msg .=3D " " . $metric_description{$metric}; + gp_message ("debugXL", $subr_name, $msg); } gp_message ("debugXL", $subr_name, "user_metrics =3D $user_metrics= "); gp_message ("debugXL", $subr_name, "system_metrics =3D $system_metri= cs"); @@ -918,9 +1003,10 @@ sub main # # TBD: These should be OS dependent. #-------------------------------------------------------------------------= ----- - gp_message ("verbose", $subr_name, "Select the set of default metric= s");=20 + $msg =3D "select the set of default metrics"; + gp_message ("verbose", $subr_name, $msg); =20 - ($metric_description_ref, $metric_found_ref, $summary_metrics,=20 + ($metric_description_ref, $metric_found_ref, $summary_metrics, $detail_metrics, $detail_metrics_system, $call_metrics ) =3D set_default_metrics ($outfile1, \%ignored_metrics); =20 @@ -929,51 +1015,54 @@ sub main %metric_found =3D %{ $metric_found_ref }; %metric_description_reversed =3D reverse %metric_description; =20 - gp_message ("debug", $subr_name, "after the call to set_default_metr= ics"); + $msg =3D "after the call to set_default_metrics"; + gp_message ("debug", $subr_name, $msg); =20 } =20 $number_of_metrics =3D split (":", $summary_metrics); =20 - gp_message ("debugXL", $subr_name, "summary_metrics =3D $summary_m= etrics"); - gp_message ("debugXL", $subr_name, "detail_metrics =3D $detail_me= trics"); - gp_message ("debugXL", $subr_name, "detail_metrics_system =3D $detail_me= trics_system"); - gp_message ("debugXL", $subr_name, "call_metrics =3D $call_metr= ics"); - gp_message ("debugXL", $subr_name, "number_of_metrics =3D $number_of_met= rics"); + $msg =3D "summary_metrics =3D " . $summary_metrics; + gp_message ("debugXL", $subr_name, $msg); + $msg =3D "detail_metrics =3D " . $detail_metrics; + gp_message ("debugXL", $subr_name, $msg); + $msg =3D "detail_metrics_system =3D " . $detail_metrics_system; + gp_message ("debugXL", $subr_name, $msg); + $msg =3D "call_metrics =3D " . $call_metrics; + gp_message ("debugXL", $subr_name, $msg); + $msg =3D "number_of_metrics =3D " . $number_of_metrics; + gp_message ("debugXL", $subr_name, $msg); =20 #-------------------------------------------------------------------------= ----- # TBD Find a way to better handle this situation: #-------------------------------------------------------------------------= ----- for my $im (keys %metric_found) { - gp_message ("debugXL", $subr_name, "metric_found{$im} =3D $metric_fo= und{$im}"); + $msg =3D "metric_found{$im} =3D " . $metric_found{$im}; + gp_message ("debugXL", $subr_name, $msg); } for my $im (keys %ignored_metrics) { if (not exists ($metric_found{$im})) { - gp_message ("debugXL", $subr_name, "user requested ignored metri= c (-im) $im does not exist in collected metrics"); + $msg =3D "user requested ignored metric (-im) $im does not exis= t in"; + $msg .=3D " collected metrics"; + gp_message ("debugXL", $subr_name, $msg); } } =20 #-------------------------------------------------------------------------= ----- # Get the information on the experiments. #-------------------------------------------------------------------------= ----- - gp_message ("verbose", $subr_name, "Generate the experiment information"= ); - =20 - my $exp_info_file_ref; - my $exp_info_file; - my $exp_info_ref; - my @exp_info; - - my $experiment_data_ref; + $msg =3D "generate the experiment information"; + gp_message ("verbose", $subr_name, $msg); =20 - $experiment_data_ref =3D get_experiment_info (\$outputdir, \@exp_dir_lis= t); - my @experiment_data =3D @{ $experiment_data_ref }; + my $experiment_data_ref =3D get_experiment_info (\$outputdir, \@exp_dir_= list); + @experiment_data =3D @{ $experiment_data_ref }; =20 for my $i (sort keys @experiment_data) { - my $msg =3D "i =3D $i " . $experiment_data[$i]{"exp_id"} . " =3D> " = .=20 + my $msg =3D "i =3D $i " . $experiment_data[$i]{"exp_id"} . " =3D> " . $experiment_data[$i]{"exp_name_full"}; gp_message ("debugM", $subr_name, $msg); } @@ -991,21 +1080,21 @@ sub main } } =20 - @g_html_experiment_stats =3D @{ create_exp_info ( - \@exp_dir_list, - \@experiment_data) }; + @g_html_experiment_stats =3D @{ create_exp_info (\@exp_dir_list, + \@experiment_data) }; =20 - $table_execution_stats_ref =3D html_generate_exp_summary ( - \$outputdir,=20 - \@experiment_data); + $table_execution_stats_ref =3D html_generate_exp_summary (\$outputdir, + \@experiment_data); @table_execution_stats =3D @{ $table_execution_stats_ref }; =20 #-------------------------------------------------------------------------= ----- # Get the function overview. #-------------------------------------------------------------------------= ----- - gp_message ("verbose", $subr_name, "Generate the list with functions exe= cuted"); + $msg =3D "generate the list with functions executed"; + gp_message ("verbose", $subr_name, $msg); =20 - my ($outfile, $sort_fields_ref) =3D get_hot_functions (\@exp_dir_list, $= summary_metrics, $outputdir); + my ($outfile, $sort_fields_ref) =3D + get_hot_functions (\@exp_dir_list, $summary_metrics, $outputdir); =20 @sort_fields =3D @{$sort_fields_ref}; =20 @@ -1013,11 +1102,12 @@ sub main # Parse the output from the fsummary command and store the relevant data f= or # all the functions listed there. #-------------------------------------------------------------------------= ----- + $msg =3D "analyze and store the relevant function information"; + gp_message ("verbose", $subr_name, $msg); =20 - gp_message ("verbose", $subr_name, "Analyze and store the relevant funct= ion information"); - - ($function_info_ref, $function_address_and_index_ref, $addressobjtextm_r= ef,=20 - $LINUX_vDSO_ref, $function_view_structure_ref) =3D get_function_info ($= outfile); + ($function_info_ref, $function_address_and_index_ref, $addressobjtextm_r= ef, + $LINUX_vDSO_ref, $function_view_structure_ref) =3D + get_function_info ($outfile); =20 @function_info =3D @{ $function_info_ref }; %function_address_and_index =3D %{ $function_address_and_index_ref }; @@ -1029,194 +1119,215 @@ sub main { for my $fields (keys %{$function_info[$keys]}) { - gp_message ("debugXL", $subr_name,"$keys $fields $function_info[= $keys]{$fields}"); + $msg =3D "$keys $fields $function_info[$keys]{$fields}"; + gp_message ("debugXL", $subr_name, $msg); } } =20 for my $i (keys %addressobjtextm) { - gp_message ("debugXL", $subr_name,"addressobjtextm{$i} =3D $addresso= bjtextm{$i}"); + $msg =3D "addressobjtextm{$i} =3D " . $addressobjtextm{$i}; + gp_message ("debugXL", $subr_name, $msg); } =20 - gp_message ("verbose", $subr_name, "Generate the files with function ove= rviews and the callers-callees information");=20 + $msg =3D "generate the files with function overviews and the"; + $msg .=3D " callers-callees information"; + gp_message ("verbose", $subr_name, $msg); =20 - $script_pc_metrics =3D generate_function_level_info (\@exp_dir_list,=20 - $call_metrics,=20 - $summary_metrics,=20 - $outputdir,=20 + $script_pc_metrics =3D generate_function_level_info (\@exp_dir_list, + $call_metrics, + $summary_metrics, + $outputdir, $sort_fields_ref); =20 - gp_message ("verbose", $subr_name, "Preprocess the files with the functi= on level information"); + $msg =3D "preprocess the files with the function level information"; + gp_message ("verbose", $subr_name, $msg); =20 $ignore_value =3D preprocess_function_files ( - $metric_description_ref,=20 - $script_pc_metrics,=20 - $outputdir,=20 + $metric_description_ref, + $script_pc_metrics, + $outputdir, \@sort_fields); =20 - gp_message ("verbose", $subr_name, "For each function, generate a set of= files"); - - ($function_info_ref, $function_address_info_ref, $addressobj_index_ref) = =3D process_function_files ( - = \@exp_dir_list, - = $executable_name, - = $time_percentage_multiplier, - = $summary_metrics, - = $process_all_functions, - = $elf_loadobjects_found,=20 - = $outputdir,=20 - = \@sort_fields,=20 - = \@function_info,=20 - = \%function_address_and_index, - = \%LINUX_vDSO, - = \%metric_description, - = $elf_arch, - = $base_va_executable, - = $ARCHIVES_MAP_NAME, $ARCHIVES_MAP_VADDR, \%elf_rats); + $msg =3D "for each function, generate a set of files"; + gp_message ("verbose", $subr_name, $msg); + + ($function_info_ref, $function_address_info_ref, $addressobj_index_ref) = =3D + process_function_files (\@exp_dir_list, + $executable_name, + $time_percentage_multiplier, + $summary_metrics, + $process_all_functions, + $elf_loadobjects_found, + $outputdir, + \@sort_fields, + \@function_info, + \%function_address_and_index, + \%LINUX_vDSO, + \%metric_description, + $elf_arch, + $base_va_executable, + $ARCHIVES_MAP_NAME, + $ARCHIVES_MAP_VADDR, + \%elf_rats); =20 @function_info =3D @{ $function_info_ref }; %function_address_info =3D %{ $function_address_info_ref }; %addressobj_index =3D %{ $addressobj_index_ref }; =20 -#-------------------------------------------------------------------------= ------------ +#-------------------------------------------------------------------------= ----- # Parse the disassembly information and generate the html files. -#-------------------------------------------------------------------------= ------------ - gp_message ("verbose", $subr_name, "Parse the disassembly files and gene= rate the html files"); +#-------------------------------------------------------------------------= ----- + $msg =3D "parse the disassembly files and generate the html files"; + gp_message ("verbose", $subr_name, $msg); =20 - $ignore_value =3D parse_dis_files (\$number_of_metrics, \@function_info,= =20 - \%function_address_and_index, - \$outputdir, \%addressobj_index); + $ignore_value =3D parse_dis_files (\$number_of_metrics, + \@function_info, + \%function_address_and_index, + \$outputdir, + \%addressobj_index); =20 -#-------------------------------------------------------------------------= ------------ +#-------------------------------------------------------------------------= ----- # Parse the source information and generate the html files. -#-------------------------------------------------------------------------= ------------ - gp_message ("verbose", $subr_name, "Parse the source files and generate = the html files"); +#-------------------------------------------------------------------------= ----- + $msg =3D "parse the source files and generate the html files"; + gp_message ("verbose", $subr_name, $msg); =20 parse_source_files (\$number_of_metrics, \@function_info, \$outputdir); =20 -#-------------------------------------------------------------------------= ------------ +#-------------------------------------------------------------------------= ----- # Parse the caller-callee information and generate the html files. -#-------------------------------------------------------------------------= ------------ - gp_message ("verbose", $subr_name, "Process the caller-callee informatio= n and generate the html file"); +#-------------------------------------------------------------------------= ----- + $msg =3D "process the caller-callee information and generate the html fi= le"; + gp_message ("verbose", $subr_name, $msg); =20 -#-------------------------------------------------------------------------= ------------ +#-------------------------------------------------------------------------= ----- # Generate the caller-callee information. -#-------------------------------------------------------------------------= ------------ - $ignore_value =3D generate_caller_callee ( - \$number_of_metrics,=20 - \@function_info,=20 - \%function_view_structure, - \%function_address_info,=20 - \%addressobjtextm,=20 - \$outputdir); - -#-------------------------------------------------------------------------= ------------ +#-------------------------------------------------------------------------= ----- + $ignore_value =3D generate_caller_callee (\$number_of_metrics, + \@function_info, + \%function_view_structure, + \%function_address_info, + \%addressobjtextm, + \$outputdir); + +#-------------------------------------------------------------------------= ----- # Parse the calltree information and generate the html files. -#-------------------------------------------------------------------------= ------------ +#-------------------------------------------------------------------------= ----- if ($g_user_settings{"calltree"}{"current_value"} eq "on") { - my $msg =3D "Process the call tree information and generate the html= file"; + $msg =3D "process the call tree information and generate the html fi= le"; gp_message ("verbose", $subr_name, $msg); =20 - $ignore_value =3D process_calltree ( - \@function_info,=20 - \%function_address_info,=20 - \%addressobjtextm,=20 - $outputdir); + $ignore_value =3D process_calltree (\@function_info, + \%function_address_info, + \%addressobjtextm, + $outputdir); } =20 -#-------------------------------------------------------------------------= ------------ -# TBD -#-------------------------------------------------------------------------= ------------ - gp_message ("verbose", $subr_name, "Generate the html file with the metr= ics information"); +#-------------------------------------------------------------------------= ----- +# Process the metric values. +#-------------------------------------------------------------------------= ----- + $msg =3D "generate the html file with the metrics information"; + gp_message ("verbose", $subr_name, $msg); =20 - $ignore_value =3D process_metrics ( - $outputdir,=20 - \@sort_fields,=20 - \%metric_description,=20 - \%ignored_metrics); + $ignore_value =3D process_metrics ($outputdir, + \@sort_fields, + \%metric_description, + \%ignored_metrics); =20 -#-------------------------------------------------------------------------= ------------ +#-------------------------------------------------------------------------= ----- # Generate the function view html files. -#-------------------------------------------------------------------------= ------------ - gp_message ("verbose", $subr_name, "Generate the function view html file= s"); +#-------------------------------------------------------------------------= ----- + $msg =3D "generate the function view html files"; + gp_message ("verbose", $subr_name, $msg); =20 $html_first_metric_file_ref =3D generate_function_view ( - \$outputdir,=20 - \$summary_metrics,=20 - \$number_of_metrics,=20 - \@function_info,=20 - \%function_view_structure, - \%function_address_info,=20 - \@sort_fields,=20 - \@exp_dir_list,=20 - \%addressobjtextm); + \$outputdir, + \$summary_metrics, + \$number_of_metrics, + \@function_info, + \%function_view_structure, + \%function_address_info, + \@sort_fields, + \@exp_dir_list, + \%addressobjtextm); =20 $html_first_metric_file =3D ${ $html_first_metric_file_ref }; =20 - gp_message ("debugXL", $subr_name, "html_first_metric_file =3D $html_fir= st_metric_file"); + $msg =3D "html_first_metric_file =3D " . $html_first_metric_file; + gp_message ("debugXL", $subr_name, $msg); =20 - my $html_test =3D ${ generate_home_link ("left") }; - gp_message ("debugXL", $subr_name, "html_test =3D $html_test"); + $html_test =3D ${ generate_home_link ("left") }; + $msg =3D "html_test =3D " . $html_test; + gp_message ("debugXL", $subr_name, $msg); =20 - my $number_of_warnings_ref =3D create_html_warnings_page (\$outputdir); +#-------------------------------------------------------------------------= ----- +# Unconditionnaly generate the page with the warnings. +#-------------------------------------------------------------------------= ----- + $ignore_value =3D html_create_warnings_page (\$outputdir); =20 -#-------------------------------------------------------------------------= ------------ +#-------------------------------------------------------------------------= ----- # Generate the index.html file. -#-------------------------------------------------------------------------= ------------ - gp_message ("verbose", $subr_name, "Generate the index.html file"); - - $ignore_value =3D generate_index (\$outputdir,=20 - \$html_first_metric_file, - \$summary_metrics,=20 - \$number_of_metrics,=20 - \@function_info,=20 - \%function_address_info,=20 - \@sort_fields,=20 - \@exp_dir_list,=20 - \%addressobjtextm,=20 - \%metric_description_reversed, - $number_of_warnings_ref, - \@table_execution_stats); - -#-------------------------------------------------------------------------= ------------ -# We're done. In debug mode, print the meta data for the experiment direc= tories. -#-------------------------------------------------------------------------= ------------ - $ignore_value =3D print_meta_data_experiments ("debug"); - - my $results_file =3D $abs_path_outputdir . "/index.html"; - my $prologue_text =3D "Processing completed - view file $results_file in= a browser"; - gp_message ("diag", $subr_name, $prologue_text); - - return (0); +#-------------------------------------------------------------------------= ----- + $msg =3D "generate the index.html file"; + gp_message ("verbose", $subr_name, $msg); =20 -} #-- End of subroutine main + $ignore_value =3D html_generate_index (\$outputdir, + \$html_first_metric_file, + \$summary_metrics, + \$number_of_metrics, + \@function_info, + \%function_address_info, + \@sort_fields, + \@exp_dir_list, + \%addressobjtextm, + \%metric_description_reversed, + \@table_execution_stats); =20 #-------------------------------------------------------------------------= ----- -# Print a message after a failure in $GP_DISPLAY_TEXT. +# We're done. In debug mode, print the meta data for the experiment +# directories. #-------------------------------------------------------------------------= ----- -sub msg_display_text_failure -{ - my $subr_name =3D get_my_name (); - - my ($gp_display_text_cmd, $error_code, $error_file) =3D @_; - - my $msg; + $ignore_value =3D print_meta_data_experiments ("debug"); =20 - $msg =3D "error code =3D $error_code - failure executing the following c= ommand:"; - gp_message ("error", $subr_name, $msg); +#-------------------------------------------------------------------------= ----- +# Before the execution completes, print the warning(s) on the screen. +# +# Note that this assumes that no additional warnings have been created sin= ce +# the call to html_create_warnings_page. Otherwise there will be a discre= pancy +# between what is printed on the screen and shown in the warnings.html pag= e. +#-------------------------------------------------------------------------= ----- + if (($g_total_warning_count > 0) and ($g_warnings)) + { + $ignore_value =3D print_warnings_buffer (); + @g_warning_msgs =3D (); + } =20 - gp_message ("error", $subr_name, $gp_display_text_cmd); +#-------------------------------------------------------------------------= ----- +# This is not supposed to happen, but in case there are any fatal errors t= hat +# have not caused the execution to terminate, print them here. +#-------------------------------------------------------------------------= ----- + if (@g_error_msgs) + { + $ignore_value =3D print_errors_buffer (\$g_error_keyword); + } =20 - $msg =3D "check file $error_file for more details"; - gp_message ("error", $subr_name, $msg); +#-------------------------------------------------------------------------= ----- +# One line message to show where the results can be found. +#-------------------------------------------------------------------------= ----- + my $results_file =3D $abs_path_outputdir . "/index.html"; + my $prologue_text =3D "Processing completed - view file $results_file" . + " in a browser"; + gp_message ("diag", $subr_name, $prologue_text); =20 return (0); =20 -} #-- End of subroutine msg_display_text_failure +} #-- End of subroutine main =20 #-------------------------------------------------------------------------= ----- # If it is not present, add a "/" to the name of the argument. This is -# intended to be used for the name of the output directory and makes it=20 +# intended to be used for the name of the output directory and makes it # easier to construct pathnames. #-------------------------------------------------------------------------= ----- sub append_forward_slash @@ -1228,7 +1339,7 @@ sub append_forward_slash my $length_of_string =3D length ($input_string); my $return_string =3D $input_string; =20 - if (rindex ($input_string, "/") !=3D $length_of_string-1)=20 + if (rindex ($input_string, "/") !=3D $length_of_string-1) { $return_string .=3D "/"; } @@ -1255,7 +1366,7 @@ sub build_pretty_dir_list } #-- End of subroutine build_pretty_dir_list =20 #-------------------------------------------------------------------------= ----- -# Calculate the target address in hex by adding the instruction to the=20 +# Calculate the target address in hex by adding the instruction to the # instruction address. #-------------------------------------------------------------------------= ----- sub calculate_target_hex_address @@ -1264,14 +1375,15 @@ sub calculate_target_hex_address =20 my ($instruction_address, $instruction_offset) =3D @_; =20 - my $dec_branch_target;=20 + my $dec_branch_target; my $d1; my $d2; my $first_char; my $length_of_string; my $mask; + my $msg; my $number_of_fields; - my $raw_hex_branch_target;=20 + my $raw_hex_branch_target; my $result; =20 if ($g_addressing_mode eq "64 bit") @@ -1281,10 +1393,11 @@ sub calculate_target_hex_address } else { - gp_message ("abort", $subr_name, "g_addressing_mode =3D $g_addressin= g_mode not supported\n"); + $msg =3D "g_addressing_mode =3D $g_addressing_mode not supported"; + gp_message ("abort", $subr_name, $msg); } - =20 - $length_of_string =3D length ($instruction_offset);=20 + + $length_of_string =3D length ($instruction_offset); $first_char =3D lcfirst (substr ($instruction_offset,0,1)); $d1 =3D bigint::hex ($instruction_offset); $d2 =3D bigint::hex ($mask); @@ -1315,11 +1428,15 @@ sub calculate_target_hex_address } #-- End of subroutine calculate_target_hex_address =20 #-------------------------------------------------------------------------= ----- -# Sets the absolute path to all commands in array @cmds. The commands and= =20 -# their respective paths are stored in hash "g_mapped_cmds". +# Sets the absolute path to all commands in array @cmds. +# +# First, it is checked if the command is in the search path, built-in, or = an +# alias. If this is not the case, search for it in a couple of locations. +# +# If this all fails, warning messages are printed, but this is not a hard +# error. Yet. Most likely, things will go bad later on. # -# If no such mapping is found, a warning is issued, but execution continue= s. -# The warning(s) may help with troubleshooting, should a failure occur lat= er. +# The commands and their respective paths are stored in hash "g_mapped_cmd= s". #-------------------------------------------------------------------------= ----- sub check_and_define_cmds { @@ -1333,37 +1450,129 @@ sub check_and_define_cmds my @cmds =3D @{$cmds_ref}; my @search_path =3D @{$search_path_ref}; =20 - my $found_match; - my $target_cmd;=20 - my $failed_cmd;=20 - my $no_of_failed_mappings;=20 + my @the_fields =3D (); + + my $cmd; + my $cmd_found; + my $error_code; + my $failed_cmd; my $failed_cmds; + my $found_match; + my $mapped; + my $msg; + my $no_of_failed_mappings; + my $no_of_fields; + my $output_cmd; + my $target_cmd; + my $failed_mapping =3D $FALSE; + my $full_path_cmd; =20 - gp_message ("debug", $subr_name, "\@cmds =3D @cmds"); - gp_message ("debug", $subr_name, "\@search_path =3D @search_path"); + gp_message ("debugXL", $subr_name, "\@cmds =3D @cmds"); + gp_message ("debugXL", $subr_name, "\@search_path =3D @search_path"); =20 #-------------------------------------------------------------------------= ----- -# Search for the command to be in the search path given. In case no such = path +# Search for the command and record the absolute path. In case no such pa= th # can be found, the entry in $g_mapped_cmds is assigned a special value th= at # will be checked for in the next block. #-------------------------------------------------------------------------= ----- - for my $cmd (@cmds) + for $cmd (@cmds) { - $found_match =3D $FALSE; - for my $path (@search_path) + $target_cmd =3D "(command -v $cmd; echo \$\?)"; + + ($error_code, $output_cmd) =3D execute_system_cmd ($target_cmd); + + if ($error_code !=3D 0) +#-------------------------------------------------------------------------= ----- +# This is unlikely to happen, since it means the command executed failed. +#-------------------------------------------------------------------------= ----- + { + $msg =3D "error executing this command: " . $target_cmd; + gp_message ("warning", $subr_name, $msg); + $msg =3D "execution continues, but may fail later on"; + gp_message ("warning", $subr_name, $msg); + + $g_total_warning_count++; + } + else +#-------------------------------------------------------------------------= ----- +# So far, all is well, but is the target command available? +#-------------------------------------------------------------------------= ----- { - $target_cmd =3D $path . "/" . $cmd;=20 - if (-x $target_cmd) +#-------------------------------------------------------------------------= ----- +# The output from the $target_cmd command should contain 2 lines in case t= he +# command has been found. The first line shows the command with the full +# path, while the second line has the exit code. +# +# If the exit code is not zero, the command has not been found. +#-------------------------------------------------------------------------= ----- + +#-------------------------------------------------------------------------= ----- +# Split the output at the \n character and check the number of lines as +# well as the return code. +#-------------------------------------------------------------------------= ----- + @the_fields =3D split ("\n", $output_cmd); + $no_of_fields =3D scalar (@the_fields); + $cmd_found =3D ($the_fields[$no_of_fields-1] =3D=3D 0 ? $TRUE= : $FALSE); + +#-------------------------------------------------------------------------= ----- +# This is unexpected. Throw an assertion error and bail out. +#-------------------------------------------------------------------------= ----- + if ($no_of_fields > 2) { - $found_match =3D $TRUE; - $g_mapped_cmds{$cmd} =3D $target_cmd; - last; + gp_message ("error", $subr_name, "output from $target_cmd:"); + gp_message ("error", $subr_name, $output_cmd); + + $msg =3D "the output from $target_cmd has more than 2 lines"; + gp_message ("assertion", $subr_name, $msg); } - } =20 - if (not $found_match) - { - $g_mapped_cmds{$cmd} =3D "road_to_nowhere"; + if ($cmd_found) + { + $full_path_cmd =3D $the_fields[0]; +#-------------------------------------------------------------------------= ----- +# The command is in the search path. Store the full path to the command. +#-------------------------------------------------------------------------= ----- + $msg =3D "the $cmd command is in the search path"; + gp_message ("debug", $subr_name, $msg); + + $g_mapped_cmds{$cmd} =3D $full_path_cmd; + } + else +#-------------------------------------------------------------------------= ----- +# A best effort to locate the command elsewhere. If found, store the comm= and +# with the absolute path included. Otherwise print a warning, but continu= e. +#-------------------------------------------------------------------------= ----- + { + $msg =3D "the $cmd command is not in the search path"; + $msg .=3D " - start a best effort search to find it"; + gp_message ("debug", $subr_name, $msg); + + $found_match =3D $FALSE; + for my $path (@search_path) + { + $target_cmd =3D $path . "/" . $cmd; + if (-x $target_cmd) + { + $msg =3D "found the command in $path"; + gp_message ("debug", $subr_name, $msg); + + $found_match =3D $TRUE; + $g_mapped_cmds{$cmd} =3D $target_cmd; + last; + } + else + { + $msg =3D "failure to find the $cmd command in $path"; + gp_message ("debug", $subr_name, $msg); + } + } + + if (not $found_match) + { + $g_mapped_cmds{$cmd} =3D "road to nowhere"; + $failed_mapping =3D $TRUE; + } + } } } =20 @@ -1372,26 +1581,50 @@ sub check_and_define_cmds #-------------------------------------------------------------------------= ----- $no_of_failed_mappings =3D 0; $failed_cmds =3D ""; - while ( my ($cmd, $mapped) =3D each %g_mapped_cmds) + +#-------------------------------------------------------------------------= ----- +# Print a warning message before showing the results, that at least one se= arch +# has failed. +#-------------------------------------------------------------------------= ----- + if ($failed_mapping) + { + $msg =3D "
" . "failure in the verification of the OS commands:"; + gp_message ("warning", $subr_name, $msg); + } + + while ( ($cmd, $mapped) =3D each %g_mapped_cmds) { - if ($mapped eq "road_to_nowhere") + if ($mapped eq "road to nowhere") { - my $msg =3D "cannot find a path for command $cmd - " . - "assume this will still work without a path"; + $msg =3D "cannot find a path for command $cmd"; gp_message ("warning", $subr_name, $msg); - $no_of_failed_mappings++;=20 - $failed_cmds .=3D $cmd;=20 + gp_message ("debug", $subr_name, $msg); + + $no_of_failed_mappings++; + $failed_cmds .=3D $cmd; $g_mapped_cmds{$cmd} =3D $cmd; } else { - gp_message ("debug", $subr_name, "path for the $cmd command is $= mapped"); + $msg =3D "path for the $cmd command is $mapped"; + gp_message ("debug", $subr_name, $msg); } } if ($no_of_failed_mappings !=3D 0) { - gp_message ("debug", $subr_name, "failed to find a mapping for $fail= ed_cmds"); - gp_message ("debug", $subr_name, "a total of $no_of_failed_mappings = mapping failures"); + my $plural_1 =3D ($no_of_failed_mappings > 1) ? "failures" : "fail= ure"; + my $plural_2 =3D ($no_of_failed_mappings > 1) ? "commands" : "comman= d"; + + $msg =3D "encountered $no_of_failed_mappings $plural_1 to locate"; + $msg .=3D " selected " . $plural_2; + gp_message ("warning", $subr_name, $msg); + gp_message ("debug", $subr_name, $msg); + + $msg =3D "execution continues, but may fail later on"; + gp_message ("warning", $subr_name, $msg); + gp_message ("debug", $subr_name, $msg); + + $g_total_warning_count++; } =20 return ($no_of_failed_mappings); @@ -1423,7 +1656,7 @@ sub check_and_proc_dis_branches my $msg; my $raw_hex_branch_target; =20 - if ( ($input_line =3D~ /$g_branch_regex/)=20 + if ( ($input_line =3D~ /$g_branch_regex/) or ($input_line =3D~ /$g_endbr_regex/)) { if (defined ($3)) @@ -1451,12 +1684,13 @@ sub check_and_proc_dis_branches #-------------------------------------------------------------------------= ----- $instruction_offset =3D $3; $raw_hex_branch_target =3D calculate_target_hex_address ( - $instruction_address,=20 - $instruction_offset);=20 + $instruction_address, + $instruction_offset); =20 $hex_branch_target =3D "0x" . $raw_hex_branch_target; $branch_target{$hex_branch_target} =3D 1; - $extended_branch_target{$instruction_address} =3D $raw_hex_b= ranch_target; + $extended_branch_target{$instruction_address} =3D + $raw_hex_branch_target; } if (defined ($2) and (not defined ($3))) { @@ -1482,7 +1716,8 @@ sub check_and_proc_dis_branches # TBD: Perhaps this should be an assertion or alike. #-------------------------------------------------------------------------= ----- $branch_target{"0x0000"} =3D $FALSE; - gp_message ("debug", $subr_name, "cannot determine branch target= "); + $msg =3D "cannot determine branch target"; + gp_message ("debug", $subr_name, $msg); } } else @@ -1512,11 +1747,11 @@ sub check_and_proc_dis_func_call my %extended_branch_target =3D %{ $extended_branch_target_ref }; =20 my $found_it =3D $TRUE; - my $hex_branch_target;=20 + my $hex_branch_target; my $instruction_address; my $instruction_offset; my $msg; - my $raw_hex_branch_target;=20 + my $raw_hex_branch_target; =20 if ( $input_line =3D~ /$g_function_call_v2_regex/ ) { @@ -1558,8 +1793,8 @@ sub check_and_proc_dis_func_call # address. #-------------------------------------------------------------------------= ----- $raw_hex_branch_target =3D calculate_target_hex_address ( - $instruction_address,=20 - $instruction_offset);=20 + $instruction_address, + $instruction_offset); $hex_branch_target =3D "0x" . $raw_hex_branch_target; =20 $msg =3D "calculated hex_branch_target =3D " . @@ -1567,12 +1802,13 @@ sub check_and_proc_dis_func_call gp_message ("debugXL", $subr_name, $msg); =20 $branch_target{$hex_branch_target} =3D 1; - $extended_branch_target{$instruction_address} =3D $raw_h= ex_branch_target; + $extended_branch_target{$instruction_address} =3D + $raw_hex_branch_target; =20 $msg =3D "set branch_target{$hex_branch_target} to 1"; gp_message ("debugXL", $subr_name, $msg); - $msg =3D "added extended_branch_target{$instruction_add= ress}" . - " =3D $extended_branch_target{$instruction_addre= ss}"; + $msg =3D "added extended_branch_target{$instruction_add= ress}"; + $msg .=3D " =3D $extended_branch_target{$instruction_add= ress}"; gp_message ("debugXL", $subr_name, $msg); } else @@ -1593,11 +1829,77 @@ sub check_and_proc_dis_func_call } #-- End of subroutine check_and_proc_dis_func_call =20 #-------------------------------------------------------------------------= ----- -# Check for the $GP_DISPLAY_TEXT tool to be available. This is a critical= tool=20 -# needed to provide the information. If it can not be found, execution is= =20 +# Check if the value for the user option given is valid. +# +# In case the value is valid, the g_user_settings table is updated with the +# (new) value. +# +# Otherwise an error message is pushed into the g_error_msgs buffer. +# +# The return value is TRUE/FALSE. +#-------------------------------------------------------------------------= ----- +sub check_and_set_user_option +{ + my $subr_name =3D get_my_name (); + + my ($internal_opt_name, $value) =3D @_; + + my $msg; + my $valid; + my $option_value_missing; + + my $option =3D $g_user_settings{$internal_opt_name}{"option"}; + my $data_type =3D $g_user_settings{$internal_opt_name}{"data_type"}; + my $no_of_args =3D $g_user_settings{$internal_opt_name}{"no_of_arguments= "}; +=20 + if (($no_of_args >=3D 1) and + ((not defined ($value)) or (length ($value) =3D=3D 0))) +#-------------------------------------------------------------------------= ----- +# If there was no value given, but it is required, flag an error. +# There could also be a value, but it might be the empty string. +# +# Note that that there are currently no options with multiple values. Sho= uld +# these be introduced, the current check may need to be refined. +#-------------------------------------------------------------------------= ----- + { + $valid =3D $FALSE; + $option_value_missing =3D $TRUE; + } + elsif ($no_of_args >=3D 1) + { + $option_value_missing =3D $FALSE; +#-------------------------------------------------------------------------= ----- +# There is an input value. Check if it is valid and if so, store it. +# +# Note that we allow the options to be case insensitive. +#-------------------------------------------------------------------------= ----- + $valid =3D verify_if_input_is_valid ($value, $data_type); + + if ($valid) + { + if (($data_type eq "onoff") or ($data_type eq "size")) + { + $g_user_settings{$internal_opt_name}{"current_value"} =3D + lc ($value); + } + else + { + $g_user_settings{$internal_opt_name}{"current_value"} =3D $v= alue; + } + $g_user_settings{$internal_opt_name}{"defined"} =3D $TRUE; + } + } + + return (\$valid, \$option_value_missing); + +} #-- End of subroutine check_and_set_user_option + +#-------------------------------------------------------------------------= ----- +# Check for the $GP_DISPLAY_TEXT tool to be available. This is a critical= tool +# needed to provide the information. If it can not be found, execution is # terminated. # -# We first search foe this tool in the current execution directory. If it +# We first search for this tool in the current execution directory. If it # cannot be found there, use $PATH to try to locate it. #-------------------------------------------------------------------------= ----- sub check_availability_tool @@ -1608,6 +1910,7 @@ sub check_availability_tool =20 my $error_code; my $error_occurred; + my $gp_path; my $msg; my $output_which_gp_display_text; my $return_value; @@ -1616,23 +1919,24 @@ sub check_availability_tool #-------------------------------------------------------------------------= ----- # Get the path to gp-display-text. #-------------------------------------------------------------------------= ----- - my ($error_occurred_ref, $return_value_ref) =3D find_path_to_gp_display_= text ( - $location_gp_comman= d_ref - ); - $error_occurred =3D ${ $error_occurred_ref}; =20 + my ($error_occurred_ref, $gp_path_ref, $return_value_ref) =3D + find_path_to_gp_display_text ($location_gp_command_ref); + + $error_occurred =3D ${ $error_occurred_ref}; + $gp_path =3D ${ $gp_path_ref }; $return_value =3D ${ $return_value_ref}; =20 $msg =3D "error_occurred =3D $error_occurred return_value =3D $return_va= lue"; gp_message ("debugXL", $subr_name, $msg); =20 - if (not $error_occurred)=20 + if (not $error_occurred) #-------------------------------------------------------------------------= ----- # All is well and gp-display-text has been located. #-------------------------------------------------------------------------= ----- { $g_path_to_tools =3D $return_value; =20 - $msg =3D "located $GP_DISPLAY_TEXT in execution directory"; + $msg =3D "located $GP_DISPLAY_TEXT in the execution directory"; gp_message ("debug", $subr_name, $msg); $msg =3D "g_path_to_tools =3D $g_path_to_tools"; gp_message ("debug", $subr_name, $msg); @@ -1643,42 +1947,49 @@ sub check_availability_tool # $GP_DISPLAY_TEXT through the search path. #-------------------------------------------------------------------------= ----- { - $msg =3D "error accessing $GP_DISPLAY_TEXT: $return_value - " . - "run time behaviour may be undefined"; + $msg =3D $g_html_new_line; + $msg .=3D "could not find $GP_DISPLAY_TEXT in directory $gp_path :"; + $msg .=3D " $return_value"; gp_message ("warning", $subr_name, $msg); - =20 + #-------------------------------------------------------------------------= ----- # Check if we can find $GP_DISPLAY_TEXT in the search path. #-------------------------------------------------------------------------= ----- - $msg =3D "check for $GP_DISPLAY_TEXT in search path"; + $msg =3D "check for $GP_DISPLAY_TEXT to be in the search path"; gp_message ("debug", $subr_name, $msg); =20 + gp_message ("warning", $subr_name, $msg); + $g_total_warning_count++; + $target_cmd =3D $g_mapped_cmds{"which"} . " $GP_DISPLAY_TEXT 2>&1"; =20 - ($error_code, $output_which_gp_display_text) =3D=20 - execute_system_cmd ($target= _cmd); - =20 + ($error_code, $output_which_gp_display_text) =3D + execute_system_cmd ($target_cmd); + if ($error_code =3D=3D 0) { - my ($gp_file_name, $gp_path, $suffix_not_used) =3D=20 + my ($gp_file_name, $gp_path, $suffix_not_used) =3D fileparse ($output_which_gp_display_t= ext); $g_path_to_tools =3D $gp_path; =20 - $msg =3D "using $GP_DISPLAY_TEXT in $g_path_to_tools instead"; + $msg =3D "located $GP_DISPLAY_TEXT in $g_path_to_tools"; + gp_message ("warning", $subr_name, $msg); + $msg =3D "this is the version that will be used"; gp_message ("warning", $subr_name, $msg); =20 $msg =3D "the $GP_DISPLAY_TEXT tool is in the search path"; gp_message ("debug", $subr_name, $msg); $msg =3D "g_path_to_tools =3D $g_path_to_tools"; gp_message ("debug", $subr_name, $msg); - }=20 + } else { $msg =3D "failure to find $GP_DISPLAY_TEXT in the search path"; - gp_message ("debug", $subr_name, $msg); + gp_message ("error", $subr_name, $msg); =20 - $msg =3D "fatal error executing command $target_cmd"; - gp_message ("abort", $subr_name, $msg); + $g_total_error_count++; + + gp_message ("abort", $subr_name, $g_abort_msg); } } =20 @@ -1690,7 +2001,7 @@ sub check_availability_tool # This function determines whether load objects are in ELF format. # # Compared to the original code, any input value other than 2 or 3 is reje= cted -# upfront. This not only reduces the nesting level, but also eliminates a= =20 +# upfront. This not only reduces the nesting level, but also eliminates a # possible bug. # # Also, by isolating the tests for the input files, another nesting level = could @@ -1702,17 +2013,23 @@ sub check_loadobjects_are_elf =20 my ($selected_archive) =3D @_; =20 + my $event_kind_map_regex; + $event_kind_map_regex =3D '^$'; + my $hostname_current =3D $local_system_config{"hostname_current"}; my $arch =3D $local_system_config{"processor"}; my $arch_uname_s =3D $local_system_config{"kernel_name"}; =20 - my $extracted_information;=20 + my $extracted_information; =20 my $elf_magic_number; =20 my $executable_name; my $va_executable_in_hex; -=20 + my $arch_exp; my $hostname_exp; my $os_exp; @@ -1722,19 +2039,21 @@ sub check_loadobjects_are_elf my $rc_b; my $file; my $line; + my $msg; my $name; my $name_path; my $foffset; my $vaddr; my $modes; =20 - my $path_to_map_file;=20 + my $path_to_map_file; my $path_to_log_file; =20 #-------------------------------------------------------------------------= ----- # TBD: Parameterize and should be the first experiment directory from the = list. #-------------------------------------------------------------------------= ----- - $path_to_log_file =3D $g_exp_dir_meta_data{$selected_archive}{"director= y_path"};=20 + $path_to_log_file =3D + $g_exp_dir_meta_data{$selected_archive}{"directory_path"}; $path_to_log_file .=3D $selected_archive; $path_to_log_file .=3D "/log.xml"; =20 @@ -1748,34 +2067,40 @@ sub check_loadobjects_are_elf # This check can probably be removed since the presence of the log.xml fil= e is # checked for in an earlier phase. #-------------------------------------------------------------------------= ----- + $msg =3D " - unable to open file $path_to_log_file for reading:"; open (LOG_XML, "<", $path_to_log_file) - or die ("$subr_name - unable to open file $path_to_log_file for readin= g: '$!'"); - gp_message ("debug", $subr_name, "opened file $path_to_log_file for read= ing"); - =20 + or die ($subr_name . $msg . " " . $!); + + $msg =3D "opened file $path_to_log_file for reading"; + gp_message ("debug", $subr_name, $msg); + while () { $line =3D $_; chomp ($line); - gp_message ("debug", $subr_name, "read line: $line"); + gp_message ("debugM", $subr_name, "read line: $line"); #-------------------------------------------------------------------------= ----- # Search for the first line starting with " -# +# #-------------------------------------------------------------------------= ----- if ($line =3D~ /^\s*