1 | initial version |
As @break suspected, it was the problem with our wrapper. After code review and slight changes to unit tests to create appropriate conditions, we have confirmed that the problem was that Go GC could collect Go buffer while being used by OpenCV.
During code peer review I looked closely at passing image buffer (allocated in Go) to OpenCV. cgo Passing pointers
This gave me an idea:
We are looing two functions:
- CvRotateOrtaghonal()
- cvFromGoImageNoCopy()
Starting with CvRotateOrtaghonal()
we try to rotate for 90*. First, we take image
and convert it to OpenCV using cvFromGoImageNoCopy()
. cvFromGoImageNoCopy()
will take img. buffer and create OpenCV header for it. In the process, we call C.cvSetData()
to store Go pointer inside C structure for later use. This is a direct violation of "cgo Passing pointers" rule:
C code may not keep a copy of a Go pointer after the call returns.
After this, we need OpenCV image, but inImage
might be or might not be referenced anywhere in Go code anymore.
It certainly isn't referenced inside CvRotateOrtaghonal()
anymore. For Go garbage collector this means, that memory is ready to be collected and can be reused by something else, while OpenCV is rotating this same buffer.
And even if garbage collector does not collect memory it can move it inside virtual address space at the whim, confusing C code in the process.