The following file, from the development sources of mutt, is miscompiled at -march=i386 -mcpu=i686 -Ox where x > 0. AFAICT, it's mutt_copy_hdr that's being miscompiled. The code where it dies is in either the safe_realloc or safe_strdup around lines 190-195, as headers[x] ends up being something bogus.
Created attachment 8228 [details] preprocessed source of miscompiled file
How can I reproduce this? I guess I'll need whole mutt sources (can you tell me which exact sources from where etc.), some test mailbox and some sequence of commands which trigger this...
Sure. Take mutt-1.3.13i.tar.gz (I can either attach it, or you can get it direct from ftp.mutt.org:/pub/mutt/devel/. Build it, then start mutt on any folder. Enter the command: :hdr_order From: Date: To: Cc: Subject: (the hdr_order itself isn't exactly relevnant, but there needs to be *some* hdr_order set) Then open up a message, and hit ESC-C (for decode-copy): once you select a folder, it should then segfault. When copy.c is built without optimization, it works. I'll see if I can narrow it down some more.
It's definitely mutt_copy_hdr that's miscompiled; if I split that out to a separate source file and compile just *that* with -O0, mutt works.
If you have a broken binary, set a breakpoint at mutt_copy_hdr. When you get there when copying the message, go up one frame, and set a watchpoint on 'h'. Breakpoint 1, mutt_copy_hdr (in=0x80e5cd0, out=0x80e7e88, off_start=0, off_end=1620, flags=18971, prefix=0x0) at copy2.c:44 44 int from = 0; (gdb) up #1 0x08057bcf in mutt_copy_header (in=0x80e5cd0, h=0x80e6680, out=0x80e7e88, flags=18971, prefix=0x0) at copy.c:62 62 if (mutt_copy_hdr (in, out, h->offset, h->content->offset, flags, prefix) == -1) (gdb) watch h Watchpoint 2: h (gdb) down #0 mutt_copy_hdr (in=0x80e5cd0, out=0x80e7e88, off_start=0, off_end=1620, flags=18971, prefix=0x0) at copy2.c:44 44 int from = 0; (gdb) next 43 { (gdb) 46 int ignore = 0; (gdb) 43 { (gdb) 44 int from = 0; (gdb) 55 if (ftell (in) != off_start) (gdb) 46 int ignore = 0; (gdb) 43 { (gdb) Watchpoint 2: h Old value = (HEADER *) 0x80e6680 New value = (HEADER *) 0x4a1b mutt_copy_hdr (in=0x80e5cd0, out=0x80e7e88, off_start=0, off_end=1620, flags=18971, prefix=0x0) at copy2.c:55 55 if (ftell (in) != off_start) (gdb) If that's not the problem, it certainly seems fishy.
Strange, I cannot reproduce this. Maybe our configure arguments were different, whatever. Do you have your binary exhibiting it somewhere (so I can find out if the issue is that I compiled mutt in a different way or that I just chose a bad mailbox or used a different muttrc)?
Hm, I just used our normal specfile on 1.3.13i. Tarball is ~notting/mutt-foo.tar.gz; I can attach it here if you like.
I think I've nailed it down, am just bootstrapping the patch in CVS gcc to see if it does not break anything. The if (flags & 0x80) test was done using testl -128, %edi while it should have been done using testl 128, %edi.
Fixed in gcc-2.96-73 and above.