You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am getting a segfault that I'd guess, based on observed behavior, is due to a race condition with how vips or govips manages its memory internally. I'm also open to it being something in my code, though it hasn't seemed that way in my research on it. Please let me know if I'm wrong!
I've tested with govips 2.7.1, 2.8.0, and 2.9.0. I'm using vips 8.12.1, but have also tested with vips 8.11.3. It's reproducible for me in AWS Lambda using an Alpine Docker image and a fairly large input file or two, both of which I unfortunately cannot share.
For an individual worker, I'm running 12 concurrent vips load/transform/save operations. Overall, this is a ballpark estimate and based on a few different inputs I've been testing with, but I expect to see this error in about 1 in 40,000 of those operations. This sounds pretty rare, but for my use case, it means I'm basically guaranteed a segfault when processing certain input files. (Input files are videos that we're processing frame by frame.) When it fails, it doesn't always fail on the same image inputs (i.e. it is not related purely to the content), though it does happen more often for images with higher quality/resolution.
I cannot reproduce this locally, maybe because I just can't run enough operations, or maybe because my computer is faster than a Lambda worker, or because I'm on OSX. I'm not sure. But it is reliably reproducible for me in AWS Lambda (10 GB memory) with longer and larger inputs.
Here is a repo that shows a simplified version of how I'm using govips. The relevant code is in main.go. The "parmap" helper is short for "parallel map," and is an almost-identical port of what I'm using for real. I'm hoping that I'm just not doing something correctly, so please let me know if anything stands out to you. Happy to give suggestions a try.
My temporary workaround for this issue is to remove the canvas.Close() line. Without that, I have yet to encounter the segfault. Interestingly, if I also remove file1.Close() and file2.Close(), I reliably encounter the segfault again. So I left those alone. To avoid a memory leak from not freeing the canvas, I launch a separate process to wrap the vips compositing code, then let the OS clean it up when the compositing process terminates. This solves my problem in the short term, but it has me worried about dealing with segfaults in the future.
About half the time, the error stack shows the call to thumbnail_image():
Coincidentally, I'm looking into an (accidental) double-free, on govips v2.11.0, libvips 8.10.5, when calling *vips.ImageRef.Close() twice (which should be okay from the looks of the Go source).
Could it be that a nil overlay here causes the function to still call canvas.Insert() with a nil overlay? And that, internally, this calls clearImage() that somehow cleans up the canvas reference as well?
(My current hunch in out setup is that *vips.ImageRef.Close() neatly uses a lock before calling clearImage on an internal reference, but it's not guaranteed that all code paths using clearImage also set the internal reference in ImageRef to nil)
I am getting a segfault that I'd guess, based on observed behavior, is due to a race condition with how vips or govips manages its memory internally. I'm also open to it being something in my code, though it hasn't seemed that way in my research on it. Please let me know if I'm wrong!
I've tested with govips 2.7.1, 2.8.0, and 2.9.0. I'm using vips 8.12.1, but have also tested with vips 8.11.3. It's reproducible for me in AWS Lambda using an Alpine Docker image and a fairly large input file or two, both of which I unfortunately cannot share.
For an individual worker, I'm running 12 concurrent vips load/transform/save operations. Overall, this is a ballpark estimate and based on a few different inputs I've been testing with, but I expect to see this error in about 1 in 40,000 of those operations. This sounds pretty rare, but for my use case, it means I'm basically guaranteed a segfault when processing certain input files. (Input files are videos that we're processing frame by frame.) When it fails, it doesn't always fail on the same image inputs (i.e. it is not related purely to the content), though it does happen more often for images with higher quality/resolution.
I cannot reproduce this locally, maybe because I just can't run enough operations, or maybe because my computer is faster than a Lambda worker, or because I'm on OSX. I'm not sure. But it is reliably reproducible for me in AWS Lambda (10 GB memory) with longer and larger inputs.
Here is a repo that shows a simplified version of how I'm using govips. The relevant code is in main.go. The "parmap" helper is short for "parallel map," and is an almost-identical port of what I'm using for real. I'm hoping that I'm just not doing something correctly, so please let me know if anything stands out to you. Happy to give suggestions a try.
My temporary workaround for this issue is to remove the
canvas.Close()
line. Without that, I have yet to encounter the segfault. Interestingly, if I also removefile1.Close()
andfile2.Close()
, I reliably encounter the segfault again. So I left those alone. To avoid a memory leak from not freeing the canvas, I launch a separate process to wrap the vips compositing code, then let the OS clean it up when the compositing process terminates. This solves my problem in the short term, but it has me worried about dealing with segfaults in the future.About half the time, the error stack shows the call to
thumbnail_image()
:The other half, the error stack shows the call to
clear_image()
:Let me know if there's any more information I can get, or anything else I should try!
The text was updated successfully, but these errors were encountered: