GCC parameter order causes segmentation fault in embree 2.0

Alec Jacobson

October 29, 2013

weblog/

I was trying to compile and link against embree 2.0 (checked out from svn yesterday) on a Mac OS X 10.7.5 iMac with a 3.4 GHz Intel Core i7. I compiled Embree as per the instructions on the website using cmake and make. My default c/c++ compiler is gcc 4.7.2.

Upon trying to compile and run with embree I found that certain gcc parameter orders cause embree's rtcinit function to crash at runtime. Here is a minimal C++ program to reproduce the problem, save it in bug.cpp:

#include <embree/include/embree.h>
#include <iostream>

class EmbreeIntersector
{
  public:
    EmbreeIntersector()
    {
      using namespace std;
      cout<<"EmbreeIntersector(): before rtcInit()"<<endl;
      embree::rtcInit();
      cout<<"EmbreeIntersector(): after rtcInit()"<<endl;
    }
} ei;

int main()
{
  using namespace std;

  return 0;
}

If I compile with:

g++ \
  -I/usr/local/igl/libigl/external/embree/embree \
  -I/usr/local/igl/libigl/external/embree/ \
  -L/usr/local/igl/libigl/external/embree/bin \
  -o bug \
  -lembree \
  bug.cpp  \
  -lsys

then running ./bug seems to execute correctly. I see as output:

EmbreeIntersector(): before rtcInit()
EmbreeIntersector(): after rtcInit()

However, if I compile with:

g++ \
  -I/usr/local/igl/libigl/external/embree/embree \
  -I/usr/local/igl/libigl/external/embree/ \
  -L/usr/local/igl/libigl/external/embree/bin \
  -o bug \
  bug.cpp  \
  -lembree \
  -lsys

then running ./bug I see:

EmbreeIntersector(): before rtcInit()
Segmentation fault: 11

I'm guessing that this will be chalked up to a GCC bug. But is there any reason to expect this sort of behavior from gcc or embree?

Update: Seems to also happen in a separated compile and link build. Compile first with:

g++ \
  -I/usr/local/igl/libigl/external/embree/embree \
  -I/usr/local/igl/libigl/external/embree/ \
  -o bug.o \
  -c bug.cpp

Then this parameter order for linking produces a good binary:

g++ \
  -o bug \
  -L/usr/local/igl/libigl/external/embree/bin \
  -lembree \
  bug.o \
  -lsys

And equivalently here's the bad order:

g++ \
  -o bug \
  -L/usr/local/igl/libigl/external/embree/bin \
  bug.o \
  -lembree \
  -lsys

Update: I emailed embree support and immediately got a helpful response:

You are calling the rtcInit function from the constructor of a global variable "ei". This causes problems, as other global variables that Embree needs have to be initialized before your global variable. Using Embree this way is not supported. Create an instance of your EmbreeInstersector function using the new operator in the main function fixes the problem.

Seems that the GCC link order also determines the order of initializations for global variables. Indeed, dynamically instantiating my EmbreeIntersector class using new EmbreeIntersector() resolves this issue.