Opencv stack overrun in dll?

Unhandled exception at 0x00E61A6C in testdll_1.exe: Stack cookie instrumentation code detected a stack-based buffer overrun.

Here’s what i’ve done, i’m doubting that some class like mat or Net caused this problem,

class ocr()
{
private:
Net net
public:
ocr(){net = readnetfromonnx(path)}
~ocr(){nothing here}
void recognizefunc1(Mat &mat1, Net &net, double &result)
}

can you add more info, like os, compiler, opencv version ? where/how did you get the libs ? how did you build / link your dll ?

also, if you want anyone to repeat it, it would need a minimal, reproducable example, not the useless pseudocode above

@iceburger

I believe you have a C++ coding problem, I don’t believe it’s OpenCV related.

May be you pass a local Mat or Net, and the function needs a pointer to it to use later after that variable lifetime.

same question:

Here’s the problem, Is it possible that the Net type cause this situation?
c++ - OpenCV readNetFromONNX function cause stack overrun in dll - Stack Overflow

I’m using Opencv4.5.3 x86 static lib with cmake3.21.2, vs2015,compiler should be default, windows8,the question has alse been discovered on other version. Some others said that the readNetFromonnx(“path”)would cause the memory location error

simply created a dll like this:

#include …(all opencv’s static lib in x86)
using namespace …
(…)dllexport ocr:
private:
Net net;
public:
ocr(){net= readNetFromONNX("./1.onnx")}
~ocr(){net.~Net()}
void showimg(string path){ Mat img = imread ; imshow() ; cv::waitKey;}

using the dll by coping it and #pragma comment (lib, …)
this still cause the problem of stack overrun.
I’ve just tried
ocr read;
return;
}
the function works fine, but after the return the error shows up, How so?
Any other ways to create a Net type and allocate memory location suggest? Thanks!(perhaps like getMemoryConsumption())

so, you must have built that locally, right ?

please run a debug build, to check vector overruns etc.

not needed.

please also try without the dll (put all code into main())

if that works, check your dll project for weird things (x86/64, debug/release, managed code, whatever)

Hi, these indeed are my own built libs, I’ve tried debug with main contained only:

ocr read; (the class dllexported)
return;

and checked x86, release/debug, and the code I have was only 1 function with imshow(’’), I wasn’t even using this function. APPLICATION of this class without dll works fine.
it still goes:
Run-Time Check Failure #2 - Stack around the variable 'read' was corrupted.
net.~Net seems not needed indeed, I’m doubting that the function readNetFromONNX() leads to this, but not the Net, Is it possible that link static libraries of opencv to a DLL would cause this.

no, i mean: dont build a dll at all (put all the code into main())

then your SO post mentions “static MFC libs”. get rid of that. use an empty project template with absolutely NO assumptions

I think I get your idea, which means build a simple app, However I’m trying to build a dll to handle it to someone else, which means it’s not right approach for me.
I’ve just found out a possible reason of the stack overrun error! while link Opencv’s static libs to a dll, opencv would like to use another heap(BUT NOT THE LOCAL HEAP). It’s like when I declare a Net/vector type, etc, in my dll, Opencv can’t run the destructor .
This would cause the memory location error,
which means Net net= readNetFromONNX(path) is probably a wrong way, Would you please show any way of solution of this?
Define like this wouldn’t help, Net net[300]
Maybe should I try pointer or just allocate memory to all similar function?

no, that’s entirely correct.

please show, how you build your dll (im sure the problem is there)

mate, your github issue shows 2 (different !) definitions of the ocr class.

ONE ONLY IS ALLOWED !

clean up that first !

both dll and main code need to refer to the same header/class definition

it constructs one version in the dll, and deletes another, no wonder, your stack is corrupted …

#include "stdafx.h"
clear sign, this has some MFC BS in it. dont do that !

Using mfc in a static library would cause error of:
unresolved external symbol _imp_BitBlt@36, _imp_CombineRgn@16 and so on.
so I’m using standard windows libraries.

Is it possible that cut the header of makedll.hpp into makedll.cpp?
I’m wondering using opencv_world453.dll instead of static libs, I’ve heard that some static libs would cause not using local heap error.

Hi I have tried copied the hpp and it goes well!
But however this would lead to a problem,
What am I supposed to do If I have Net and Mat type in my class’s private?
What about other member functions that are I’m not willing to show to others
This made it impossible to exclude whole Opencv’s hpps while releasing my own dll.

private or not does not matter.
if you dont want to expose opencv data types
(how would you pass images ?)
you might “wrap” it, using your own types.

read up on “PIMPL”, please. somethiing like this:


// header
class Impl; // forward ref

class ocr { // hides opencv types
   std::shared_ptr<Impl> impl;
public:
   ocr();
   void read_image(string name);
};
// dll cpp

class Impl { // uses opencv types
public:
   void read_image(string name) {
         cv::Mat m = cv::imread(name);
         ... 
   }
};

ocr::ocr() {
    impl = new Impl();
}
void ocr::read_image(string name)
   impl->read_image(name);
}

(also read up on interfaces / virtual functions, that’s a MUST !)

1 Like

THANKS for that suggestion, it helped indeed!!
I was trying to hide Mat type is because that the environment somebody going to use dll with is different from mine, who’s making the dll.
eg. I’m makeing dll with opencv4.5.3 which contains dnn module.
But the env using this would be opencv2 instead.

I’m able to hide Net type with class’s interface right now.
I’m wondering that is the Mat type being changed in previous version? Or maybe I should transfer a unsigned char* a = mat.data() and Its’ h,w,rgb_type instead?
I’m afraid that there would be a little difference while the mat meetings with different type around rgb,rbg, and gray type. It might be a little difficult to verify the img being transfered right or not without opencv.