ronaldoussoren / pyobjc

The Python <-> Objective-C Bridge with bindings for macOS frameworks
https://pyobjc.readthedocs.io
553 stars 47 forks source link

segmentation fault when repeatedly calling VNRecognizeTextRequest #591

Closed straussmaximilian closed 7 months ago

straussmaximilian commented 7 months ago

Describe the bug Hi, Thank you for your fantastic library. I have used this and written a small wrapper around VNRecognizeTextRequest named ocrmac. I got a bug report that repeatedly calling this function causes a segmentation fault at random instances. I could reproduce it and created a minimal code example that reproduces this bug. Test files are here.

Maybe I am doing something wrong when deallocating or this could be a bug? Any feedback is very much appreciated. Thank you!

import objc
from PIL import Image
import io  
import Vision
from pathlib import Path

def pil2buf(pil_image: Image.Image):
    """Convert PIL image to buffer"""
    buffer = io.BytesIO()
    pil_image.save(buffer, format="PNG")
    return buffer.getvalue()

for loc in sorted(Path(".frames/").glob("*.png")):
    path = str(loc)
    print(loc)

    image = Image.open(path)
    with objc.autorelease_pool():
        req = Vision.VNRecognizeTextRequest.alloc().init()
        req.setRecognitionLevel_(0)
        req.setRecognitionLanguages_("zh-Hans")

        handler = Vision.VNImageRequestHandler.alloc().initWithData_options_(
            pil2buf(image), None
        )

        success = handler.performRequests_error_([req], None)
        req.dealloc()
        handler.dealloc()

Platform information

To Reproduce Download the test files and execute the code above: segmentation fault and random occurrences.

Expected behavior No segmentation fault.

Additional context Add any other context about the problem here.

ronaldoussoren commented 7 months ago

Don't call req.dealloc() and handler.dealloc(), those will clear the memory of these objects regardless of the number of references. Cocoa uses automatic memory management like Python and you don't have to manage memory manually.

The autorelease pool is useful because of the delayed reference count updates in Cocoa, this avoids using unnecessarily large amounts of memory when processing a lot of images.

straussmaximilian commented 7 months ago

Thanks for the quick reply. That fixed it! Thanks!!