Hi,
80a9e99f7078199500d2d53c8d77d1b92af06fbc added an assert(3) as part of
the -width-overflow fix for Valdis's email.
Bad news: Yesterday, I got two aborts in a row when running `scan +foo'
from git. I then viewed the source, and after that it wouldn't happen.
:-( Good news: A code dump was squirrelled away.
Bad news: By the time I thought of that, the executable I'd run had
changed. Good news: gdb(1) is still happy to disassemble where I know
the execution was rather than where it thinks it was in the source, and
dump memory, so I've poked about it a bit. Here's what I found in the
hope it helps fix it, and as a prompt to me should I get it to re-occur.
if (!str)
return;
0x00409774 <+0>: push %rbp
0x00409775 <+1>: mov %rsp,%rbp
0x00409778 <+4>: sub $0x40,%rsp
0x0040977c <+8>: mov %rdi,-0x28(%rbp) dest
0x00409780 <+12>: mov %rsi,-0x30(%rbp) max
0x00409784 <+16>: mov %rdx,-0x38(%rbp) str
0x00409788 <+20>: movl $0x1,-0x4(%rbp) prevCtrl
0x0040978f <+27>: movq $0x0,-0x18(%rbp) altstr
0x00409797 <+35>: cmpq $0x0,-0x38(%rbp) str
0x0040979c <+40>: je 0x409931 <cpstripped+445>
len = strlen(str);
0x004097a2 <+46>: mov -0x38(%rbp),%rax
0x004097a6 <+50>: mov %rax,%rdi str
0x004097a9 <+53>: callq 0x4025c0 <strlen@plt>
0x004097ae <+58>: mov %eax,-0x8(%rbp) len
if (mbtowc(NULL, NULL, 0)) {} /* Reset shift state */
0x004097b1 <+61>: mov $0x0,%edx
0x004097b6 <+66>: mov $0x0,%esi
0x004097bb <+71>: mov $0x0,%edi
0x004097c0 <+76>: callq 0x402830 <mbtowc@plt>
while (*str != '\0' && len > 0 && max > 0) {
Skipped.
char_len = mbtowc(&wide_char, str, len);
0x004097ca <+86>: mov -0x8(%rbp),%eax len
0x004097cd <+89>: movslq %eax,%rdx len
0x004097d0 <+92>: mov -0x38(%rbp),%rcx str
0x004097d4 <+96>: lea -0x20(%rbp),%rax wide_char
0x004097d8 <+100>: mov %rcx,%rsi str
0x004097db <+103>: mov %rax,%rdi &wide_char
0x004097de <+106>: callq 0x402830 <mbtowc@plt>
0x004097e3 <+111>: mov %eax,-0xc(%rbp) char_len
w = wcwidth(wide_char);
0x004097e6 <+114>: mov -0x20(%rbp),%eax wide_char
0x004097e9 <+117>: mov %eax,%edi
0x004097eb <+119>: callq 0x4028b0 <wcwidth@plt>
0x004097f0 <+124>: mov %eax,-0x1c(%rbp) w
assert(w >= 0); /* This aborts. */
0x00409880 <+268>: cmpl $0x0,-0x1c(%rbp)
0x00409884 <+272>: jns 0x40989f <cpstripped+299>
0x00409886 <+274>: mov $0x41f418,%ecx
0x0040988b <+279>: mov $0x12c,%edx
0x00409890 <+284>: mov $0x41effa,%esi
0x00409895 <+289>: mov $0x41f009,%edi
0x0040989a <+294>: callq 0x402690 <__assert_fail@plt>
(gdb) x $rbp - 0x1c
0x7ffc861af084: 0xffffffff w
(gdb) x $rbp - 0x20
0x7ffc861af080: 0x0000003f wide_char = '?'
(gdb) x $rbp - 0xc
0x7ffc861af094: 0x00000001 char_len on '?'
(gdb) x $rbp - 0x38
0x7ffc861af068: 0x0327d1d3 str
(gdb) x $rbp - 0x8
0x7ffc861af098: 172 len, after len -= char_len
(gdb) x/32ub 0x0327d1c0
0x327d1c0: 46 56 32 77 66 41 32 97
0x327d1c8: 110 100 32 50 50 53 44 48
0x327d1d0: 48 48 10 [ 194 ] 161 195 145 32
0x327d1d8: 50 50 53 44 48 48 48 32
$ printf '%02X' 46 56 32 77 66 41 32 97 110 100 32 50 50 53 44 48 48 48 10 \
> 194 161 195 145 32 50 50 53 44 48 48 48 32; echo
2E38204D422920616E64203232352C3030300AC2A1C391203232352C30303020
$
$ dc
<<<'16i2E38204D422920616E64203232352C3030300AC2A1C391203232352C30303020P'; echo
.8 MB) and 225,000
¡Ñ 225,000
$
The email in +foo with that fragment is text/plain, UTF-8, 8bit, with
this paragraph as the body preceded by two blank lines.
Biggest image in the smallest space, "Here is a bzip2 file of 420 bytes
that uncompresses to a PNG image of 6,132,534 bytes (5.8 MB) and 225,000
¡Ñ 225,000 pixels (50.625 gigapixels), which, if represented as a pixel
buffer of 3 bytes per pixel, takes about 141.4 GB."
https://www.bamsoftware.com/hacks/deflate.html
Naturally, running `scan -width $w +foo .' for {10..1000} doesn't cause
any problems, in C or en_GB.utf8 locale, but it seems quite possible to
me that the wcwidth() of a `mbtowc() < 0' could be -1, as above?
--
Cheers, Ralph.
https://plus.google.com/+RalphCorderoy
_______________________________________________
Nmh-workers mailing list
Nmh-workers(_at_)nongnu(_dot_)org
https://lists.nongnu.org/mailman/listinfo/nmh-workers