I'm using dd with french locale and have this segfault.
I use dapper with a dd included in coreutils (5.93-5ubuntu4).
Here is a backtrace with gdb (remade from the source from packages.ubuntu.com):
#0 0xb7ead2a3 in strlen () from /lib/tls/i686/cmov/libc.so.6
#1 0xb7e812e4 in vfprintf () from /lib/tls/i686/cmov/libc.so.6
#2 0xb7e7dd7c in cuserid () from /lib/tls/i686/cmov/libc.so.6
#3 0xb7e7dfbb in vfprintf () from /lib/tls/i686/cmov/libc.so.6
#4 0xb7e866af in fprintf () from /lib/tls/i686/cmov/libc.so.6
#5 0x080497b2 in print_stats () at dd.c:553
#6 0x0804b3fa in main (argc=5, argv=0xbfea0c24) at dd.c:600
If you take a look at dd.c on line 553 you have that:
If more than one byte is transferred, the second line in ngettext is used (the plural one) and the first format ("%"PRIuMax which give something like %ul) will load MIN (w_bytes, ULONG_MAX). After that, fprintf will load the next arg for the symbol %s and this arg is w_bytes which is an unsigned long I guess. It is not a string, so it will crash the strlen inside fprintf. Here is the segfault. I guess w_bytes as a third argument has no reason to exist. The third argument has to be the actual fourth: human_readable(....)
If only a byte is transferred, you not have the segfault because there is no format chars wich load next arguments, this because the singular line will be used.
Hi all.
I'm using dd with french locale and have this segfault.
I use dapper with a dd included in coreutils (5.93-5ubuntu4).
Here is a backtrace with gdb (remade from the source from packages. ubuntu. com):
#0 0xb7ead2a3 in strlen () from /lib/tls/ i686/cmov/ libc.so. 6 i686/cmov/ libc.so. 6 i686/cmov/ libc.so. 6 i686/cmov/ libc.so. 6 i686/cmov/ libc.so. 6
#1 0xb7e812e4 in vfprintf () from /lib/tls/
#2 0xb7e7dd7c in cuserid () from /lib/tls/
#3 0xb7e7dfbb in vfprintf () from /lib/tls/
#4 0xb7e866af in fprintf () from /lib/tls/
#5 0x080497b2 in print_stats () at dd.c:553
#6 0x0804b3fa in main (argc=5, argv=0xbfea0c24) at dd.c:600
If you take a look at dd.c on line 553 you have that:
fprintf (stderr,
ngettext ("1 byte (1 B) copied",
"%"PRIuMAX" bytes (%s) copied",
MIN (w_bytes, ULONG_MAX)),
w_bytes,
human_readable (w_bytes, hbuf, human_opts, 1, 1));
If more than one byte is transferred, the second line in ngettext is used (the plural one) and the first format ("%"PRIuMax which give something like %ul) will load MIN (w_bytes, ULONG_MAX). After that, fprintf will load the next arg for the symbol %s and this arg is w_bytes which is an unsigned long I guess. It is not a string, so it will crash the strlen inside fprintf. Here is the segfault. I guess w_bytes as a third argument has no reason to exist. The third argument has to be the actual fourth: human_readable( ....)
If only a byte is transferred, you not have the segfault because there is no format chars wich load next arguments, this because the singular line will be used.
Here is a small patch to correct this:
--- dd (copie).c 2005-11-02 14:18:47.000000000 +0100
+++ dd.c 2006-06-21 06:35:56.000000000 +0200
@@ -554,7 +554,6 @@
ngettext ("1 byte (1 B) copied",
"%"PRIuMAX" bytes (%s) copied",
MIN (w_bytes, ULONG_MAX)),
- w_bytes,
human_readable (w_bytes, hbuf, human_opts, 1, 1));
if (start_time < now)
Note that I have a new bug now with this patch: "%"PRIuMAX" should give "%llu" by me. But on output it gives (as an example):
%<PRIuMAX> octets (3 B) copiés, 0,000179 seconde, 16,8 kB/s
That's strange, I can't understand that....