GPIO.remove_event_detect + C-call = segmentation fault
A Python module to control the GPIO on a Raspberry Pi
Brought to you by:
croston
When I call GPIO.remove_event_detect
inside of a event callback and then run a C API call like Image.open
or suprocess.Popen
I get a segmentation fault as soon as the callback returns.
Here's a minimal example:
import RPi.GPIO as GPIO import time from PIL import Image from PIL import ImageStat GPIO.setmode(GPIO.BCM) GPIO.setup(3, GPIO.IN) def on_buzzer_pushed_once(channel): GPIO.remove_event_detect(channel) # swapping this with the following line im = Image.open("capt0000.jpg") # fixes the issue print("This is printed, segfault comes after this line") GPIO.add_event_detect(3, GPIO.FALLING, callback=on_buzzer_pushed_once) while True: time.sleep(1)
The result is simply this:
$ python test.py This is printed, segfault comes after this line Segmentation fault
If I swap the two lines in the callback, it works as expected!
raspi-gpio version is 0.6.2
issue appears on python 3.4.2 and 2.7.9
GDB did not help much so far:
gdb python GNU gdb (Raspbian 7.7.1+dfsg-5) 7.7.1 Copyright (C) 2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "arm-linux-gnueabihf". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from python...(no debugging symbols found)...done. (gdb) r test.py Starting program: /usr/bin/python test.py [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1". [New Thread 0x76721460 (LWP 7043)] Cannot access memory at address 0x3000e27a Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x76721460 (LWP 7043)] 0x7692ab84 in ?? () from /usr/lib/python2.7/dist-packages/RPi/_GPIO.arm-linux-gnueabihf.so (gdb) bt #-1 0x7692ab84 in ?? () from /usr/lib/python2.7/dist-packages/RPi/_GPIO.arm-linux-gnueabihf.so #0 0x7692ab84 in ?? () from /usr/lib/python2.7/dist-packages/RPi/_GPIO.arm-linux-gnueabihf.so /build/gdb-nrlhe3/gdb-7.7.1+dfsg/gdb/frame.c:472: internal-error: get_frame_id: Assertion `fi->this_id.p' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n)
I have something similar but changing the order does not result in working code.
Minimized example:
Found a Workaround for this by using a variable to skip the callback code if we are already inside:
There will be a fix for this in 0.6.3 - I have been sent a patch for the issue which I am currently evaluating.
Problem is still there in 0.6.3
sometimes 'Segmentation fault' occurs after removing the event with 'remove_event_detect'.
I'm using the event to measure the frequency of a 4 kHz square wave. When the measurement is stopped I don't want the event any more. But removing will cause an error.
A workaround would be fine, but it is not as simple as the above...