Hello, I'm running into a segfault with MPlayer on MKV files. I think it might be a bug in some aspect of GCC 4.4's optimization, but I'm having trouble narrowing it down. All I know for sure is: Works: * compiled by gcc 4.4 with -O2 * compiled by gcc 3.3, 3.4, 4.0, 4.1, 4.2, 4.3 (any optimization level) * compiled by gcc svn trunk (any optimization level) Crashes: * compiled by gcc 4.4 with -O3 Here's a full list of steps to reproduce this bug. ------------------------------------------------------------------------ $ svn co -r '{2009-09-26}' svn://svn.mplayerhq.hu/mplayer/trunk mplayer $ cd mplayer $ CFLAGS=-O3 ./configure --cc=gcc-4.4 $ make $ wget http://samples.mplayerhq.hu/Matroska/theora.mkv $ ./mplayer theora.mkv ------------------------------------------------------------------------ I'm seeing mplayer segfault here. I don't get a segfault if I compile with a lower optimization level: $ make distclean && CFLAGS=-O2 ./configure --cc=gcc-4.4 && make ...or with a different version of GCC. $ make distclean && CFLAGS=-O3 ./configure --cc=gcc-4.3 && make I understand that messing with CFLAGS is contra-indicated when compiling MPlayer, but I'm just trying to isolate a problem that occurs with the default CFLAGS anyway. GCC's optimization levels, if I understand correctly, enable groups of compiler flags. I tried to determine if the segfault was caused by a particular flag; however, it seems that there are several flags where removing any one of them makes the crash go away. In other words, the following set of flags causes a segfault: -O1 -fgcse -finline-small-functions -fschedule-insns2 -fstrict-aliasing -finline-functions I wasn't able to narrow down the "-O1" any further; when I replace it with the group of flags supposedly enabled by "-O1", the crash goes away. I don't know what I'm doing wrong. I'm getting the list by running: $ gcc-4.4 -c -Q -O0 --help=optimizers > /tmp/O0 $ gcc-4.4 -c -Q -O1 --help=optimizers > /tmp/O1 $ diff /tmp/O0 /tmp/O1 | awk '/enabled/ {print $2}' At this point I'm kind of stuck. I can use GDB to determine the point at which the segfault occurs: ------------------------------------------------------------------------ Program received signal SIGSEGV, Segmentation fault. 0x0000000000584039 in add_cluster_position (demuxer=<value optimized out>, ds=<value optimized out>) at libmpdemux/demux_mkv.c:240 240 mkv_d->cluster_positions[mkv_d->num_cluster_pos++] = position; (gdb) print mkv_d $1 = <value optimized out> ------------------------------------------------------------------------ ...but with the optimizations enabled I can't figure out what's going on with the code. I started to try some "printf debugging" but stopped when I discovered that any printf usage makes the crash go away (see attached mask_bug.diff). One other item worth mentioning is that the line where the crash occurs is right after a probable realloc(). I can't determine that for sure though--the optimizations throw off my GDB usage. I discovered this bug with Debian's gcc 4.4.1 and verified the same behavior with unmodified svn from "gcc-4_4-branch". My gcc is compiled without any special options. Just: ------------------------------------------------------------------------ $ mkdir build $ cd build $ ../gcc-4_4-branch/configure --prefix=/home/bugfood/gcc4 $ make $ make install ------------------------------------------------------------------------ Most of my testing of this bug is on amd64, but it seems to happen the same on i386 as well. Does anybody have advice for how I should proceed? I'd like to be able to write an actual bug report but at this point I don't think I have enough precise information. Thanks, Corey
Index: libmpdemux/demux_mkv.c =================================================================== --- libmpdemux/demux_mkv.c (revision 29712) +++ libmpdemux/demux_mkv.c (working copy) @@ -237,6 +237,7 @@ grow_array((void **)&mkv_d->cluster_positions, mkv_d->num_cluster_pos, sizeof(uint64_t)); + printf("hello\n"); mkv_d->cluster_positions[mkv_d->num_cluster_pos++] = position; }