Skip to content

Conversation

zserg8
Copy link

@zserg8 zserg8 commented Feb 18, 2018

There is an old issue with the library which results in SEGFAULT if remove_event_detect() function is called from within the python callback.
More information can be found here:
https://sourceforge.net/p/raspberry-gpio-python/tickets/136/
https://raspberrypi.stackexchange.com/questions/73791/gpio-callbacks-throw-segmentation-fault
https://stackoverflow.com/questions/35632689/how-to-correctly-remove-interrupt-callback-in-beaglebone-black
http://schlierf.info/raspberry/pi/gpio/python/2016/04/15/RPi.GPIO_SegFault.html

The origin of the problem is the way of handling callbacks - C code stores them in a linked list structure, and, while it correctly removes/inserts new items it doesn't do any sanity checks inside the wrapper that iterates over the list. That results in dereferencing zero pointer if last callback in the chain was removed inside the callback function.
I provide a possible solution to this. Two places need to be patched. While the base C code (event_gpio.c) requires only minor alteration to prevent SEGFAULTs, upper-level python library (py_gpio.c) needs a bit more elaborate workaround to stop traversing the callback chain immediately if event detection was removed while running one of the callback functions.
Typical example when this functionality might be needed is programming interrupt-like behavior with event detection system (see 3rd link above).

@pdp7 pdp7 self-assigned this Feb 18, 2018
@pdp7
Copy link
Collaborator

pdp7 commented Feb 18, 2018

@zsserg thank you. I will review and try out on a BeagleBone.

@pdp7
Copy link
Collaborator

pdp7 commented Feb 18, 2018

Testing of @zsserg's branch

debian@beaglebone:~/tmp/zsserg$ sudo ./pytest_all_versions.sh Testing Python 2.7 ============================================================================ test session starts ============================================================================ platform linux2 -- Python 2.7.13, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 rootdir: /home/debian/tmp/zsserg, inifile: collected 58 items test_adc.py ...... test_gpio_input.py .. test_gpio_output.py ...... test_gpio_setup.py .......... test_led.py .. test_pwm_setup.py ........................... test_spi.py .. test_uart.py ... ========================================================================= 58 passed in 7.88 seconds ========================================================================= Testing Python 3.5 ============================================================================ test session starts ============================================================================ platform linux -- Python 3.5.3, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 rootdir: /home/debian/tmp/zsserg, inifile: collected 58 items test_adc.py ...... test_gpio_input.py .. test_gpio_output.py ...... test_gpio_setup.py .......... test_led.py .. test_pwm_setup.py ........................... test_spi.py .. test_uart.py ... ========================================================================= 58 passed in 8.10 seconds ========================================================================= Testing Python 3.6 ============================================================================ test session starts ============================================================================ platform linux -- Python 3.6.3, pytest-3.2.5, py-1.5.2, pluggy-0.4.0 rootdir: /home/debian/tmp/zsserg, inifile: collected 58 items test_adc.py ...... test_gpio_input.py .. test_gpio_output.py ...... test_gpio_setup.py .......... test_led.py .. test_pwm_setup.py ........................... test_spi.py .. test_uart.py ... ============================================================================= warnings summary ============================================================================== test/test_gpio_input.py::TestGPIOInput::()::test_input /home/debian/tmp/zsserg/test/test_gpio_input.py:15: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/gpio/gpio68/value' mode='r' encoding='UTF-8'> value = open('/sys/class/gpio/gpio68/value').read() test/test_gpio_output.py::TestGPIOOutput::()::test_output_high /home/debian/tmp/zsserg/test/test_gpio_output.py:13: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/gpio/gpio68/value' mode='r' encoding='UTF-8'> value = open('/sys/class/gpio/gpio68/value').read() test/test_gpio_output.py::TestGPIOOutput::()::test_output_low /home/debian/tmp/zsserg/test/test_gpio_output.py:20: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/gpio/gpio68/value' mode='r' encoding='UTF-8'> value = open('/sys/class/gpio/gpio68/value').read() test/test_gpio_output.py::TestGPIOOutput::()::test_output_greater_than_one /home/debian/tmp/zsserg/test/test_gpio_output.py:31: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/gpio/gpio68/value' mode='r' encoding='UTF-8'> value = open('/sys/class/gpio/gpio68/value').read() test/test_gpio_setup.py::TestSetup::()::test_setup_output_key /home/debian/tmp/zsserg/test/test_gpio_setup.py:18: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/gpio/gpio68/direction' mode='r' encoding='UTF-8'> direction = open('/sys/class/gpio/gpio68/direction').read() test/test_gpio_setup.py::TestSetup::()::test_setup_output_name /home/debian/tmp/zsserg/test/test_gpio_setup.py:29: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/gpio/gpio68/direction' mode='r' encoding='UTF-8'> direction = open('/sys/class/gpio/gpio68/direction').read() test/test_gpio_setup.py::TestSetup::()::test_setup_input_key /home/debian/tmp/zsserg/test/test_gpio_setup.py:36: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/gpio/gpio68/direction' mode='r' encoding='UTF-8'> direction = open('/sys/class/gpio/gpio68/direction').read() test/test_gpio_setup.py::TestSetup::()::test_setup_input_name /home/debian/tmp/zsserg/test/test_gpio_setup.py:47: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/gpio/gpio68/direction' mode='r' encoding='UTF-8'> direction = open('/sys/class/gpio/gpio68/direction').read() test/test_gpio_setup.py::TestSetup::()::test_setup_input_pull_up /home/debian/tmp/zsserg/test/test_gpio_setup.py:54: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/gpio/gpio68/direction' mode='r' encoding='UTF-8'> direction = open('/sys/class/gpio/gpio68/direction').read() test/test_gpio_setup.py::TestSetup::()::test_setup_input_pull_down /home/debian/tmp/zsserg/test/test_gpio_setup.py:61: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/gpio/gpio68/direction' mode='r' encoding='UTF-8'> direction = open('/sys/class/gpio/gpio68/direction').read() test/test_led.py::TestLED::()::test_brightness_high /home/debian/tmp/zsserg/test/test_led.py:27: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/leds/beaglebone:green:usr0/brightness' mode='r' encoding='UTF-8'> return open(path).read() /home/debian/tmp/zsserg/test/test_led.py:27: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/leds/beaglebone:green:usr1/brightness' mode='r' encoding='UTF-8'> return open(path).read() /home/debian/tmp/zsserg/test/test_led.py:27: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/leds/beaglebone:green:usr2/brightness' mode='r' encoding='UTF-8'> return open(path).read() /home/debian/tmp/zsserg/test/test_led.py:27: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/leds/beaglebone:green:usr3/brightness' mode='r' encoding='UTF-8'> return open(path).read() test/test_led.py::TestLED::()::test_brightness_low /home/debian/tmp/zsserg/test/test_led.py:27: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/leds/beaglebone:green:usr0/brightness' mode='r' encoding='UTF-8'> return open(path).read() /home/debian/tmp/zsserg/test/test_led.py:27: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/leds/beaglebone:green:usr1/brightness' mode='r' encoding='UTF-8'> return open(path).read() /home/debian/tmp/zsserg/test/test_led.py:27: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/leds/beaglebone:green:usr2/brightness' mode='r' encoding='UTF-8'> return open(path).read() /home/debian/tmp/zsserg/test/test_led.py:27: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/class/leds/beaglebone:green:usr3/brightness' mode='r' encoding='UTF-8'> return open(path).read() test/test_pwm_setup.py::TestPwmSetup::()::test_start_pwm /home/debian/tmp/zsserg/test/test_pwm_setup.py:43: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/duty_cycle' mode='r' encoding='UTF-8'> duty = open(pwm_dir + '/duty_cycle').read() /home/debian/tmp/zsserg/test/test_pwm_setup.py:46: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/period' mode='r' encoding='UTF-8'> period = open(pwm_dir + '/period').read() test/test_pwm_setup.py::TestPwmSetup::()::test_start_pwm_ecap0 /home/debian/tmp/zsserg/test/test_pwm_setup.py:58: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/duty_cycle' mode='r' encoding='UTF-8'> duty = open(pwm_dir + '/duty_cycle').read() /home/debian/tmp/zsserg/test/test_pwm_setup.py:61: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/period' mode='r' encoding='UTF-8'> period = open(pwm_dir + '/period').read() test/test_pwm_setup.py::TestPwmSetup::()::test_start_pwm_with_polarity_one /home/debian/tmp/zsserg/test/test_pwm_setup.py:91: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/duty_cycle' mode='r' encoding='UTF-8'> duty = open(pwm_dir + '/duty_cycle').read() /home/debian/tmp/zsserg/test/test_pwm_setup.py:94: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/period' mode='r' encoding='UTF-8'> period = open(pwm_dir + '/period').read() /home/debian/tmp/zsserg/test/test_pwm_setup.py:95: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/polarity' mode='r' encoding='UTF-8'> polarity = open(pwm_dir + '/polarity').read() test/test_pwm_setup.py::TestPwmSetup::()::test_start_pwm_with_polarity_default /home/debian/tmp/zsserg/test/test_pwm_setup.py:120: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/duty_cycle' mode='r' encoding='UTF-8'> duty = open(pwm_dir + '/duty_cycle').read() /home/debian/tmp/zsserg/test/test_pwm_setup.py:123: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/period' mode='r' encoding='UTF-8'> period = open(pwm_dir + '/period').read() /home/debian/tmp/zsserg/test/test_pwm_setup.py:124: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/polarity' mode='r' encoding='UTF-8'> polarity = open(pwm_dir + '/polarity').read() test/test_pwm_setup.py::TestPwmSetup::()::test_start_pwm_with_polarity_zero /home/debian/tmp/zsserg/test/test_pwm_setup.py:149: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/duty_cycle' mode='r' encoding='UTF-8'> duty = open(pwm_dir + '/duty_cycle').read() /home/debian/tmp/zsserg/test/test_pwm_setup.py:152: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/period' mode='r' encoding='UTF-8'> period = open(pwm_dir + '/period').read() /home/debian/tmp/zsserg/test/test_pwm_setup.py:153: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/polarity' mode='r' encoding='UTF-8'> polarity = open(pwm_dir + '/polarity').read() test/test_pwm_setup.py::TestPwmSetup::()::test_pwm_duty_modified /home/debian/tmp/zsserg/test/test_pwm_setup.py:228: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/duty_cycle' mode='r' encoding='UTF-8'> duty = open(pwm_dir + '/duty_cycle').read() /home/debian/tmp/zsserg/test/test_pwm_setup.py:231: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/period' mode='r' encoding='UTF-8'> period = open(pwm_dir + '/period').read() /home/debian/tmp/zsserg/test/test_pwm_setup.py:237: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/duty_cycle' mode='r' encoding='UTF-8'> duty = open(pwm_dir + '/duty_cycle').read() /home/debian/tmp/zsserg/test/test_pwm_setup.py:240: ResourceWarning: unclosed file <_io.TextIOWrapper name='/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3/pwm0/period' mode='r' encoding='UTF-8'> period = open(pwm_dir + '/period').read() -- Docs: http://doc.pytest.org/en/latest/warnings.html ================================================================== 58 passed, 35 warnings in 9.46 seconds =================================================================== debian@beaglebone:~/tmp/zsserg$ 
@pdp7 pdp7 merged commit 49b2be3 into adafruit:master Feb 18, 2018
@pdp7
Copy link
Collaborator

pdp7 commented Feb 18, 2018

thanks @zsserg

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