From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2041) id 746F3385736D; Mon, 25 Jul 2022 22:07:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 746F3385736D 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: fix bug 29356 - Execution fails if gprofng is not included in PATH X-Act-Checkin: binutils-gdb X-Git-Author: Ruud van der Pas X-Git-Refname: refs/heads/master X-Git-Oldrev: c69c2b6033a98d8fd28386ad92cada01dfd9b823 X-Git-Newrev: 91a5dd8e4acde7938ec8603673d47098070ccc35 Message-Id: <20220725220752.746F3385736D@sourceware.org> Date: Mon, 25 Jul 2022 22:07:52 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Jul 2022 22:07:52 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D91a5dd8e4acd= e7938ec8603673d47098070ccc35 commit 91a5dd8e4acde7938ec8603673d47098070ccc35 Author: Ruud van der Pas Date: Fri Jul 22 06:15:12 2022 -0700 gprofng: fix bug 29356 - Execution fails if gprofng is not included in = PATH =20 gprofng/Changelog: 2022-07-22 Ruud van der Pas =20 PR gprofng/29356 * gp-display-html/gp-display-html.in: fixed a problem to execute gp-display-text in case gprofng is not included in the search path. Diff: --- gprofng/gp-display-html/gp-display-html.in | 307 +++++++++++++++++++++++++= +--- 1 file changed, 284 insertions(+), 23 deletions(-) diff --git a/gprofng/gp-display-html/gp-display-html.in b/gprofng/gp-displa= y-html/gp-display-html.in index 774dbd537b3..ab21dbb0862 100644 --- a/gprofng/gp-display-html/gp-display-html.in +++ b/gprofng/gp-display-html/gp-display-html.in @@ -54,8 +54,16 @@ INIT my $TRUE =3D 1; my $FALSE =3D 0; =20 +#-------------------------------------------------------------------------= ----- +# Used to ensure correct alignment of columns. +#-------------------------------------------------------------------------= ----- my $g_max_length_first_metric; =20 +#-------------------------------------------------------------------------= ----- +# This variable contains the path used to execute $GP_DISPAY_TEXT. +#-------------------------------------------------------------------------= ----- +my $g_path_to_tools; + #-------------------------------------------------------------------------= ------ # Code debugging flag #-------------------------------------------------------------------------= ------ @@ -282,9 +290,16 @@ sub main #-------------------------------------------------------------------------= ----- # OS commands executed and search paths. #-------------------------------------------------------------------------= ----- - my @selected_os_cmds =3D qw (rm mv cat hostname locale which printenv ls= =20 + my @selected_os_cmds =3D qw (rm mv cat hostname locale which printenv ls uname readelf mkdir); - my @search_paths_os_cmds =3D qw (/usr/bin /bin); + my @search_paths_os_cmds =3D qw ( + /usr/bin + /bin + /usr/local/bin + /usr/local/sbin + /usr/sbin + /sbin + ); =20 #-------------------------------------------------------------------------= ----- # TBD: Eliminate these. @@ -410,6 +425,11 @@ sub main # things that are needed later on. #-------------------------------------------------------------------------= ----- =20 +#-------------------------------------------------------------------------= ----- +# Store the absolute path of the command executed. +#-------------------------------------------------------------------------= ----- + my $location_gp_command =3D $0; + #-------------------------------------------------------------------------= ----- # 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: @@ -695,10 +715,30 @@ sub main gp_message ("debug", $subr_name, "base_va_executable =3D $base_va_execut= able"); =20 #-------------------------------------------------------------------------= ----- -# The gp-display-text tool is critical and has to be available in order to= proceed. +# 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." #-------------------------------------------------------------------------= ----- - $ignore_value =3D check_availability_tool (); + $g_path_to_tools =3D ${ check_availability_tool (\$location_gp_command)}; + + $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"); + +#-------------------------------------------------------------------------= ----- +# Check if $GP_DISPLAY_TEXT is executable for user, group, and other. +# If not, print a warning only, since this may not be fatal but could +# potentially lead to issues later on. +#-------------------------------------------------------------------------= ----- + if (not is_file_executable ($GP_DISPLAY_TEXT)) + { + my $msg =3D "file $GP_DISPLAY_TEXT is not executable for user, group= , and other"; + gp_message ("warning", $subr_name, $msg); + } + +#-------------------------------------------------------------------------= ----- +# Find out what the decimal separator is, as set by the user. +#-------------------------------------------------------------------------= ----- ($return_code, $decimal_separator, $convert_to_dot) =3D=20 determine_decimal_separato= r (); =20 @@ -711,7 +751,7 @@ sub main } else { - my $msg =3D "the decimal separator can not be determined - set to $d= ecimal_separator"; + my $msg =3D "the decimal separator cannot be determined - set to $de= cimal_separator"; gp_message ("warning", $subr_name, $msg); } =20 @@ -1275,10 +1315,11 @@ sub calculate_target_hex_address } #-- End of subroutine calculate_target_hex_address =20 #-------------------------------------------------------------------------= ----- -# This subroutine sets the absolute path to all commands in array @cmds. = The -# commands and their respective paths are stored in hash "g_mapped_cmds". +# Sets the absolute path to all commands in array @cmds. The commands and= =20 +# their respective paths are stored in hash "g_mapped_cmds". # -# It is a fatal error if such a path can't be found. +# 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. #-------------------------------------------------------------------------= ----- sub check_and_define_cmds { @@ -1311,7 +1352,7 @@ sub check_and_define_cmds $found_match =3D $FALSE; for my $path (@search_path) { - $target_cmd =3D $path."/".$cmd;=20 + $target_cmd =3D $path . "/" . $cmd;=20 if (-x $target_cmd) { $found_match =3D $TRUE; @@ -1335,9 +1376,12 @@ sub check_and_define_cmds { if ($mapped eq "road_to_nowhere") { - gp_message ("error", $subr_name, "cannot find a path for command= $cmd"); + my $msg =3D "cannot find a path for command $cmd - " . + "assume this will still work without a path"; + gp_message ("warning", $subr_name, $msg); $no_of_failed_mappings++;=20 $failed_cmds .=3D $cmd;=20 + $g_mapped_cmds{$cmd} =3D $cmd; } else { @@ -1346,8 +1390,8 @@ sub check_and_define_cmds } if ($no_of_failed_mappings !=3D 0) { - gp_message ("error", $subr_name, "failed to find a mapping for $fail= ed_cmds"); - gp_message ("error", $subr_name, "a total of $no_of_failed_mappings = mapping failures"); + 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"); } =20 return ($no_of_failed_mappings); @@ -1552,29 +1596,93 @@ sub check_and_proc_dis_func_call # 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 # terminated. +# +# We first search foe this tool in the current execution directory. If it +# cannot be found there, use $PATH to try to locate it. #-------------------------------------------------------------------------= ----- sub check_availability_tool { my $subr_name =3D get_my_name (); =20 - my $target_cmd; - my $output_which_gp_display_text; + my ($location_gp_command_ref) =3D @_; + my $error_code; + my $error_occurred; + my $msg; + my $output_which_gp_display_text; + my $return_value; + my $target_cmd; =20 - $target_cmd =3D $g_mapped_cmds{"which"} . " $GP_DISPLAY_TEXT 2>&1"; +#-------------------------------------------------------------------------= ----- +# 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 + $return_value =3D ${ $return_value_ref}; =20 - ($error_code, $output_which_gp_display_text) =3D execute_system_cmd ($ta= rget_cmd); - =20 - if ($error_code =3D=3D 0) + $msg =3D "error_occurred =3D $error_occurred return_value =3D $return_va= lue"; + gp_message ("debugXL", $subr_name, $msg); + + if (not $error_occurred)=20 +#-------------------------------------------------------------------------= ----- +# All is well and gp-display-text has been located. +#-------------------------------------------------------------------------= ----- { - gp_message ("debug", $subr_name, "tool $GP_DISPLAY_TEXT is in the se= arch path"); - }=20 + $g_path_to_tools =3D $return_value; + + $msg =3D "located $GP_DISPLAY_TEXT in 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); + } else +#-------------------------------------------------------------------------= ----- +# Something went wrong, but perhaps we can still continue. Try to find +# $GP_DISPLAY_TEXT through the search path. +#-------------------------------------------------------------------------= ----- { - gp_message ("abort", $subr_name, "fatal error executing command $tar= get_cmd"); - } + $msg =3D "error accessing $GP_DISPLAY_TEXT: $return_value - " . + "run time behaviour may be undefined"; + 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"; + gp_message ("debug", $subr_name, $msg); =20 - return (0); + $target_cmd =3D $g_mapped_cmds{"which"} . " $GP_DISPLAY_TEXT 2>&1"; + + ($error_code, $output_which_gp_display_text) =3D=20 + execute_system_cmd ($target= _cmd); + =20 + if ($error_code =3D=3D 0) + { + my ($gp_file_name, $gp_path, $suffix_not_used) =3D=20 + fileparse ($output_which_gp_display_t= ext); + $g_path_to_tools =3D $gp_path; + + $msg =3D "using $GP_DISPLAY_TEXT in $g_path_to_tools instead"; + gp_message ("warning", $subr_name, $msg); + + $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); + + $msg =3D "fatal error executing command $target_cmd"; + gp_message ("abort", $subr_name, $msg); + } + } + + return (\$g_path_to_tools); =20 } #-- End of subroutine check_availability_tool =20 @@ -3874,6 +3982,58 @@ sub find_keyword_in_string =20 } #-- End of subroutine find_keyword_in_string =20 +#-------------------------------------------------------------------------= ----- +# Retrieve the absolute path that was used to execute the command. This p= ath +# is used to execute gp-display-text later on. +#-------------------------------------------------------------------------= ----- +sub find_path_to_gp_display_text +{ + my $subr_name =3D get_my_name (); + + my ($full_command_ref) =3D @_; + + my $full_command =3D ${ $full_command_ref }; + + my $error_occurred =3D $TRUE; + my $return_value; + +#-------------------------------------------------------------------------= ----- +# Get the path name. +#-------------------------------------------------------------------------= ----- + my ($gp_file_name, $gp_path, $suffix_not_used) =3D fileparse ($full_comm= and); + + gp_message ("debug", $subr_name, "full_command =3D $full_command"); + gp_message ("debug", $subr_name, "gp_path =3D $gp_path"); + + my $gp_display_text_instance =3D $gp_path . $GP_DISPLAY_TEXT; + +#-------------------------------------------------------------------------= ----- +# Check if $GP_DISPLAY_TEXT exists, is not empty, and executable. +#-------------------------------------------------------------------------= ----- + if (not -e $gp_display_text_instance) + { + $return_value =3D "file not found"; + } + else + { + if (is_file_empty ($gp_display_text_instance)) + { + $return_value =3D "file is empty"; + } + else + { +#-------------------------------------------------------------------------= ----- +# All is well. Capture the path. +#-------------------------------------------------------------------------= ----- + $error_occurred =3D $FALSE; + $return_value =3D $gp_path; + } + } + + return (\$error_occurred, \$return_value); + +} #-- End of subroutine find_path_to_gp_display_text + #-------------------------------------------------------------------------= ----- # Scan the command line to see if the specified option is present. # @@ -9272,6 +9432,107 @@ sub is_file_empty =20 } #-- End of subroutine is_file_empty =20 +#-------------------------------------------------------------------------= ----- +# Check if a file is executable and return $TRUE or $FALSE. +#-------------------------------------------------------------------------= ----- +sub is_file_executable +{ + my $subr_name =3D get_my_name (); + + my ($filename) =3D @_; + + my $file_permissions; + my $index_offset; + my $is_executable; + my $mode; + my $number_of_bytes;=20 + my @permission_settings =3D (); + my %permission_values =3D (); + + chomp ($filename); + + gp_message ("debug", $subr_name, "check if filename =3D $filename is exe= cutable"); + + if (not -e $filename) + { +#-------------------------------------------------------------------------= ----- +# The return value is used in the caller. This is why we return the empty +# string in case the file does not exist. +#-------------------------------------------------------------------------= ----- + gp_message ("debug", $subr_name, "filename =3D $filename not found"); + $is_executable =3D $FALSE; + } + else + { + $mode =3D stat ($filename)->mode; + + gp_message ("debugXL", $subr_name, "mode =3D $mode"); +#-------------------------------------------------------------------------= ----- +# Get username. We currently do not do anything with this though and the +# code is commented out. +# +# my $my_name =3D getlogin () || getpwuid($<) || "Kilroy";; +# gp_message ("debug", $subr_name, "my_name =3D $my_name"); +#-------------------------------------------------------------------------= ----- + +#-------------------------------------------------------------------------= ----- +# Convert file permissions to octal, split the individual numbers and store +# the values for the respective users. +#-------------------------------------------------------------------------= ----- + $file_permissions =3D sprintf("%o", $mode & 07777); + + @permission_settings =3D split (//, $file_permissions); + + $number_of_bytes =3D scalar (@permission_settings); + + gp_message ("debugXL", $subr_name, "file_permissions =3D $file_permi= ssions"); + gp_message ("debugXL", $subr_name, "permission_settings =3D @permiss= ion_settings"); + gp_message ("debugXL", $subr_name, "number_of_settings =3D $number_o= f_bytes"); + + if ($number_of_bytes =3D=3D 4) + { + $index_offset =3D 1; + } + elsif ($number_of_bytes =3D=3D 3) + { + $index_offset =3D 0; + } + else + { + my $msg =3D "unexpected number of $number_of_bytes bytes " . + "in permission settings: @permission_settings"; + gp_message ("assertion", $subr_name, $msg); + } + + $permission_values{user} =3D $permission_settings[$index_offset++]; + $permission_values{group} =3D $permission_settings[$index_offset++]; + $permission_values{other} =3D $permission_settings[$index_offset]; + +#-------------------------------------------------------------------------= ----- +# The executable bit should be set for user, group and other. If this fai= ls +# we mark the file as not executable. Note that this is gprofng specific. +#-------------------------------------------------------------------------= ----- + $is_executable =3D $TRUE; + for my $k (keys %permission_values) + { + my $msg =3D "permission_values{" . $k . "} =3D " . + $permission_values{$k}; + gp_message ("debugXL", $subr_name, $msg); + =20 + if ($permission_values{$k} % 2 =3D=3D 0) + { + $is_executable =3D $FALSE; + last; + } + } + } + + gp_message ("debug", $subr_name, "is_executable =3D $is_executable"); + + return ($is_executable); + +} #-- End of subroutine is_file_executable + #-------------------------------------------------------------------------= ------ # TBD. #-------------------------------------------------------------------------= ------