Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segmentation fault when using Threading #26

Open
aaaaaaaaaron opened this issue Apr 26, 2024 · 6 comments
Open

Segmentation fault when using Threading #26

aaaaaaaaaron opened this issue Apr 26, 2024 · 6 comments

Comments

@aaaaaaaaaron
Copy link

I want to stream a single camera in one thread. When I close the stream and join my thread my code crashes with a segmentation fault.

I have reduced my code down to this to replicate the issue

import threading

import time
from vmbpy import *
import faulthandler

faulthandler.enable()

def start(stop_event):
    print("Initializing")
    camera_loop(stop_event)
    print("done")


def initiate_cam(cam):
    cam.LineSelector.set('Line0')
    cam.LineMode.set('Input')
    cam.TriggerSelector.set('FrameStart')
    cam.TriggerSource.set('Line0')
    cam.TriggerActivation.set('RisingEdge')
    cam.AcquisitionMode.set("Continuous")
    cam.TriggerMode.set('On')


def camera_loop(stop_event):
    with VmbSystem.get_instance() as vmb:
        cams = vmb.get_all_cameras()
        with cams[0] as cam:
            initiate_cam(cam)
            try:
                cam.start_streaming(handler=handler, buffer_count=1,
                                    allocation_mode=AllocationMode.AnnounceFrame)
                print("ready for photos...")
                stop_event.wait()
            finally:
                print("finishing")
                cam.stop_streaming()


def handler(cam: Camera, stream: Stream, frame: Frame):
    print('{} acquired {}'.format(cam, frame), flush=True)
    # do stuff
    cam.queue_frame(frame)


if __name__ == "__main__":
    producers_lock = threading.Lock()

    stop_event = threading.Event()

    with producers_lock:
        bottle_thread = threading.Thread(target=start, args=(stop_event,))
        bottle_thread.start()
    print("started")
    time.sleep(10)
    print("ending")
    with producers_lock:
        stop_event.set()
        bottle_thread.join()

The code runs fine, but when it stops it causes a segmentation fault. I feel like I am doing everything that was in the multithreading_opencv.py example but I keep getting this segmentation fault. Is this a bug? Or am I missing something from that example that would lead to a graceful shutdown?

Thank you!

@Teresa-AlliedVision
Copy link

Teresa-AlliedVision commented Apr 29, 2024

I could not reproduce the issue with your code example on Windows, can you post debgging/error message and more info on your system/OS, versioning of any used modules and Python version?

@aaaaaaaaaron
Copy link
Author

Thank you for testing that out. Here is my output:

Initializing
started
ready for photos...
ending
finishing
Fatal Python error: Segmentation fault

Thread 0x0000ffffbb9b4010 (most recent call first):
  File "/usr/lib/python3.9/logging/__init__.py", line 2142 in shutdown
done

The line File "/usr/lib/python3.9/logging/__init__.py", line 2142 in shutdown changes every time I run it so I don't think that is the issue.

I am using Python 3.9 on an Nvidia Jetson Orin Nano Developer Kit running Jetpack 5.1.2 (Ubuntu 20.04.6 LTS, arm64). Using my same venv I am actually able to run your multithreading example.

@OverBoostedBoat
Copy link

Hello !
I'm currently experiencing a very similar problem (using a frame generator with a loop instead of a streaming, but seg faulting as soon as I leave it) on pretty much the same environment, did you end up finding the source of this issue ?
Thanks !

@aaaaaaaaaron
Copy link
Author

@OverBoostedBoat No unfortunately not. My work around was to start streaming in a new process so when it ends the segfault wouldn't crash everything. Not the best solution but it works. Let me know if you find a better solution!

@OverBoostedBoat
Copy link

OverBoostedBoat commented Jul 16, 2024

I was able to reduce my code down to this. The time.sleep(1) is only here to ensure that the self.join() is called. If it's called, the seg fault systematically occurs when leaving run() (thus "Stopping Device" is never printed). If self.join() is not called, no seg fault occurs. Honestly I don't really know how I could nicely correct this problem...

It seems to me that something shady might be happening during the call_vmb_c('VmbShutdown') at line 545 of vmbsystem.py, but I could be completely mistaken.

import threading
import time
from vmbpy import *   

class Device(threading.Thread):
    def __init__(self):
        super().__init__()
        self._stop = False

    def stop(self):
        self._stop = True
        self.join()

    def run(self):
        with VmbSystem.get_instance() as vmb:
            cam = vmb.get_all_cameras()[0]
            with cam:
                while not self._stop:
                    pass
        time.sleep(1)

device = Device()

print("Starting Device")
device.start()

print("Stopping Device")
device.stop()

print("Device stopped")

If it can help, the seg fault didn't happen with the old VimbaPython API.

@Teresa-AlliedVision
Copy link

Hello,
I tried to reproduce the issue again, this time on an Orin Nano with Jetpack version 5.1.2 and did not see a segfault with either code snippet. Though with the second, I had to rename self._stop to something else. Otherwise I would get TypeError:"bool" object is not callable.
To further look into the issue, please post the debugger information. I will leave the issue open for now, so you can add information for a possible reproducer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants