bytedeco / javacpp-presets

The missing Java distribution of native C++ libraries
Other
2.68k stars 744 forks source link

Frequent crash with opencv_core.mean() function #811

Open b005t3r opened 5 years ago

b005t3r commented 5 years ago

I'm getting this weird native code crash once in a while:

Stack: [0x00007fb3b8083000,0x00007fb3b8184000],  sp=0x00007fb3b8181c98,  free space=1019k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [libopencv_core.so.4.0+0x215726]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  org.bytedeco.opencv.global.opencv_core.mean(Lorg/bytedeco/opencv/opencv_core/Mat;Lorg/bytedeco/opencv/opencv_core/Mat;)Lorg/bytedeco/opencv/opencv_core/Scalar;+0

...

siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x0000000000000005

You can see that the crash originated in: org.bytedeco.opencv.global.opencv_core.mean

Is there any way to check what this actually might be (there's no information logged to std err or std out)?

saudet commented 5 years ago

We can always use something like Valgrind or Address Sanitizer for that: https://github.com/deeplearning4j/libnd4j/wiki/Debugging-libnd4j http://btorpey.github.io/blog/2014/03/27/using-clangs-address-sanitizer/

b005t3r commented 5 years ago

Actually, I think I found the cause of this (however, haven't tried a fix yet).

Here's my example code first:

Mat img = ... // created with byte[]
Mat region = new Mat(img, rect); // cut out just a part of the image for processing

MatVector channels = new MatVector();
split(region, region);

Mat red = channels.get(2);
Mat green = channels.get(1);
Mat blue = channels.get(0);

threshold(green, green, 40, 255, THRESH_TOZERO); // keep pixels above value

Mat redMask = new Mat();
compare(green, red, redMask, CMP_GT);

Mat blueMask = new Mat();
compare(green, blue, blueMask, CMP_GT);

Mat mask = new Mat();
threshold(green, mask, 1, 255, THRESH_BINARY); // keep pixels above value

bitwise_and(redMask, mask, mask);
bitwise_and(blueMask, mask, mask);

// sometimes more or less at this point I notice that red, green and blue have been dellocated internally - set to 0 cols and rows, etc. - but heir corresponding masks aren't

I'll try to work around that by allocating red, green and blue and putting them in the MatVector before calling split(). I hope that works, but it looks like an issue with memory management in JavaCPP (at least that's my best guess at the moment).

saudet commented 5 years ago

Use PointerScope to get more control over memory management: http://bytedeco.org/news/2018/07/17/bytedeco-as-distribution/

b005t3r commented 5 years ago

I'll try that as well, but could you explain how it works exactly (and does it have a negative impact on performance)? Does it "lock" or allocations until the scope is released, so nothing allocated in that scope will get released before exiting the scope?

saudet commented 5 years ago

Something like that, as explained on the post and in the docs. If there's anything unclear after reading those, let me know.

saudet commented 4 years ago

Maybe this was a bug with OpenCV? Please try again with OpenCV 4.3.0 and see what that gives.