3

I have a multi-threaded C++ windows project in Visual Studio 2010 which uses Qt (5.1.1) and OpenCV (2.4.8). When I build it in Debug mode everything runs fine, but when I build it in Release mode the program crashes. Both configurations are almost identical (just in Release I have Multi-threaded DLL /MD and in Debug Multi-threaded Debug DLL /MDd), I disabled optimizations for the Release, and even enabled debug to catch the error. What's most weird is that the same piece of code that crashes, runs just fine in another console project.

The error is internal to OpenCV's code, it's not related to my code, my code is just:

void MyProject::findEllipses(QImage &frame, vector<RotatedRect> &ellipses)
{       
    Mat image = Mat(frame.height(), frame.width(), CV_8UC4, frame.scanLine(0));                 

    cvtColor(image, image, CV_RGB2GRAY);
    GaussianBlur(image, image, Size(3, 3), 0, 0, 4);            
    threshold(image, image, treshVal, 255, THRESH_BINARY);

    vector<vector<Point> > contours;               
    Mat contoursImage = image.clone();    
    findContours(contoursImage, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE, Point(0, 0)); 
// ....Mode Code

As I said in Debug the code runs without a problem, findContours calls _contours.create(total, 1, 0, -1, true); (in line 1720 of OpenCV's contours.cpp) and moves on that method....BUT in Release, when I step into _contours.create(total, 1, 0, -1, true), instead of executing that method, the program jumps to void _OutputArray::clear() const (line 1674 of matrix.cpp) and get's trapped in there, because it calls int k = kind(); in it's first line, which, instead of calling cv::kind(), calls:

 int _InputArray::type(int i) const
 {
    int k = kind();

Which calls againg kind() which again calls type() (instead of kind()as it should), making an infinite recursive loop, bringing a stack overflow.

I tried to make a new Visual Studio 2010 project to see if this is a project creation problem but the problem persisted.

My guess is that the function adresses are wrong in release mode so when it tries to call create(), it instead calls another address, making a mess in the stack, but that's just my guess. At first I will blame OpenCV release dlls, but, as I said, in another console project that only runs that particular code, the code runs fine in bot build modes. I don't see how my other threads and code can trigger this behavior, since the error goes down to a wrong function call in OpenCV.

This is way beyond my knowledge and I have no idea how to fix this, I appreciate all the help I can get on this problem, because I already exausted all my ideas to fix it....

EDIT :

I made a small project so anyone can see what's happening.

The files are in: https://app.box.com/s/3owljl44emv57erinrf8

In order to run it, you have to have OpenCV 2.4.8 and Qt 5.1.1 and configure the Visual Studio 2010 project to get the include files from the right places. In the resources folder there is a image that will be loaded, and in the SaraVisualControl.cpp line 20, you have to place the right path to the image, sorry I didnt made this automatic, but I was in a hurry to pack this in a small project. Any other questions about how to run it, please let me know.

EDIT 2

I found this old thread: http://code.opencv.org/issues/2218 the user appears to have the same problem as I have, and just running CMake with OPENCV_CAN_BREAK_BINARY_COMPATIBILITY turned off appears to solve it. But this option is no longer present in the new versions of OpenCV, as stated here http://code.opencv.org/issues/2358. Does anyone knows the implications of this and how it may be related?

Michel Feinstein
  • 13,416
  • 16
  • 91
  • 173
  • 1
    Use the debugger, set a break point in your code, where you call the function that crashes, examine the input - is it all valid, are all input pointers actually pointing to objects, etc. You are probably invoking undefined behavior somewhere. – UldisK Feb 24 '14 at 20:45
  • Well, that exacly how I caught that error...I examined it with breakpoints, and stepped into the functions...in Debug mode it steps where it should...in Release it doesnt...simple as that :) and yes, all the inputs are valid – Michel Feinstein Feb 24 '14 at 20:47
  • The most easy fix might be including the OpenCV source in your project (otherwise ensure compiler switches match) –  Feb 24 '14 at 20:47
  • 1
    Make sure the stack traces shown in your debugger are sane and actually show what's happening, because often the debugger cannot be trusted in release mode. – Frank Osterfeld Feb 24 '14 at 20:48
  • @DieterLücking I recompiled OpenCV myself to get the .pdb of the dlls so I could step into OpenCV functions – Michel Feinstein Feb 24 '14 at 20:49
  • @FrankOsterfeld and how may I be sure of it? – Michel Feinstein Feb 24 '14 at 20:49
  • @mFeinstein you have two builds of OpenCV (please excuse this question)? –  Feb 24 '14 at 20:52
  • @DieterLücking yes, one with debulg dlls and one with release dlls...I made this builds to catch the error, so I could step into OpenCV functions...but all this behavior happened before, when I just had the dlls (debug and release) downloaded from OpenCV website – Michel Feinstein Feb 24 '14 at 21:24
  • How can we reproduce your issue? – László Papp Feb 24 '14 at 22:01
  • I guess just if I upload the solution folder and you reconfigure your visual studio include paths for finding Qt and OpenCV includes....any better ideas? – Michel Feinstein Feb 24 '14 at 22:07
  • @LaszloPapp check the update, I placed the files so you can reproduce the issue – Michel Feinstein Feb 25 '14 at 01:36
  • That kind of weird behavior (jumps to unrelated functions) can also be caused by memory corruption (e.g. use of uninitialized pointers, writing stuff beyond an array's boundaries, etc) in your code, though the offending line is not easy to locate... – BConic Feb 27 '14 at 10:51
  • @AldurDisciple I thought about it, but I cant find anything like it – Michel Feinstein Feb 28 '14 at 09:19
  • Are you sure that the error is within your function `MyProject::findEllipses(...)` ? If you comment out the call to this function, is an error still occuring (the same or another), or does this run fine ? – BConic Mar 03 '14 at 08:58
  • yes, and actually, I just need to comment `findContours()` to "remove" the error...that's one of the main things that makes me believe it's a OpenCV problem and not mine – Michel Feinstein Mar 04 '14 at 05:20
  • I had a similar problem once, which was caused by the use of `std::vector` with the SURF extraction function. The problem was that it was allocated internally by OpenCV but released in my code by the destructor when leaving the function. If I remember correctly, I solved it by using an appropriate `cv::Mat` instead of the `std::vector`. Did you try that already ? – BConic Mar 04 '14 at 08:56
  • You can set only one thread to confirm whether the problem is leaded by multi-threads. If this problem only exists in multi-threads, please check multi-threads' interaction. – Charlie Mar 05 '14 at 03:04

5 Answers5

4

I encountered similar symptoms in the past, when mixing VC runtime versions. If you're working in VC2010 and OpenCV 2.4.8 was built on 2012 or even 2013, your ABI does not match. E.g., the layout in memory of std::vector is different, maybe the order of some methods in a vtable somewhere changed, etc.

An easy way to test this is to inspect the 'Modules' window while debugging and look for runtime dll's of a later version. Yours is msvcr100d.dll, if you see msvcr110d or 120d - this might be the source. (assuming both you and OpenCV link dynamically to the CRT - which I cannot tell).

Ofek Shilon
  • 14,734
  • 5
  • 67
  • 101
  • I don't this that's my case because I recompiled the dlls myself in order to check this error, and I did it in VS2010. I checked the modules window and I only have, msvcr100.dll, msvcp100.dll and msvcrt.dll – Michel Feinstein Mar 06 '14 at 02:23
  • Also, before I used my own libs, I was getting them from the vs2010 folder in OpenCV – Michel Feinstein Mar 06 '14 at 16:36
  • Ok. Another candidate is some header discrepancy when compiling your project/openCV. But before testing that - I suggest you make sure the call to _contours.create isn't happening in another line. In release the match between code lines and instructions is, shall we say, heuristic - you can try and set a breakpoint in the entrance to _contours.create and verify that it is not hit in Release. – Ofek Shilon Mar 07 '14 at 07:30
  • I did it, and it wasnt being triggered...this is really frustrating to me because it's my first C++ project so I feel kinda afraid of using C++ again. I feel like I have no control over the program – Michel Feinstein Mar 09 '14 at 21:26
  • Ok - please compile just the two files that call and implement _contours.create(), with 'Show Includes' set to yes, and say if you see any discrepancy in the paths of included headers. Also - it would make it much easier to help you if you could trim down the example you uploaded to something more self contained. Can you reproduce the problem without Qt dependency? Can you include in the package just the relevant OpenCV headers? – Ofek Shilon Mar 10 '14 at 22:21
  • I ma not sure...my console application example has no problems, just the GUI one...what do you think? – Michel Feinstein Mar 11 '14 at 23:16
  • I looked it more further and I found this: http://code.opencv.org/issues/2218 it's an old thread and it appears be the same problem as I have, but I cant find that CMake option anymore in this new build...does it ring any bells for you about what could be going on? – Michel Feinstein Mar 18 '14 at 21:20
  • So it seems a header discrepancy after all.. I'm not aware of this flag. If you can't find a central location #defining it, you can just search for it in the sources and set it manually in every file that uses it. – Ofek Shilon Mar 20 '14 at 15:38
0

The debug and release are different in memory allocations. Usually in Debug mode that allocs are bigger. May be you abuse some openCV call, but you don't aware of it. I would do next actions:

  1. Validate that the frame is ok. May be it is too big, or width or height are not initiated;

  2. Validate that after next line the image var is OK

    Mat image = Mat(frame.height(), frame.width(), CV_8UC4, rame.scanLine(0));

  3. Is it OK to call cvtColor while the 1st and 2nd param are the same (may be you abuse the CV here)

  4. Is it OK to call GaussianBlur while the 1st and 2nd param are the same? Try to put different 2nd param

  5. The same is with threshold function call

  6. Check that after image.clone call, the countoursImage is a valid matrix.

vmax33
  • 643
  • 5
  • 13
  • I cant see how this functions will be a problem, since this same code runs nice in another project (a console project)...and yes, all the functions that use the same input and output are expected to do so. – Michel Feinstein Mar 06 '14 at 02:30
0

I'm guessing: In addition to checking that the libraries are all correct themselves, check that you specify all libraries in the same order (in all builds). Otherwise, the linker might bind function names to different implementations during the final linker stage.

Sascha Wedler
  • 395
  • 3
  • 7
  • I checked the Linker>Inputs and all are in the same order...should I aslo check somewhere else? – Michel Feinstein Mar 06 '14 at 02:27
  • You wrote that you checked it this way: You stepped into `_contours.create(total, 1, 0, -1, true);` in a Debug-Build and into `_contours.create()` in a Release-Build. I don't know the code. But, those are obviously two different functions. Why do you expect identical behavior? Is one usually calling the other? – Sascha Wedler Mar 06 '14 at 03:31
  • If not, then the linker is in fact binding the wrong functions to your [symbols](http://stackoverflow.com/a/7048625/1500022). Have you tried linking statically? – Sascha Wedler Mar 06 '14 at 03:41
  • Try a more [verbose build](http://stackoverflow.com/questions/1211841/how-can-i-make-visual-studios-build-be-very-verbose), maybe you notice something on the build command line. And if everything else fails, use absolute path names for the LIBs in your Studio project configuration. This will ensure that you actually use all the right LIBs (including the system dependencies). If the error then still occures, it must have something to do with the Build Flags. – Sascha Wedler Mar 06 '14 at 04:01
  • Sorry, my bad, it's the same function, I just didnt want to type it 2 times, so I abreviated with the `()`, I will edit it so it will be clear. – Michel Feinstein Mar 06 '14 at 16:23
  • Yes I tried statical build and the same problem arises – Michel Feinstein Mar 06 '14 at 16:24
  • I tried the "more verbose" option and that's the output window: http://pastebin.com/Gw7iMVtk – Michel Feinstein Mar 06 '14 at 16:35
  • Please also provide the verbose output for the other build (the one that works). Then we can compare both and maybe find the compiler option that causes the trouble. – Sascha Wedler Mar 06 '14 at 20:49
  • Also, please try option "/Wall" or "/W4" to ensure you see all [warnings](http://msdn.microsoft.com/en-us/library/thxezb7y.aspx) from cl.exe. – Sascha Wedler Mar 06 '14 at 21:16
  • First, ensure that the order of your includes is identical, which it is not, yet. This can be irrelevant, but we don't know yet. – Sascha Wedler Mar 06 '14 at 21:36
  • Your two build-logs look strangely different: One of them has two cl.exe invocations, the other has only one. That makes the compare unnecessarily difficult. – Sascha Wedler Mar 06 '14 at 21:51
  • The only difference in your build flags so far, is "/MDd /D QT_NO_DEBUG /D NDEBUG" which is uncommon. Usually a release build also uses optimizations, etc. However, this should not matter. – Sascha Wedler Mar 06 '14 at 21:52
  • Please have the includes in the same order, and add the /Wall option, and make a full clean rebuild, for the debug and release version. Then test it again. – Sascha Wedler Mar 06 '14 at 21:56
  • Next, you could look-up every occurrence of "_DEBUG" in your sources (including the Open-CV sources), to find out about the differences between debug and release mode. If there are any. – Sascha Wedler Mar 06 '14 at 22:07
0

I had the same issue.I was using Qt 5.1.1 and opencv248 and my application was crashing after returning from findcontours. Turns out I was using the vc10 libs in the pro file and the corresponding dlls whereas the Qt compiler being used was msvc2013. Switching to the vc12 folder in opencv 248 solved the problem for me.

zeerak
  • 388
  • 2
  • 11
-1

Have you checked your opencv libraries for Release version. Opencv has different set of libraries for Release and Debug version. if you have accedently included debug libraries in the release mode. your code will compile with no error but will throw excecption when executed. To check your libraries goto

Project->Properties->Configuration Properties->linker->Input->Additional Dependencies.

make sure none of your Opencv libraries ends with "d" for release mode.

library for Release : 'opencv_core248.lib'

library for Debug : 'opencv_core248d.lib'

notice the d at the end for debug mode.

I hope this would be helpful.

Genutek
  • 387
  • 1
  • 5
  • 11
  • Yes, I am aware of this and I am sure they are all correct, I triple checked for this and I also compiled my own OpenCV libraries in order to debug the error further. You can see in the .rar attached all the debug and release dlls in the right folders – Michel Feinstein Feb 28 '14 at 09:21