Bug 51460 - [4.6/4.7 Regression] Struct with two boost mutexes allocated on the heap inside of a while loop causes compiler segfault
Summary: [4.6/4.7 Regression] Struct with two boost mutexes allocated on the heap insi...
Status: RESOLVED DUPLICATE of bug 48600
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.6.2
: P3 normal
Target Milestone: 4.6.3
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on: 48600
Blocks:
  Show dependency treegraph
 
Reported: 2011-12-08 00:16 UTC by Faraaz Sareshwala
Modified: 2011-12-09 09:10 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 4.5.3
Known to fail: 4.6.2, 4.7.0
Last reconfirmed: 2011-12-08 00:00:00


Attachments
preprocessed source (gzipped because too large otherwise) (233.61 KB, application/x-gzip)
2011-12-08 00:46 UTC, Faraaz Sareshwala
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Faraaz Sareshwala 2011-12-08 00:16:43 UTC
Hello,

This is my first gcc bug report so I apologize if this is in the wrong place. I tried searching for previously reported bugs, but couldn't find anything that was similar to my bug report.

gcc segfaults while trying to compile the following program:

#include <boost/thread/mutex.hpp>

struct foo {
    boost::mutex bar;
    boost::mutex baz;
};

int main() {
    while(true) {
        foo* f = new foo;
        continue;
    }
    return 0;
}

My compile command is

$ g++ -g -O3 bug.cc /usr/lib64/libboost_thread-gcc43-mt-1_37.a

The full output of verbose gcc compile is:

[fsareshwala@fsareshwala-l /tmp]% g++ -v -save-temps -g -O3 lol.cc /usr/lib64/libboost_thread-gcc43-mt-1_37.a              [ /tmp ]
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.2-5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.2 (Debian 4.6.2-5) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-g' '-O3' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/4.6/cc1plus -E -quiet -v -imultilib . -imultiarch x86_64-linux-gnu -D_GNU_SOURCE lol.cc -mtune=generic -march=x86-64 -g -fworking-directory -O3 -fpch-preprocess -o lol.ii
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/4.6
 /usr/include/c++/4.6/x86_64-linux-gnu/.
 /usr/include/c++/4.6/backward
 /usr/lib/gcc/x86_64-linux-gnu/4.6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-g' '-O3' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/4.6/cc1plus -fpreprocessed lol.ii -quiet -dumpbase lol.cc -mtune=generic -march=x86-64 -auxbase lol -g -O3 -version -o lol.s
GNU C++ (Debian 4.6.2-5) version 4.6.2 (x86_64-linux-gnu)
        compiled by GNU C version 4.6.2, GMP version 5.0.2, MPFR version 3.1.0-p3, MPC version 0.9
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++ (Debian 4.6.2-5) version 4.6.2 (x86_64-linux-gnu)
        compiled by GNU C version 4.6.2, GMP version 5.0.2, MPFR version 3.1.0-p3, MPC version 0.9
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 16d7c73e7d9f05ccb8ae4d28e530e18c
g++: internal compiler error: Segmentation fault (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.6/README.Bugs> for instructions.

Please let me know if I have forgotten anything you need.

Thank you,
Faraaz Sareshwala
Comment 1 Jonathan Wakely 2011-12-08 00:40:10 UTC
> Please submit a full bug report,
> with preprocessed source if appropriate.
> See <file:///usr/share/doc/gcc-4.6/README.Bugs> for instructions.
> 
> Please let me know if I have forgotten anything you need.

Preprocessed source and the version of Boost would help, thanks
Comment 2 Faraaz Sareshwala 2011-12-08 00:46:04 UTC
Created attachment 26019 [details]
preprocessed source (gzipped because too large otherwise)
Comment 3 Faraaz Sareshwala 2011-12-08 00:46:58 UTC
(In reply to comment #1)
> > Please submit a full bug report,
> > with preprocessed source if appropriate.
> > See <file:///usr/share/doc/gcc-4.6/README.Bugs> for instructions.
> > 
> > Please let me know if I have forgotten anything you need.
> 
> Preprocessed source and the version of Boost would help, thanks

I've attached the preprocessed source as a gzipped plain text file. It's over 2 mb and is too large to attach it as plain text.

The boost version is boost 1.37.0
Comment 4 Richard Biener 2011-12-08 10:05:34 UTC
Confirmed with -O1.

Program received signal SIGSEGV, Segmentation fault.
0x0000000000bb9511 in VEC_edge_base_index (vec_=0x7ffff52e2cf8, ix_=0, file_=Cannot access memory at address 0x7fffff7feff8
)
    at /space/rguenther/src/svn/gcc-4_6-branch/gcc/basic-block.h:64
64      DEF_VEC_P(edge);
(gdb) bt
#1  0x0000000000bb9500 in ei_edge (i=...)
    at /space/rguenther/src/svn/gcc-4_6-branch/gcc/basic-block.h:671
#2  0x0000000000bb942d in ei_cond (ei=..., p=0x7fffff7ff0e8)
    at /space/rguenther/src/svn/gcc-4_6-branch/gcc/basic-block.h:692
#3  0x0000000000bbdd75 in predict_paths_for_bb (cur=0x7ffff19a3888, 
    bb=0x7ffff1b2f270, pred=PRED_CONTINUE, taken=NOT_TAKEN)
    at /space/rguenther/src/svn/gcc-4_6-branch/gcc/predict.c:1801
#4  0x0000000000bbdda6 in predict_paths_for_bb (cur=0x7ffff1b2f270, 
    bb=0x7ffff1b2f270, pred=PRED_CONTINUE, taken=NOT_TAKEN)
    at /space/rguenther/src/svn/gcc-4_6-branch/gcc/predict.c:1836
...

we endlessly recurse in predict_paths_for_bb walking

  for (son = first_dom_son (CDI_POST_DOMINATORS, cur);
       son;
       son = next_dom_son (CDI_POST_DOMINATORS, son))
    predict_paths_for_bb (son, bb, pred, taken);

(we never do anything else in the loop above it).  Sequence of recursion
is (cur, bb): (7, 9) (3, 3) (9, 9) (7, 9) ...

;; basic block 2, loop depth 0, count 0
;; prev block 0, next block 9
;; pred:       ENTRY (fallthru,exec)
;; succ:       9 [100.0%]  (fallthru)
<bb 2>:

;; basic block 9, loop depth 1, count 0
;; prev block 2, next block 3
;; pred:       2 [100.0%]  (fallthru) 7 (fallthru,exec)
;; succ:       3 [100.0%]  (fallthru,exec) 8 (eh,exec)
<bb 9>:
f_1 = operator new (80);
D.102841_9 = &f_1->bar;
boost::mutex::mutex (D.102841_9);

;; basic block 3, loop depth 1, count 0
;; prev block 9, next block 4
;; pred:       9 [100.0%]  (fallthru,exec)
;; succ:       7 [100.0%]  (fallthru,exec) 4 (eh,exec)
<bb 3>:
D.102840_10 = &f_1->baz;
boost::mutex::mutex (D.102840_10);
goto <bb 7>;

;; basic block 7, loop depth 1, count 0
;; prev block 6, next block 8
;; pred:       3 [100.0%]  (fallthru,exec)
;; succ:       9 (fallthru,exec)
<bb 7>:
// predicted unlikely by continue predictor.
goto <bb 9>;

... so it seems post-dominators do not honor EH-edges, or at least
it is inconsistent with the way we add fake exit edges for infinite
loops.
Comment 5 Richard Biener 2011-12-08 10:43:21 UTC
Reduced testcase that fails with both 4.7 and 4.6:

class mx {
public:
    mx();
};

int main()
{
  while (true) {
      mx *bar = new mx;
      mx *baz = new mx;
      continue;
  }
  return 0;
}

4.5 happens to work.
Comment 6 Richard Biener 2011-12-08 10:58:54 UTC
For the reduced testcase we recurse endlessly through

      /* If there is non-abnormal path leaving e->src, predict edge
         using predictor.  Otherwise we need to look for paths
         leading to e->src.  */
      if (found)
        predict_edge_def (e, pred, taken);
      else
        predict_paths_for_bb (e->src, e->src, pred, taken);

instead.  That recursion is new in 4.6.  I think it wants to recurse
not to e->src but get_immediate_dominator (CDI_DOMINATORS, cur) (outside of the loop?)

Caused by rev. 161691, thus Honza.
Comment 7 Andrew Pinski 2011-12-08 18:38:46 UTC
I think this is a dup of bug 48600 which also deals with predict_paths_for_bb .
Comment 8 Richard Biener 2011-12-09 09:10:38 UTC
indeed.

*** This bug has been marked as a duplicate of bug 48600 ***