Initializing static cv::Mat with cv::Mat::zeros causes segmentation fault
Hi everybody,
I have a problem initializing a static cv::Mat with the static method cv::Mat::zeros() using the GCC compiler version 4.7.1. (Opensuse 12.2). It compiles fine, but causes a segmenation fault during runtime.
Here is a minimal code example:
#include <iostream>
#include <opencv2/core/core.hpp>
static cv::Mat staticMatOne(3,3,CV_32FC1);
static cv::Mat staticMatTwo(cv::Mat::zeros(3,3,CV_32FC1)); // This line causes the segmentation fault
int main()
{
std::cout << "Hello World" << std::endl;
return 0;
}
It is compiled with
gcc -o OpencvTest OpencvTest.cpp -I{_PATH_TO_OPENCV_}/include -lopencv_core -lstdc++ -lm -lpthread -lrt -lz -L{_PATH_TO_OPENCV_}/lib
where {_PATH_TO_OPENCV_} points to the OpenCV installation directory. I both tried the newest version of OpenCV from the git repository as well as the released version 2.4.3. and the released version 2.3.1. All versions have been linked as static libraries.
The output of gcc --version is
gcc (SUSE Linux) 4.7.1 20120723 [gcc-4_7-branch revision 189773]
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The output of gdb is
Program received signal SIGSEGV, Segmentation fault.
0x0804b616 in cv::MatExpr::operator cv::Mat (this=0xbffff330) at {_PATH_TO_OPENCV_}/include/opencv2/core/mat.hpp:1222
1222 op->assign(*this, m);
Missing separate debuginfos, use: zypper install glibc-debuginfo-2.15-22.6.4.i686 libgcc47-debuginfo-4.7.1_20120723-1.1.1.i586 libstdc++47-debuginfo-4.7.1_20120723-1.1.1.i586 zlib-debuginfo-1.2.7-2.1.2.i586
(gdb) bt
#0 0x0804b616 in cv::MatExpr::operator cv::Mat (this=0xbffff330) at {_PATH_TO_OPENCV_}/include/opencv2/core/mat.hpp:1222
#1 0x0804b2f9 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at OpencvTest.cpp:7
#2 0x0804b361 in _GLOBAL__sub_I_main () at OpencvTest.cpp:13
#3 0x08202282 in __libc_csu_init (argc=1, argv=0xbffff504, envp=0xbffff50c) at elf-init.c:125
#4 0xb7cbf36a in __libc_start_main () from /lib/libc.so.6
#5 0x0804b131 in _start () at ../sysdeps/i386/elf/start.S:119
It compiles and runs fine using gcc version 4.3.2 (Opensuse 11.1) and gcc version 4.6.2 (Opensuse 12.1)
It also runs without a segmentation fault if the line
static cv::Mat staticMatTwo(cv::Mat::zeros(3,3,CV_32FC1));
in the example is deleted.
The problem is that the static instance (modules/core/src/matop.cpp line 205)
static MatOp_Initializer g_MatOp_Initializer;
gets not constructed before the construction of the static instance of the matrix. Does anybody has an idea of how to solve this initialization problem. It would be hard for us not to use a static instance of a cv::Mat in this case.
I tried to reproduce it but I have gcc 4.5.2 and i don't have any issue with that code. I don't know if it is just a version number problem. Anyway, have you tried to initialize the matrix like
static cv::Mat staticMatTwo = cv::Mat::zeros(3,3,CV_32FC1);
S.
I tried the version you proposed. But it leads to the same behaviour => segmentation fault during execution. The Problem only occurs if I compile with gcc 4.7.1 with gcc 4.6.2 everything works fine. The problem can also be fixed if you link against dynamic OpenCV libraries. It seems that the initialization of the matrix initializer is finished before the initialization of staticMatTwo in this case. J.