> Am 19.05.2025 um 20:16 schrieb Paul Eggert <egg...@cs.ucla.edu>:
> 
> There are lots of failures there, but unfortunately I don't have access to 
> that old platform so you'll need to do some more digging to isolate the cause.


I think I tracked down the cause for diff to fail on Tiger, with .gdbinit 
containing 'break util.c:1028':

        Starting program: 
/opt/local/var/macports/build/_Users_btest_ports_sysutils_diffutils/diffutils/work/diffutils-3.12/src/diff
 -u Portfile-graphite2-312 Portfile-graphite2
        Reading symbols for shared libraries ...................+ done
        --- Portfile-graphite2-312      2025-06-09 15:48:08.000000000 +0200
        +++ Portfile-graphite2  2025-06-09 15:48:08.000000000 +0200
        @@ -27,14 +18,23 @@
        
        Breakpoint 1, print_1_line_nl (line_flag=0x0, line=0x40137c, 
skip_nl=false) at util.c:1028
        (gdb) s
        output_1_line (base=0x0, limit=0x18015ef "distname", ' ' <repeats 12 
times>, "${name}-${version}\nextract.suffix      .tgz\n\ncompiler.cxx_standard 
\\\n", ' ' <repeats 20 times>, "2011\n\nset py_ver          3.12\nset 
py_ver_nodot    [string map {. {}} ${py_ver}]\n\ntest.run "..., 
flag_format=0x0, line_flag=0x0) at util.c:1047
        (gdb) n
        (gdb) n
        (gdb) n
        (gdb) n
        (gdb) s         ->  idx_t written = fwrite (base, sizeof (char), 
to_write, outfile);
        
        Program received signal EXC_BAD_ACCESS, Could not access memory.
        Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
        0x90029b70 in memchr ()

The libc function fwrite() causes the crash. It is documented on the man page 
as:

     size_t
     fwrite(const void * restrict ptr, size_t size, size_t nmemb,
         FILE * restrict stream);

I tried to print out some values:
        
        (gdb) p to_write
        $1 = 1024
        (gdb) p base
        $2 = 0x0
        (gdb) p sizeof (char)
        $3 = 1
        (gdb) p outfile
        $4 = (FILE *) 0xa0001bec


The correct output should be something like this:

        @@ -31,7 +31,7 @@
         compiler.cxx_standard \
                             2011
         
        -set py_ver          3.12
        +set py_ver          3.13
         set py_ver_nodot    [string map {. {}} ${py_ver}]
         
         test.run            yes

Here are the last 128+ lines of util.c as reference for the line numbers given:

  998   void
  999   print_1_line_nl (char const *line_flag, char const *const *line, bool 
skip_nl)
 1000   {
 1001     char const *base = line[0], *limit = line[1]; /* Help the compiler.  
*/
 1002     FILE *out = outfile; /* Help the compiler some more.  */
 1003     char const *flag_format = nullptr;
 1004   
 1005     /* If -T was specified, use a Tab between the line-flag and the text.
 1006        Otherwise use a Space (as Unix diff does).
 1007        Print neither space nor tab if line-flags are empty.
 1008        But omit trailing blanks if requested.  */
 1009   
 1010     if (line_flag && *line_flag)
 1011       {
 1012         char const *flag_format_1 = flag_format = initial_tab ? "%s\t" : 
"%s ";
 1013         char const *line_flag_1 = line_flag;
 1014   
 1015         if (suppress_blank_empty && **line == '\n')
 1016           {
 1017             flag_format_1 = "%s";
 1018   
 1019             /* This hack to omit trailing blanks takes advantage of the
 1020                fact that the only way that LINE_FLAG can end in a blank
 1021                is when LINE_FLAG consists of a single blank.  */
 1022             line_flag_1 += *line_flag_1 == ' ';
 1023           }
 1024   
 1025         fprintf (out, flag_format_1, line_flag_1);
 1026       }
 1027   
 1028     output_1_line (base, limit - (skip_nl && limit[-1] == '\n'), 
flag_format, line_flag);
 1029   
 1030     if ((!line_flag || line_flag[0]) && limit[-1] != '\n')
 1031       {
 1032         set_color_context (RESET_CONTEXT);
 1033         fprintf (out, "\n\\ %s\n", _("No newline at end of file"));
 1034       }
 1035   }
 1036   
 1037   /* Output a line from BASE up to LIMIT.
 1038      With -t, expand white space characters to spaces, and if FLAG_FORMAT
 1039      is nonzero, output it with argument LINE_FLAG after every
 1040      internal carriage return, so that tab stops continue to line up.  */
 1041   
 1042   void
 1043   output_1_line (char const *base, char const *limit, char const 
*flag_format,
 1044                  char const *line_flag)
 1045   {
 1046     enum { MAX_CHUNK = 1024 };
 1047     if (!expand_tabs)
 1048       {
 1049         idx_t left = limit - base;
 1050         while (left)
 1051           {
 1052             idx_t to_write = MIN (left, MAX_CHUNK);
 1053             idx_t written = fwrite (base, sizeof (char), to_write, 
outfile);
 1054             process_signals ();
 1055             if (written < to_write)
 1056               return;
 1057             base += written;
 1058             left -= written;
 1059           }
 1060       }
 1061     else
 1062       {
 1063         FILE *out = outfile;
 1064         char const *t = base;
 1065         intmax_t tab = 0, column = 0, tab_size = tabsize;
 1066         int counter_proc_signals = 0;
 1067   
 1068         while (t < limit)
 1069           {
 1070             counter_proc_signals++;
 1071             if (counter_proc_signals == MAX_CHUNK)
 1072               {
 1073                 process_signals ();
 1074                 counter_proc_signals = 0;
 1075               }
 1076   
 1077             switch (*t)
 1078               {
 1079               case '\t':
 1080                 t++;
 1081                 do
 1082                   if (putc (' ', out) < 0)
 1083                     return;
 1084                 while (++column < tab_size);
 1085   
 1086                 tab++;
 1087                 column = 0;
 1088                 break;
 1089   
 1090               case '\r':
 1091                 t++;
 1092                 if (putc ('\r', out) < 0)
 1093                   return;
 1094                 if (flag_format && t < limit && *t != '\n')
 1095                   if (fprintf (out, flag_format, line_flag) < 0)
 1096                     return;
 1097                 tab = column = 0;
 1098                 break;
 1099   
 1100               case '\b':
 1101                 t++;
 1102                 if (0 < column)
 1103                   column--;
 1104                 else if (0 < tab)
 1105                   {
 1106                     tab--;
 1107                     column = tab_size - 1;
 1108                   }
 1109                 else
 1110                   continue;
 1111                 if (putc ('\b', out) < 0)
 1112                   return;
 1113                 break;
 1114   
 1115               default:;
 1116                 mcel_t g = mcel_scan (t, limit);
 1117                 column += g.err ? 1 : c32isprint (g.ch) ? c32width (g.ch) 
: 0;
 1118                 tab += column / tab_size;
 1119                 column %= tab_size;
 1120                 if (fwrite (t, sizeof *t, g.len, outfile) != g.len)
 1121                   return;
 1122                 t += g.len;
 1123                 break;
 1124               }
 1125           }
 1126       }
 1127   }


Is there anything I can do to find more clues?

--

Greetings

  Pete

Life is the only flaw in an otherwise perfect nonexistence
                                – Schopenhauer




Reply via email to