From 02cd7a14b2ac93686dd87d540ae1fcf637d64e42 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 31 Jan 2022 16:17:18 -0600 Subject: [PATCH 1/4] maint: fix extracterrmsgs We have been manually setting MPI error class index in src/mpi/errhan/baseerrnames.txt, and it has been out-of-sync with the values defined in mpi.h. This commit does following: * Remove the index from baseerrnames.txt and directly load the defined value from mpi.h instead. * Add UNKNOWN entry to map the missing entries in baseerrnames.txt. * When autogen.sh fails to extract error messages, do not generate dummy defmsg.h, fail instead. The dummy header will break the error class message translation anyway. --- autogen.sh | 21 +----- maint/extracterrmsgs | 114 ++++++++++++++++++----------- src/mpi/errhan/baseerrnames.txt | 126 ++++++++++++++++---------------- 3 files changed, 138 insertions(+), 123 deletions(-) diff --git a/autogen.sh b/autogen.sh index e3fe410b9de..55e05143f0d 100755 --- a/autogen.sh +++ b/autogen.sh @@ -401,25 +401,8 @@ fn_errmsgs() { mv .tmp src/mpi/errhan/defmsg.h fi if [ ! -s src/mpi/errhan/defmsg.h ] ; then - echo_n "Creating a dummy defmsg.h file... " - cat > src/mpi/errhan/defmsg.h < MPICH_ERROR_MSG__NONE -#define MPIR_MAX_ERROR_CLASS_INDEX 54 -static int class_to_index[] = { -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0 }; -#endif -EOF - echo "done" + error "Unable to extract error messages" + exit 1 fi } diff --git a/maint/extracterrmsgs b/maint/extracterrmsgs index 5dbc8e7ee4f..d4e842e3baa 100755 --- a/maint/extracterrmsgs +++ b/maint/extracterrmsgs @@ -45,8 +45,10 @@ foreach my $k ("envvarparse", "cvar_val"){ } # Check for special args -@files = (); -%skipFiles = (); +my $mpi_h = "src/include/mpi.h.in"; +my $baseerrnames_txt = "src/mpi/errhan/baseerrnames.txt"; +my @files = (); +my %skipFiles = (); my @errnameFiles = (); $outfile = ""; foreach $arg (@ARGV) { @@ -113,6 +115,30 @@ if ($build_test_pgm && -d "test/mpi/errhan") { print TESTFD "{\n int err;\n MPI_Init( 0, 0 );\n"; } +# Load mpi.h for error class constants +my %mpi_h_constants; +$mpi_h_constants{"MPI_SUCCESS"} = 0; +if (open In, $mpi_h) { + while () { + if (/^#define\s+((MPICH|MPI|MPI_T|MPIX)_ERR_\w+)\s+(.+)/) { + my ($key, $t) = ($1, $3); + if ($t=~/^(\d+)/) { + $mpi_h_constants{$key} = $1; + } elsif ($t=~/MPICH_ERR_FIRST_MPIX\s*\+\s*(\d+)/) { + $mpi_h_constants{$key} = $mpi_h_constants{MPICH_ERR_FIRST_MPIX} + $1; + } + } + } + close In; +} else { + die "Unable to read $mpi_h\n"; +} + +my $max_err_class = $mpi_h_constants{MPICH_ERR_LAST_MPIX}; +if (!$max_err_class) { + die "Failed to load MPICH_ERR_LAST_MPIX from $mpi_h\n"; +} + # Process the definitions foreach $file (@files) { print "$file\n" if $showfiles; @@ -127,6 +153,28 @@ foreach my $sourcefile (@errnameFiles) { &ReadErrnamesFile( $sourcefile ); } +# Load baseerrnames.txt +my @class_msgs; +if (open In, $baseerrnames_txt) { + while () { + if (/^(MPI\w+)\s+(\*\*\w+)/) { + my ($name, $shortmsg) = ($1, $2, $3); + my $id = $mpi_h_constants{$name}; + if (defined $id) { + $generic_msgs{$shortmsg}++; + $generic_loc{$shortmsg} = ":baseerrnames.txt"; + $class_msgs[$id] = $shortmsg; + } else { + die "error class $name not found in mpi.h\n"; + } + } + } + close In; +} else { + die "Unable to read $baseerrnames_txt\n"; +} + + # Create the output files from the input that we've read &CreateErrmsgsHeader( $OUTFD ); &CreateErrMsgMapping( $OUTFD ); @@ -193,46 +241,15 @@ typedef struct msgpair { sub CreateErrMsgMapping { my $OUTFD = $_[0]; - # Create a mapping of MPI error classes to the specific error - # message by index into generic_err_msgs. This reads the file - # baseerrnames, looks up the generic message, and maps the MPI error - # class to the corresponding index. - # We must do this here because we must ensure that all MPI error - # classes have been added to the generic messages - @class_msgs = (); - open (FD, "<$rootdir/src/mpi/errhan/baseerrnames.txt" ) || - die "Could not open $rootdir/src/mpi/errhan/baseerrnames.txt\n"; - while () { - s/#.*$//; - my ($mpiname,$num,$shortmsg) = split(/\s\s*/); - if (!defined($shortmsg)) { - # In case there is no short message entry (!) - $shortmsg = ""; - } - if ($shortmsg ne "") - { - if ($shortmsg =~ /\%/) - { - print STDERR "Warning: generic message $shortmsg in baseerrnames.txt contains format control\n"; - } - - $generic_msgs{$shortmsg}++; - $generic_loc{$shortmsg} = ":baseerrnames.txt"; - - $class_msgs[$num] = "$shortmsg"; - } - } - close (FD); - # For the case of classes only, output the strings for the class # messages print $OUTFD "#if MPICH_ERROR_MSG_LEVEL == MPICH_ERROR_MSG__CLASS\n"; print $OUTFD "#define MPIR_MAX_ERROR_CLASS_INDEX $#class_msgs+1\n"; print $OUTFD "static const char *classToMsg[] = {\n"; - for (my $i=0; $i<=$#class_msgs; $i++) { + for (my $i=0; $i<=$max_err_class; $i++) { my $shortname = $class_msgs[$i]; - my $msg = $longnames{$shortname}; - print $OUTFD "\"$msg\", /* $i $class_msgs[$i] */\n"; + my $msg = $longnames{$shortname}; + print $OUTFD "\"$msg\", /* $i $class_msgs[$i] */\n"; } print $OUTFD "0 }; \n"; print $OUTFD "#endif /* MSG_CLASS */\n"; @@ -246,8 +263,18 @@ sub CreateErrMsgMapping { print $OUTFD "/* The names are in sorted order, allowing the use of a simple\ linear search or bisection algorithm to find the message corresponding to\ a particular message */\n"; + my @sorted_generic_msgs = sort keys %generic_msgs; + + # add a dummy UNKNOWN entry in the front. + # NOTE: assume all other generic message are lowercase so "UNKNOWN" will + # be ordered first. This is critical because FindGenericMsgIndex assumes + # this ordering! + unshift @sorted_generic_msgs, "**UNKNOWN"; + $generic_loc{"**UNKNOWN"} = ":[NONE]"; + $longnames{"**UNKNOWN"} = "Unknown error class"; + my $num = 0; - foreach my $key (sort keys %generic_msgs) + foreach my $key (@sorted_generic_msgs) { $longvalue = "\"\0\""; if (!defined($longnames{$key})) @@ -333,12 +360,17 @@ sub CreateErrMsgMapping { print $OUTFD "#endif\n\n"; print $OUTFD "#if MPICH_ERROR_MSG_LEVEL > MPICH_ERROR_MSG__CLASS\n"; - $maxval = $#class_msgs + 1; + $maxval = $max_err_class + 1; print $OUTFD "#define MPIR_MAX_ERROR_CLASS_INDEX $maxval\n"; print $OUTFD "static int class_to_index[] = {\n"; - for (my $i=0; $i<=$#class_msgs; $i++) { - print $OUTFD "$short_to_num{$class_msgs[$i]}"; - print $OUTFD "," if ($i < $#class_msgs); + for (my $i=0; $i<=$max_err_class; $i++) { + my $idx = $short_to_num{$class_msgs[$i]}; + if (!$idx) { + # 0 is the "**UNKNOWN" entry + $idx = 0; + } + print $OUTFD "$idx"; + print $OUTFD "," if ($i < $max_err_class); print $OUTFD "\n" if !(($i + 1) % 10); } print $OUTFD "};\n"; diff --git a/src/mpi/errhan/baseerrnames.txt b/src/mpi/errhan/baseerrnames.txt index e2e3afe131e..9da37597f11 100644 --- a/src/mpi/errhan/baseerrnames.txt +++ b/src/mpi/errhan/baseerrnames.txt @@ -10,75 +10,75 @@ # mpi_err_xxx integer-value short-name # where "integer-value" is the same as in mpi.h (eventually, we should # generate this automatically). -MPI_SUCCESS 0 **success +MPI_SUCCESS **success # Communication argument parameters -MPI_ERR_BUFFER 1 **buffer -MPI_ERR_COUNT 2 **count -MPI_ERR_TYPE 3 **dtype -MPI_ERR_TAG 4 **tag -MPI_ERR_COMM 5 **comm -MPI_ERR_RANK 6 **rank -MPI_ERR_ROOT 7 **root -MPI_ERR_TRUNCATE 14 **truncate +MPI_ERR_BUFFER **buffer +MPI_ERR_COUNT **count +MPI_ERR_TYPE **dtype +MPI_ERR_TAG **tag +MPI_ERR_COMM **comm +MPI_ERR_RANK **rank +MPI_ERR_ROOT **root +MPI_ERR_TRUNCATE **truncate # MPI Objects (other than COMM) -MPI_ERR_GROUP 8 **group -MPI_ERR_OP 9 **op -MPI_ERR_REQUEST 19 **request +MPI_ERR_GROUP **group +MPI_ERR_OP **op +MPI_ERR_REQUEST **request # Special topology argument parameters -MPI_ERR_TOPOLOGY 10 **topology -MPI_ERR_DIMS 11 **dims +MPI_ERR_TOPOLOGY **topology +MPI_ERR_DIMS **dims # All other arguments. This is a class with many kinds -MPI_ERR_ARG 12 **arg +MPI_ERR_ARG **arg # Other errors that are not simply an invalid argument -MPI_ERR_OTHER 15 **other -MPI_ERR_UNKNOWN 13 **unknown -MPI_ERR_INTERN 16 **intern +MPI_ERR_OTHER **other +MPI_ERR_UNKNOWN **unknown +MPI_ERR_INTERN **intern # Multiple completion has two special error classes -MPI_ERR_IN_STATUS 17 **instatus -MPI_ERR_PENDING 18 **pending -MPIX_ERR_PROC_FAILED_PENDING 19 **failure_pending +MPI_ERR_IN_STATUS **instatus +MPI_ERR_PENDING **pending +MPIX_ERR_PROC_FAILED_PENDING **failure_pending # New MPI-2 Error classes -MPI_ERR_FILE 27 **file -MPI_ERR_ACCESS 20 **fileaccess -MPI_ERR_AMODE 21 **fileamode -MPI_ERR_BAD_FILE 22 **filename -MPI_ERR_FILE_EXISTS 25 **fileexist -MPI_ERR_FILE_IN_USE 26 **fileinuse -MPI_ERR_NO_SPACE 36 **filenospace -MPI_ERR_NO_SUCH_FILE 37 **filenoexist -MPI_ERR_IO 32 **io -MPI_ERR_READ_ONLY 40 **filerdonly -MPI_ERR_CONVERSION 23 **conversion -MPI_ERR_DUP_DATAREP 24 **datarepused -MPI_ERR_UNSUPPORTED_DATAREP 43 **datarepunsupported +MPI_ERR_FILE **file +MPI_ERR_ACCESS **fileaccess +MPI_ERR_AMODE **fileamode +MPI_ERR_BAD_FILE **filename +MPI_ERR_FILE_EXISTS **fileexist +MPI_ERR_FILE_IN_USE **fileinuse +MPI_ERR_NO_SPACE **filenospace +MPI_ERR_NO_SUCH_FILE **filenoexist +MPI_ERR_IO **io +MPI_ERR_READ_ONLY **filerdonly +MPI_ERR_CONVERSION **conversion +MPI_ERR_DUP_DATAREP **datarepused +MPI_ERR_UNSUPPORTED_DATAREP **datarepunsupported # MPI_ERR_INFO is NOT defined in the MPI-2 standard. I believe that # this is an oversight -MPI_ERR_INFO 28 **info -MPI_ERR_INFO_KEY 29 **infokey -MPI_ERR_INFO_VALUE 30 **infoval -MPI_ERR_INFO_NOKEY 31 **infonokey -MPI_ERR_NAME 33 **nameservice -MPI_ERR_NO_MEM 34 **allocmem -MPI_ERR_NOT_SAME 35 **notsame -MPI_ERR_PORT 38 **port -MPI_ERR_QUOTA 39 **filequota -MPI_ERR_SERVICE 41 **servicename -MPI_ERR_SPAWN 42 **spawn -MPI_ERR_UNSUPPORTED_OPERATION 44 **fileopunsupported -MPI_ERR_WIN 45 **win -MPI_ERR_BASE 46 **base -MPI_ERR_LOCKTYPE 47 **locktype -MPI_ERR_KEYVAL 48 **keyval -MPI_ERR_RMA_CONFLICT 49 **rmaconflict -MPI_ERR_RMA_SYNC 50 **rmasync -MPI_ERR_SIZE 51 **rmasize -MPI_ERR_DISP 52 **rmadisp -MPI_ERR_ASSERT 53 **assert -MPIX_ERR_PROC_FAILED 54 **proc_failed -MPI_ERR_RMA_RANGE 55 **rmarange -MPI_ERR_RMA_ATTACH 56 **rmaattach -MPI_ERR_RMA_SHARED 57 **rmashared -MPI_ERR_RMA_FLAVOR 58 **rmaflavor -MPIX_ERR_REVOKED 59 **revoked -MPIX_ERR_EAGAIN 60 **eagain -MPIX_ERR_NOREQ 61 **nomemreq +MPI_ERR_INFO **info +MPI_ERR_INFO_KEY **infokey +MPI_ERR_INFO_VALUE **infoval +MPI_ERR_INFO_NOKEY **infonokey +MPI_ERR_NAME **nameservice +MPI_ERR_NO_MEM **allocmem +MPI_ERR_NOT_SAME **notsame +MPI_ERR_PORT **port +MPI_ERR_QUOTA **filequota +MPI_ERR_SERVICE **servicename +MPI_ERR_SPAWN **spawn +MPI_ERR_UNSUPPORTED_OPERATION **fileopunsupported +MPI_ERR_WIN **win +MPI_ERR_BASE **base +MPI_ERR_LOCKTYPE **locktype +MPI_ERR_KEYVAL **keyval +MPI_ERR_RMA_CONFLICT **rmaconflict +MPI_ERR_RMA_SYNC **rmasync +MPI_ERR_SIZE **rmasize +MPI_ERR_DISP **rmadisp +MPI_ERR_ASSERT **assert +MPIX_ERR_PROC_FAILED **proc_failed +MPI_ERR_RMA_RANGE **rmarange +MPI_ERR_RMA_ATTACH **rmaattach +MPI_ERR_RMA_SHARED **rmashared +MPI_ERR_RMA_FLAVOR **rmaflavor +MPIX_ERR_REVOKED **revoked +MPIX_ERR_EAGAIN **eagain +MPIX_ERR_NOREQ **nomemreq From 91ee6883e2198abb3a401a2ff37c7848559264c4 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 31 Jan 2022 18:30:13 -0600 Subject: [PATCH 2/4] maint: indent the generated defmsg.h Add some indentation to the generated src/mpi/errhan/defmsg.h. --- maint/extracterrmsgs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/maint/extracterrmsgs b/maint/extracterrmsgs index d4e842e3baa..13272e5d7d9 100755 --- a/maint/extracterrmsgs +++ b/maint/extracterrmsgs @@ -249,9 +249,9 @@ sub CreateErrMsgMapping { for (my $i=0; $i<=$max_err_class; $i++) { my $shortname = $class_msgs[$i]; my $msg = $longnames{$shortname}; - print $OUTFD "\"$msg\", /* $i $class_msgs[$i] */\n"; + print $OUTFD " \"$msg\", /* $i $class_msgs[$i] */\n"; } - print $OUTFD "0 }; \n"; + print $OUTFD " NULL\n};\n"; print $OUTFD "#endif /* MSG_CLASS */\n"; # Now, output each short,long key @@ -314,7 +314,7 @@ sub CreateErrMsgMapping { my $sentinal2 = "0xcb0bfa11"; print $OUTFD "static const msgpair generic_err_msgs[] = {\n"; for (my $i = 0; $i < $num; $i ++) { - print $OUTFD "{ $sentinal1, short_gen$i, long_gen$i, $sentinal2 }"; + print $OUTFD " { $sentinal1, short_gen$i, long_gen$i, $sentinal2 }"; print $OUTFD "," if ($i < $num - 1); print $OUTFD "\n"; } @@ -352,7 +352,7 @@ sub CreateErrMsgMapping { print $OUTFD "\nstatic const int specific_msgs_len = $num;\n"; print $OUTFD "static const msgpair specific_err_msgs[] = {\n"; for (my $i = 0; $i < $num ; $i ++) { - print $OUTFD "{ $sentinal1, short_spc$i, long_spc$i, $sentinal2 }"; + print $OUTFD " { $sentinal1, short_spc$i, long_spc$i, $sentinal2 }"; print $OUTFD "," if ($i < $num - 1); print $OUTFD "\n"; } @@ -362,7 +362,7 @@ sub CreateErrMsgMapping { print $OUTFD "#if MPICH_ERROR_MSG_LEVEL > MPICH_ERROR_MSG__CLASS\n"; $maxval = $max_err_class + 1; print $OUTFD "#define MPIR_MAX_ERROR_CLASS_INDEX $maxval\n"; - print $OUTFD "static int class_to_index[] = {\n"; + print $OUTFD "static int class_to_index[] = {\n "; for (my $i=0; $i<=$max_err_class; $i++) { my $idx = $short_to_num{$class_msgs[$i]}; if (!$idx) { @@ -371,9 +371,9 @@ sub CreateErrMsgMapping { } print $OUTFD "$idx"; print $OUTFD "," if ($i < $max_err_class); - print $OUTFD "\n" if !(($i + 1) % 10); + print $OUTFD "\n " if !(($i + 1) % 10); } - print $OUTFD "};\n"; + print $OUTFD "\n};\n"; print $OUTFD "#endif\n"; } # From 4d1dca697c1c15da4ab7363ef1b40e25d103a4f6 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Mon, 31 Jan 2022 18:21:49 -0600 Subject: [PATCH 3/4] maint: optimize extracterrmsgs Re-initializing %KnownErrRoutines for every line of the source code is waste of time. Just load once can make the script run much faster -- from 3 seconds to a fraction of a second. --- maint/extracterrmsgs | 146 +++++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 67 deletions(-) diff --git a/maint/extracterrmsgs b/maint/extracterrmsgs index 13272e5d7d9..b45c6d4c828 100755 --- a/maint/extracterrmsgs +++ b/maint/extracterrmsgs @@ -652,8 +652,14 @@ sub ReadErrnamesFile { # The last two are used to provide better error reporting. # $filename = ""; # Make global so that other routines can echo filename +%KnownErrRoutines; + sub ProcessFile { + if (!%KnownErrRoutines) { + load_KnownErrRoutines(); + } + # Leave filename global for AddTest $filename = $_[0]; my $linecount = 0; @@ -676,74 +682,13 @@ sub ProcessFile $_ = StripComments( FD, $_ ); # Skip the definition of the function if (/int\s+MPI[OUR]_Err_create_code/) { $remainder = ""; next; } - # Match the known routines and macros. - # Then check that the arguments match if there is a - # specific string (number of args matches the number present) - # MPIR_ERR_CHK(FATAL)?ANDJUMP[1-4]?(cond,code,class,gmsg[,smsg,args]) - # MPIR_ERR_SET(FATAL)?ANDJUMP[1-4]?(code,class,gmsg[,smsg,args]) - # MPIR_ERR_CHK(FATAL)?ANDSTMT[1-4]?(cond,code,class,stmt,gmsg[,smsg,args]) - # MPIR_ERR_SET(FATAL)?ANDSTMT[1-4]?(code,class,stmt,gmsg[,smsg,args]) - # Value is a tuple of: - # the count of args where the generic msg begins (starting from 0) - # location of __LINE__ (-1 for none) - # specific msg arg required (0 for no, > 0 for yes) - # is the generic message an indirect from errnames.txt (1=yes 0=no) - # location of the error class - %KnownErrRoutines = ( 'MPIR_Err_create_code' => '5:3:1:1:4', - 'MPIO_Err_create_code' => '5:3:1:0:-1', - 'MPIR_ERR_SET' => '2:-1:0:1:1', - 'MPIR_ERR_SETSIMPLE' => '2:-1:0:1:1', - 'MPIR_ERR_SET1' => '2:-1:1:1:1', - 'MPIR_ERR_SET2' => '2:-1:2:1:1', - 'MPIR_ERR_SETANDSTMT' => '3:-1:0:1:1', - 'MPIR_ERR_SETANDSTMT1' => '3:-1:1:1:1', - 'MPIR_ERR_SETANDSTMT2' => '3:-1:1:1:1', - 'MPIR_ERR_SETANDSTMT3' => '3:-1:1:1:1', - 'MPIR_ERR_SETANDSTMT4' => '3:-1:1:1:1', - 'MPIR_ERR_SETANDJUMP' => '2:-1:0:1:1', - 'MPIR_ERR_SETANDJUMP1' => '2:-1:1:1:1', - 'MPIR_ERR_SETANDJUMP2' => '2:-1:1:1:1', - 'MPIR_ERR_SETANDJUMP3' => '2:-1:1:1:1', - 'MPIR_ERR_SETANDJUMP4' => '2:-1:1:1:1', - 'MPIR_ERR_CHKANDSTMT' => '4:-1:0:1:2', - 'MPIR_ERR_CHKANDSTMT1' => '4:-1:1:1:2', - 'MPIR_ERR_CHKANDSTMT2' => '4:-1:1:1:2', - 'MPIR_ERR_CHKANDSTMT3' => '4:-1:1:1:2', - 'MPIR_ERR_CHKANDSTMT4' => '4:-1:1:1:2', - 'MPIR_ERR_CHKANDJUMP' => '3:-1:0:1:2', - 'MPIR_ERR_CHKANDJUMP1' => '3:-1:1:1:2', - 'MPIR_ERR_CHKANDJUMP2' => '3:-1:1:1:2', - 'MPIR_ERR_CHKANDJUMP3' => '3:-1:1:1:2', - 'MPIR_ERR_CHKANDJUMP4' => '3:-1:1:1:2', - 'MPIR_ERR_SETFATAL' => '2:-1:0:1:1', - 'MPIR_ERR_SETFATALSIMPLE' => '2:-1:0:1:1', - 'MPIR_ERR_SETFATAL1' => '2:-1:1:1:1', - 'MPIR_ERR_SETFATAL2' => '2:-1:2:1:1', - 'MPIR_ERR_SETFATALANDSTMT' => '3:-1:0:1:1', - 'MPIR_ERR_SETFATALANDSTMT1' => '3:-1:1:1:1', - 'MPIR_ERR_SETFATALANDSTMT2' => '3:-1:1:1:1', - 'MPIR_ERR_SETFATALANDSTMT3' => '3:-1:1:1:1', - 'MPIR_ERR_SETFATALANDSTMT4' => '3:-1:1:1:1', - 'MPIR_ERR_SETFATALANDJUMP' => '2:-1:0:1:1', - 'MPIR_ERR_SETFATALANDJUMP1' => '2:-1:1:1:1', - 'MPIR_ERR_SETFATALANDJUMP2' => '2:-1:1:1:1', - 'MPIR_ERR_SETFATALANDJUMP3' => '2:-1:1:1:1', - 'MPIR_ERR_SETFATALANDJUMP4' => '2:-1:1:1:1', - 'MPIR_ERR_CHKFATALANDSTMT' => '4:-1:0:1:2', - 'MPIR_ERR_CHKFATALANDSTMT1' => '4:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDSTMT2' => '4:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDSTMT3' => '4:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDSTMT4' => '4:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDJUMP' => '3:-1:0:1:2', - 'MPIR_ERR_CHKFATALANDJUMP1' => '3:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDJUMP2' => '3:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDJUMP3' => '3:-1:1:1:2', - 'MPIR_ERR_CHKFATALANDJUMP4' => '3:-1:1:1:2', - 'MPIR_ERRTEST_VALID_HANDLE' => '4:-1:0:1:3', - ); - while (/(MPI[OUR]_E[A-Za-z0-9_]+)\s*(\(.*)$/) { + while (/(MPI[OUR]_Err[A-Za-z0-9_]+)\s*(\(.*)$/i) { my $routineName = $1; my $arglist = $2; + if ($routineName =~ /MPIR_ERR_(CHECK|POP|ADD|GET_CLASS|COLL_CHECKANDCONT|is_fatal)/i) { + # skip known false positives + next; + } if (!defined($KnownErrRoutines{$routineName})) { print "Skipping $routineName\n" if $debug; last; @@ -943,7 +888,74 @@ sub ExpandDir { return @files; } - +sub load_KnownErrRoutines { + # Match the known routines and macros. + # Then check that the arguments match if there is a + # specific string (number of args matches the number present) + # MPIR_ERR_CHK(FATAL)?ANDJUMP[1-4]?(cond,code,class,gmsg[,smsg,args]) + # MPIR_ERR_SET(FATAL)?ANDJUMP[1-4]?(code,class,gmsg[,smsg,args]) + # MPIR_ERR_CHK(FATAL)?ANDSTMT[1-4]?(cond,code,class,stmt,gmsg[,smsg,args]) + # MPIR_ERR_SET(FATAL)?ANDSTMT[1-4]?(code,class,stmt,gmsg[,smsg,args]) + # Value is a tuple of: + # the count of args where the generic msg begins (starting from 0) + # location of __LINE__ (-1 for none) + # specific msg arg required (0 for no, > 0 for yes) + # is the generic message an indirect from errnames.txt (1=yes 0=no) + # location of the error class + %KnownErrRoutines = ( + 'MPIR_Err_create_code' => '5:3:1:1:4', + 'MPIO_Err_create_code' => '5:3:1:0:-1', + 'MPIR_ERR_SET' => '2:-1:0:1:1', + 'MPIR_ERR_SETSIMPLE' => '2:-1:0:1:1', + 'MPIR_ERR_SET1' => '2:-1:1:1:1', + 'MPIR_ERR_SET2' => '2:-1:2:1:1', + 'MPIR_ERR_SETANDSTMT' => '3:-1:0:1:1', + 'MPIR_ERR_SETANDSTMT1' => '3:-1:1:1:1', + 'MPIR_ERR_SETANDSTMT2' => '3:-1:1:1:1', + 'MPIR_ERR_SETANDSTMT3' => '3:-1:1:1:1', + 'MPIR_ERR_SETANDSTMT4' => '3:-1:1:1:1', + 'MPIR_ERR_SETANDJUMP' => '2:-1:0:1:1', + 'MPIR_ERR_SETANDJUMP1' => '2:-1:1:1:1', + 'MPIR_ERR_SETANDJUMP2' => '2:-1:1:1:1', + 'MPIR_ERR_SETANDJUMP3' => '2:-1:1:1:1', + 'MPIR_ERR_SETANDJUMP4' => '2:-1:1:1:1', + 'MPIR_ERR_CHKANDSTMT' => '4:-1:0:1:2', + 'MPIR_ERR_CHKANDSTMT1' => '4:-1:1:1:2', + 'MPIR_ERR_CHKANDSTMT2' => '4:-1:1:1:2', + 'MPIR_ERR_CHKANDSTMT3' => '4:-1:1:1:2', + 'MPIR_ERR_CHKANDSTMT4' => '4:-1:1:1:2', + 'MPIR_ERR_CHKANDJUMP' => '3:-1:0:1:2', + 'MPIR_ERR_CHKANDJUMP1' => '3:-1:1:1:2', + 'MPIR_ERR_CHKANDJUMP2' => '3:-1:1:1:2', + 'MPIR_ERR_CHKANDJUMP3' => '3:-1:1:1:2', + 'MPIR_ERR_CHKANDJUMP4' => '3:-1:1:1:2', + 'MPIR_ERR_SETFATAL' => '2:-1:0:1:1', + 'MPIR_ERR_SETFATALSIMPLE' => '2:-1:0:1:1', + 'MPIR_ERR_SETFATAL1' => '2:-1:1:1:1', + 'MPIR_ERR_SETFATAL2' => '2:-1:2:1:1', + 'MPIR_ERR_SETFATALANDSTMT' => '3:-1:0:1:1', + 'MPIR_ERR_SETFATALANDSTMT1' => '3:-1:1:1:1', + 'MPIR_ERR_SETFATALANDSTMT2' => '3:-1:1:1:1', + 'MPIR_ERR_SETFATALANDSTMT3' => '3:-1:1:1:1', + 'MPIR_ERR_SETFATALANDSTMT4' => '3:-1:1:1:1', + 'MPIR_ERR_SETFATALANDJUMP' => '2:-1:0:1:1', + 'MPIR_ERR_SETFATALANDJUMP1' => '2:-1:1:1:1', + 'MPIR_ERR_SETFATALANDJUMP2' => '2:-1:1:1:1', + 'MPIR_ERR_SETFATALANDJUMP3' => '2:-1:1:1:1', + 'MPIR_ERR_SETFATALANDJUMP4' => '2:-1:1:1:1', + 'MPIR_ERR_CHKFATALANDSTMT' => '4:-1:0:1:2', + 'MPIR_ERR_CHKFATALANDSTMT1' => '4:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDSTMT2' => '4:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDSTMT3' => '4:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDSTMT4' => '4:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDJUMP' => '3:-1:0:1:2', + 'MPIR_ERR_CHKFATALANDJUMP1' => '3:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDJUMP2' => '3:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDJUMP3' => '3:-1:1:1:2', + 'MPIR_ERR_CHKFATALANDJUMP4' => '3:-1:1:1:2', + 'MPIR_ERRTEST_VALID_HANDLE' => '4:-1:0:1:3', + ); +} # # Other todos: From 6429e794ba1dff5c2e3ef8afd769d462f368e608 Mon Sep 17 00:00:00 2001 From: Hui Zhou Date: Tue, 1 Feb 2022 13:48:13 -0600 Subject: [PATCH 4/4] maint: use strict in maint/extracterrmsgs Use strict prevents misuse of global variables in Perl scripts. --- maint/extracterrmsgs | 107 +++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 50 deletions(-) diff --git a/maint/extracterrmsgs b/maint/extracterrmsgs index b45c6d4c828..bbf56bd2214 100755 --- a/maint/extracterrmsgs +++ b/maint/extracterrmsgs @@ -4,6 +4,8 @@ ## See COPYRIGHT in top-level directory ## +use strict; + # (Tested with -w; 10/5/04) # # Find the parse.sub routine. @@ -16,23 +18,22 @@ if ( ! -s "maint/parse.sub" ) { $maintdir = $program; $rootdir = $program; $rootdir =~ s/\/maint//g; - print "Rootdir = $rootdir\n" if $debug; } } require "$maintdir/parse.sub"; -$debug = 0; -$careful = 0; # Set careful to 1 to flag unused messages -$carefulFilename = ""; -$showfiles = 0; -$quiet = 0; -$build_test_pgm = 1; +my $debug = 0; +my $careful = 0; # Set careful to 1 to flag unused messages +my $carefulFilename = ""; +my $showfiles = 0; +my $quiet = 0; +my $build_test_pgm = 1; # FIXME: checkErrClass should be set to 1; currently set to zero # to permit autogen.sh to complete -$checkErrClass = 1; +my $checkErrClass = 1; # Strict is used to control checking of error message strings. -$gStrict = 0; +my $gStrict = 0; if (defined($ENV{"DEBUG_STRICT"})) { $gStrict = 1; } our (%generic_msgs, %generic_loc, %specific_msgs, %specific_loc); @@ -50,8 +51,8 @@ my $baseerrnames_txt = "src/mpi/errhan/baseerrnames.txt"; my @files = (); my %skipFiles = (); my @errnameFiles = (); -$outfile = ""; -foreach $arg (@ARGV) { +my $outfile = ""; +foreach my $arg (@ARGV) { if ($arg =~ /^--?showfiles/) { $showfiles = 1; } elsif( $arg =~ /^--?debug/) { $debug = 1; } elsif( $arg =~ /^--?quiet/) { $quiet = 1; } @@ -69,7 +70,7 @@ foreach $arg (@ARGV) { if (-d $arg) { # Add all .c files from directory $arg to the list of files # to process (this lets us shorten the arg list) - @files = (@files, &ExpandDir( $arg )); + ExpandDir(\@files, $arg); } else { # errname files are treated differently @@ -84,15 +85,17 @@ foreach $arg (@ARGV) { } # End of argument processing +print "Rootdir = $rootdir\n" if $debug; + # Setup the basic file for errnames - Now determined in ExpandDirs #@errnameFiles = ( "$rootdir/src/mpi/errhan/errnames.txt" ); +my $OUTFD; if ($outfile ne "") { - $OUTFD = "MyOutFile"; open( $OUTFD, ">$outfile" ) or die "Could not open $outfile\n"; } else { - $OUTFD = STDOUT; + $OUTFD = *STDOUT; } # Setup before processing the files if ($build_test_pgm && -d "test/mpi/errhan") { @@ -140,7 +143,8 @@ if (!$max_err_class) { } # Process the definitions -foreach $file (@files) { +my (%generic_msgs, %generic_loc, %specific_msgs, %specific_loc); +foreach my $file (@files) { print "$file\n" if $showfiles; &ProcessFile( $file ); } @@ -148,6 +152,8 @@ foreach $file (@files) { # # Create the hash %longnames that maps the short names to the long names, # $longnames{shortname} => longname, by reading the errnames.txt files +# +my (%longnames, %longnamesDefined); foreach my $sourcefile (@errnameFiles) { #print STDERR "processing $sourcefile for error names\n"; &ReadErrnamesFile( $sourcefile ); @@ -176,6 +182,7 @@ if (open In, $baseerrnames_txt) { # Create the output files from the input that we've read +my (%longnamesUsed, %short_to_num); &CreateErrmsgsHeader( $OUTFD ); &CreateErrMsgMapping( $OUTFD ); @@ -187,15 +194,14 @@ if ($build_test_pgm && -d "test/mpi/errhan") { # # Generate a list of unused keys if ($careful) { - my $OUTFD = STDERR; + my $OUTFD = *STDERR; if ($carefulFilename ne "") { - $OUTFD = "ERRFD"; open $OUTFD, ">$carefulFilename" or die "Cannot open $carefulFilename"; } - foreach $shortname (keys(%longnames)) { + foreach my $shortname (keys(%longnames)) { if (!defined($longnamesUsed{$shortname}) || $longnamesUsed{$shortname} < 1) { - $loc = $longnamesDefined{$shortname}; + my $loc = $longnamesDefined{$shortname}; print $OUTFD "Name $shortname is defined in $loc but never used\n"; } } @@ -211,7 +217,7 @@ if ($careful) { # text. # This is a temporary routine; the exact output form will be defined later sub CreateErrmsgsHeader { - $FD = $_[0]; + my $FD = $_[0]; print $FD "/*\ * Copyright (C) by Argonne National Laboratory\ * See COPYRIGHT in top-level directory\ @@ -276,15 +282,14 @@ sub CreateErrMsgMapping { my $num = 0; foreach my $key (@sorted_generic_msgs) { - $longvalue = "\"\0\""; + my $longvalue = "\"\0\""; if (!defined($longnames{$key})) { - $seenfile = $generic_loc{$key}; + my $seenfile = $generic_loc{$key}; if ($key =~ /^\*\*/) { # If the message begins with text, assume that it is a # literal message print STDERR "Shortname $key for generic messages has no expansion (first seen in file $seenfile)\n"; - print STDERR "(Add expansion to $sourcefile)\n"; } next; } @@ -324,9 +329,9 @@ sub CreateErrMsgMapping { $num = 0; # Now output the instance specific messages print $OUTFD "#if MPICH_ERROR_MSG_LEVEL > MPICH_ERROR_MSG__GENERIC\n"; - foreach $key (sort keys %specific_msgs) + foreach my $key (sort keys %specific_msgs) { - $longvalue = "\"\0\""; + my $longvalue = "\"\0\""; if (!defined($longnames{$key})) { @@ -360,7 +365,7 @@ sub CreateErrMsgMapping { print $OUTFD "#endif\n\n"; print $OUTFD "#if MPICH_ERROR_MSG_LEVEL > MPICH_ERROR_MSG__CLASS\n"; - $maxval = $max_err_class + 1; + my $maxval = $max_err_class + 1; print $OUTFD "#define MPIR_MAX_ERROR_CLASS_INDEX $maxval\n"; print $OUTFD "static int class_to_index[] = {\n "; for (my $i=0; $i<=$max_err_class; $i++) { @@ -380,9 +385,10 @@ sub CreateErrMsgMapping { # Add a call to test this message for the error message. # Handle both the generic and specific messages # +my (%test_generic_msg, %test_specific_msg); sub AddTestCall { - my $genericArgLoc = $_[0]; + my ($filename, $genericArgLoc, @msg_args) = @_; my $last_errcode = "MPI_SUCCESS"; # $_[0]; my $fatal_flag = "MPIR_ERR_RECOVERABLE"; # $_[1]; @@ -390,9 +396,11 @@ sub AddTestCall { my $linenum = "__LINE__"; # $_[3]; my $errclass = "MPI_ERR_OTHER"; # $_[4]; - my $generic_msg = $_[$genericArgLoc+1]; - my $specific_msg = $_[$genericArgLoc+2]; - if ($#_ < $genericArgLoc+2) { $specific_msg = "0"; } + my $generic_msg = $msg_args[$genericArgLoc]; + my $specific_msg = $msg_args[$genericArgLoc+1]; + if (!defined $specific_msg) { + $specific_msg = "0"; + } # Ensure that the last_errcode, class and fatal flag are specified. There are a few places where these are variables. if (!($last_errcode =~ /MPI_ERR_/) ) @@ -550,7 +558,7 @@ sub AddTestCall { print STDERR "Unrecognized format type $type for $fullformat in $filename\n"; } } - $actargs = $#_ - $genericArgLoc - 2; + my $actargs = $#msg_args - $genericArgLoc - 1; if ($actargs != $narg) { print STDERR "Error: Format $fullformat provides $narg arguments but call has $actargs in $filename\n"; @@ -651,8 +659,8 @@ sub ReadErrnamesFile { # and the same for hash specific_loc{msg}. # The last two are used to provide better error reporting. # -$filename = ""; # Make global so that other routines can echo filename -%KnownErrRoutines; +my %KnownErrRoutines; +my %bad_syntax_in_file; sub ProcessFile { @@ -660,18 +668,18 @@ sub ProcessFile load_KnownErrRoutines(); } - # Leave filename global for AddTest - $filename = $_[0]; + my $filename = $_[0]; my $linecount = 0; - open (FD, "<$filename" ) or die "Could not open $filename\n"; + my $remainder; + open (my $FD, "<$filename" ) or die "Could not open $filename\n"; - while () { + while (<$FD>) { $linecount++; # Skip code that is marked as ignore (e.g., for # macros that are used to simplify the use of MPIR_Err_create_code # (such macros must also be recognized and processed) if (/\/\*\s+--BEGIN ERROR MACROS--\s+\*\//) { - while () { + while (<$FD>) { $linecount++; if (/\/\*\s+--END ERROR MACROS--\s+\*\//) { last; } } @@ -679,7 +687,7 @@ sub ProcessFile next; } # Next, remove any comments - $_ = StripComments( FD, $_ ); + $_ = StripComments($FD, $_ ); # Skip the definition of the function if (/int\s+MPI[OUR]_Err_create_code/) { $remainder = ""; next; } while (/(MPI[OUR]_Err[A-Za-z0-9_]+)\s*(\(.*)$/i) { @@ -697,11 +705,12 @@ sub ProcessFile my ($genericArgLoc,$hasLine,$hasSpecific,$onlyIndirect,$errClassLoc) = split(/:/,$KnownErrRoutines{$routineName}); - ($leader, $remainder, @args ) = &GetSubArgs( FD, $arglist ); + my ($leader, @args); + ($leader, $remainder, @args ) = &GetSubArgs($FD, $arglist ); # Discard leader if ($debug) { print "Line begins with $leader\n"; # Use $leader to keep -w happy - foreach $arg (@args) { + foreach my $arg (@args) { print "|$arg|\n"; } } @@ -826,7 +835,7 @@ sub ProcessFile } if ($build_test_pgm) { - &AddTestCall( $genericArgLoc, @args ) + &AddTestCall($filename, $genericArgLoc, @args ) } if ($generic_msg =~ /^\"(.*)\"$/) { @@ -851,17 +860,16 @@ sub ProcessFile $_ = $remainder; } } - close FD; + close $FD; } # Get all of the .c files from the named directory, including any subdirs # Also, add any errnames.txt files to the errnamesFiles arrays sub ExpandDir { - my $dir = $_[0]; + my ($files, $dir) = @_; my @otherdirs = (); - my @files = (); opendir DIR, "$dir"; - while ($filename = readdir DIR) { + while (my $filename = readdir DIR) { if ($filename =~ /^\./) { next; } @@ -872,7 +880,7 @@ sub ExpandDir { # Test for both Unix- and Windows-style directory separators if (!defined($skipFiles{"$dir/$filename"}) && !defined($skipFiles{"$dir\\$filename"})) { - $files[$#files + 1] = "$dir/$filename"; + push @$files, "$dir/$filename"; } } elsif ($filename eq "errnames.txt") { @@ -882,10 +890,9 @@ sub ExpandDir { closedir DIR; # (almost) tail recurse on otherdirs (we've closed the directory handle, # so we don't need to worry about it anymore) - foreach $dir (@otherdirs) { - @files = (@files, &ExpandDir( $dir ) ); + foreach my $dir (@otherdirs) { + ExpandDir($files, $dir); } - return @files; } sub load_KnownErrRoutines {