Hello,
When processing an "a" (append text) command in an ed-style diff, a line number
range appears to hang patch.
If a range (e.g. "1,2") is given as a prefix to "a", the 2nd address ("2") is
used as the target address.
Ed-style diffs can be pasted from a previous ed editor session or typed
manually.
Regular diff tools will only generate "a" commands with a single address in an
ed-style diff.
In this case I modified a diff to change the "322a" command to "1,322a", which
is equivalent in ed.
%cat bad.diffe
1,322a
my $Maxlen = 1; # longest string for current directory
.
317,318d
113d
The patch process seems to get stuck. Software details are:
%uname -a
Linux raspberrypi 6.6.51+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.6.51-1+rpt3
(2024-10-08) aarch64 GNU/Linux
%patch -v
GNU patch 2.7.6
When running patch under strace I see a loop of clone() then openat() creating
a temporary file.
The read() lines from strace indicate that the input file "ls" (a perl script)
is being read repeatedly.
%strace patch -e ls bad.diffe
<SNIP>
unlinkat(AT_FDCWD, "/tmp/peoFCi0M", 0) = 0
faccessat(AT_FDCWD, "ls", W_OK) = 0
getpid() = 11227
openat(AT_FDCWD, "./ls.oKllpLz", O_WRONLY|O_CREAT|O_EXCL, 0755) = 4
getpid() = 11227
openat(AT_FDCWD, "/tmp/peOYUvvm", O_RDWR|O_CREAT|O_EXCL, 000) = 5
fcntl(5, F_GETFL) = 0x20002 (flags O_RDWR|O_LARGEFILE)
newfstatat(5, "", {st_mode=S_IFREG|000, st_size=0, ...}, AT_EMPTY_PATH) = 0
write(5, "w\nq\n", 4) = 4
lseek(5, 0, SEEK_SET) = 0
openat(AT_FDCWD, "./ls.oKllpLz", O_WRONLY|O_CREAT|O_TRUNC|O_NOFOLLOW, 0100644)
= 6
openat(AT_FDCWD, "ls", O_RDONLY|O_NOFOLLOW) = 7
read(7, "#!/usr/bin/perl\n\n=begin metadata"..., 8192) = 8192
write(6, "#!/usr/bin/perl\n\n=begin metadata"..., 8192) = 8192
read(7, " 0: $Attributes->{$_}->blocks;"..., 8192) = 7897
write(6, " 0: $Attributes->{$_}->blocks;"..., 7897) = 7897
read(7, "", 8192) = 0
close(7) = 0
close(6) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,
child_tidptr=0x7f7fc9ff90) = 11336
wait4(11336, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 11336
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=11336, si_uid=1000,
si_status=0, si_utime=0, si_stime=0} ---
close(5) = 0
fstat(4, {st_mode=S_IFREG|0755, st_size=16089, ...}) = 0
close(4) = 0
rt_sigprocmask(SIG_BLOCK, [HUP INT PIPE TERM XCPU XFSZ], [], 8) = 0
fchmodat(AT_FDCWD, "./ls.oKllpLz", 0100755) = 0
newfstatat(AT_FDCWD, "ls", {st_mode=S_IFREG|0755, st_size=16089, ..},
AT_SYMLINK_NOFOLLOW) = 0
renameat(AT_FDCWD, "./ls.oKllpLz", AT_FDCWD, "ls") = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
lseek(3, 80, SEEK_SET) = 80
newfstatat(AT_FDCWD, "ls", {st_mode=S_IFREG|0755, st_size=16089, ..},
AT_SYMLINK_NOFOLLOW) = 0
lseek(3, 80, SEEK_SET) = 80
unlinkat(AT_FDCWD, "/tmp/peOYUvvm", 0) = 0
faccessat(AT_FDCWD, "ls", W_OK) = 0
getpid() = 11227
openat(AT_FDCWD, "./ls.oazM6A9", O_WRONLY|O_CREAT|O_EXCL, 0755) = 4
getpid() = 11227
openat(AT_FDCWD, "/tmp/pekPWoGW", O_RDWR|O_CREAT|O_EXCL, 000) = 5
fcntl(5, F_GETFL) = 0x20002 (flags O_RDWR|O_LARGEFILE)
newfstatat(5, "", {st_mode=S_IFREG|000, st_size=0, ...}, AT_EMPTY_PATH) = 0
write(5, "w\nq\n", 4) = 4
lseek(5, 0, SEEK_SET) = 0
openat(AT_FDCWD, "./ls.oazM6A9", O_WRONLY|O_CREAT|O_TRUNC|O_NOFOLLOW, 0100644)
= 6
openat(AT_FDCWD, "ls", O_RDONLY|O_NOFOLLOW) = 7
read(7, "#!/usr/bin/perl\n\n=begin metadata"..., 8192) = 8192
write(6, "#!/usr/bin/perl\n\n=begin metadata"..., 8192) = 8192
read(7, " 0: $Attributes->{$_}->blocks;"..., 8192) = 7897
write(6, " 0: $Attributes->{$_}->blocks;"..., 7897) = 7897
read(7, "", 8192) = 0
close(7) = 0
close(6) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,
child_tidptr=0x7f7fc9ff90) = 11337
wait4(11337, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 11337
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=11337, si_uid=1000,
si_status=0, si_utime=0, si_stime=0} ---
close(5) = 0
fstat(4, {st_mode=S_IFREG|0755, st_size=16089, ...}) = 0
close(4) = 0
rt_sigprocmask(SIG_BLOCK, [HUP INT PIPE TERM XCPU XFSZ], [], 8) = 0
fchmodat(AT_FDCWD, "./ls.oazM6A9", 0100755) = 0
newfstatat(AT_FDCWD, "ls", {st_mode=S_IFREG|0755, st_size=16089, ..},
AT_SYMLINK_NOFOLLOW) = 0
renameat(AT_FDCWD, "./ls.oazM6A9", AT_FDCWD, "ls") = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
lseek(3, 80, SEEK_SET) = 80
newfstatat(AT_FDCWD, "ls", {st_mode=S_IFREG|0755, st_size=16089, ..},
AT_SYMLINK_NOFOLLOW) = 0
lseek(3, 80, SEEK_SET) = 80
unlinkat(AT_FDCWD, "/tmp/pekPWoGW", 0) = 0
faccessat(AT_FDCWD, "ls", W_OK) = 0
getpid() = 11227
openat(AT_FDCWD, "./ls.oalqSjJ", O_WRONLY|O_CREAT|O_EXCL, 0755) = 4
getpid() = 11227
openat(AT_FDCWD, "/tmp/pemgJiWv", O_RDWR|O_CREAT|O_EXCL, 000) = 5
fcntl(5, F_GETFL) = 0x20002 (flags O_RDWR|O_LARGEFILE)
newfstatat(5, "", {st_mode=S_IFREG|000, st_size=0, ...}, AT_EMPTY_PATH) = 0
write(5, "w\nq\n", 4) = 4
lseek(5, 0, SEEK_SET) = 0
openat(AT_FDCWD, "./ls.oalqSjJ", O_WRONLY|O_CREAT|O_TRUNC|O_NOFOLLOW, 0100644)
= 6
openat(AT_FDCWD, "ls", O_RDONLY|O_NOFOLLOW) = 7
read(7, "#!/usr/bin/perl\n\n=begin metadata"..., 8192) = 8192
write(6, "#!/usr/bin/perl\n\n=begin metadata"..., 8192) = 8192
read(7, " 0: $Attributes->{$_}->blocks;"..., 8192) = 7897
write(6, " 0: $Attributes->{$_}->blocks;"..., 7897) = 7897
read(7, "", 8192) = 0
close(7) = 0
close(6^Cstrace: Process 11227 detached
<detached ...>
Running patch under the sotruss utility doesn't clarify anything to me I see
fputc() and fread() calls.
Probably these are just the I/O happening on the temporary files as strace
shows.
Sorry if I missed something in this report. Have a nice day.
- Michael