> Am 19.05.2025 um 20:16 schrieb Paul Eggert <[email protected]>:
>
> 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