gocv icon indicating copy to clipboard operation
gocv copied to clipboard

Native Byte Buffer - segmentation fault

Open HrachMD opened this issue 1 year ago • 1 comments

In some cases after processing you want to have your data in memory instead of directly saving to file. For example sending over network, uploading to S3 bucket etc. Recently I've faced a problem, when data is more ~500-600Kb then accessing the data previously read from the buffer cause fatal error - memory fault.

Description

In particular case - I've resized the image and used IMEncodeWithParams to get byte buffer.

buf, err = gocv.IMEncodeWithParams(gocv.PNGFileExt, myMat, []int{gocv.IMWritePngCompression, compr})
if err != nil {
    // some logic
    return
}
defer buf.Close()

Then to upload to S3 bucket or/and content serving I need to create a reader object:

// before buffer closing
myReader := bytes.NewReader(buf.GetBytes()) // On this line I had a fatal error.

-or-

b := buf.GetBytes()
myReader := bytes.NewReader(b) // The same error.

I have tried a lot of approaches and the problem has been solved this way:

b := make([]byte, buf.Len())
copy(b, buf.GetBytes())
myReader := bytes.NewReader(b) // This works fine!

Steps to Reproduce

  1. Just take any image (jpg or png) with size of 1-2Mb
  2. Create gocv.Mat
  3. Then get buffer from IMEncodeWithParams (any compression or format, just preserve file size over ~500-600Kb)
  4. Try to create an io.Reader from the byte slice which returned the GetBytes() method

Your Environment

Docker container, Droplet on Digital Ocean - 1vCPU, 2Gb Ram, 50Gb storage

  • Operating System and version: Debian - bullseye
  • OpenCV version used: 4.6.0
  • How did you install OpenCV? (git clone https://github.com/hybridgroup/gocv.git, make install)
  • GoCV version used: 0.31.0
  • Go version: 1.18.5
  • Did you run the env.sh or env.cmd script before trying to go run or go build? No

HrachMD avatar Aug 03 '22 15:08 HrachMD

It seems that calling buf.GetBytes() will not return a copy of Mat. So after calling buf.Close() and trying to access the variable b := buf.GetBytes() it will give a signal SIGSEGV: segmentation violation error.

Using copy(b, buf.GetBytes()) worked for me. Thanks for posting.

JoshChristie avatar Aug 11 '22 23:08 JoshChristie