python-mercuryapi icon indicating copy to clipboard operation
python-mercuryapi copied to clipboard

Segmentation Fault in python3.7

Open mikcox opened this issue 4 years ago • 7 comments

Hello!

First off, thanks a ton for this library. I've been using it extensively and it's saved us a ton of time!

I recently ran into an issue on a new application where I need to be running python3.7. It seems that things work okay to install python-mercuryapi via pip3 / python3.7, but while running my actual reader script with python3.7 I get a Segmentation Fault.

For this project, I'm on a raspberry pi running Raspbian Stretch.

My code is roughly the following:

...
reader = mercury.Reader("tmr://" + readerIP)
reader.stop_reading()
time.sleep(5)
reader.set_read_plan([1], "GEN2", read_power=3100)
reader.start_reading(myReadCallback, on_time=0, off_time=0)
...

Debugging my script with gdb python3 gives me the following insight:

GNU gdb (Raspbian 7.12-6) 7.12.0.20161007-git
...
(gdb) run myProgram.py 
Starting program: /usr/bin/python3 myProgram.py
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
[New Thread 0x76749470 (LWP 25765)]
[New Thread 0x75dff470 (LWP 25766)]
[New Thread 0x755fe470 (LWP 25767)]

Thread 4 "python3" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x755fe470 (LWP 25767)]
PyErr_SetObject (exception=0x24d310 <_PyExc_TypeError>, value=0x76a525a0) at Python/errors.c:98
98	    exc_value = _PyErr_GetTopmostException(tstate)->exc_value;
(gdb) backtrace
#0  PyErr_SetObject (exception=0x24d310 <_PyExc_TypeError>, value=0x76a525a0) at Python/errors.c:98
#1  0x000f7f20 in PyErr_SetString (exception=0x24d310 <_PyExc_TypeError>, string=<optimized out>) at Python/errors.c:169
#2  0x767d7c04 in notify_exception_listeners (reader=0x2e25f0, status=67108868) at tm_reader_async.c:571
#3  0x767d90c8 in do_background_reads (arg=0x2e25f0) at tm_reader_async.c:1210
#4  0x76f80fc4 in start_thread (arg=0x755fe470) at pthread_create.c:458
#5  0x76e68038 in ?? () at ../sysdeps/unix/sysv/linux/arm/clone.S:76 from /lib/arm-linux-gnueabihf/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) Quit

Interestingly, the exact same script works fine if I run it using python3.5. I've also tried running it using python2.7, but because of the issue described in #28 (which I think should be reopened now after ef5bff9, by the way) I'm not able to run it with python2.7 yet either.

Do you have any insight as to why we might be hitting a segfault in python3.7 only?

mikcox avatar Jan 30 '20 01:01 mikcox

I also get Segmentation fault while using python 3.6.9. Any ideas as to the source of the issue?

sebastian-bartkowiak avatar Mar 10 '20 13:03 sebastian-bartkowiak

I'm getting segfaults in both Python 3.5.4 and 3.7.3

Running my code in gdb results in a similar error to that posted above by mikcox:

  (gdb) run reader.py
  Starting program: /usr/bin/python3.5 reader.py
  [Thread debugging using libthread_db enabled]
  Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
  [New Thread 0xb67c6460 (LWP 21829)]
  [New Thread 0xb5fc5460 (LWP 21830)]
  Reading...
  Reading...

  Thread 3 "python3.5" received signal SIGSEGV, Segmentation fault.
  [Switching to Thread 0xb5fc5460 (LWP 21830)]
  0x001a0060 in PyErr_SetObject ()
  (gdb) backtrace
  #0  0x001a0060 in PyErr_SetObject ()
  #1  0x001a0a34 in PyErr_SetString ()
  #2  0xb68cd73c in notify_exception_listeners (reader=0x4a8d68, status=16777217) at   tm_reader_async.c:571
  #3  0xb68cea50 in do_background_reads (arg=0x4a8d68) at tm_reader_async.c:1147
  #4  0xb6f95494 in start_thread (arg=0xb5fc5460) at pthread_create.c:486
  #5  0xb6e04578 in ?? () at ../sysdeps/unix/sysv/linux/arm/clone.S:73 from /lib/arm-linux-  gnueabihf/libc.so.6
  Backtrace stopped: previous frame identical to this frame (corrupt stack?)
  (gdb)

cspencer avatar May 30 '20 22:05 cspencer

could you try my fork https://github.com/HanYangZhao/python-mercuryapi? I think i have a fix. It's a bug in the invoke_exception_callback with the python GIL

HanYangZhao avatar Jun 09 '20 23:06 HanYangZhao

@HanYangZhao I have tried your fork and the problem persist. There is any different way to use your .start_reading that avoid the Segmentation fault? What I have noticed is: reader.start_reading(lambda tag: print(tag.epc , tag.rssi)) can run forever without Segmentation fault reader.start_reading(lambda tag: sendViaSerialToBluetooth(tag.epc , tag.rssi)) adding a function that send the data to another device using pyserial will incur in Segmentation fault

Any suggestions?

ambroweb avatar Jun 28 '20 15:06 ambroweb

Could you try

def sendViaSerialToBluetooth(tags):
    #do stuff with tags

reader.start_reading(sendViaSerialToBluetooth)

If that doesn't work, could you post the actually error running with gdb?

HanYangZhao avatar Jun 29 '20 14:06 HanYangZhao

I have tried to run the program with gdb but I get this error, and I cannot get a meaningful error log from the program. This is only limited when I'm opening the program with gdb normally it runs.

Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
Traceback (most recent call last):
  File "simple2.py", line 2, in <module>
    import mercury
  File "build/bdist.linux-armv7l/egg/mercury.py", line 7, in <module>
  File "build/bdist.linux-armv7l/egg/mercury.py", line 6, in __bootstrap__
ImportError: /home/pi/.cache/Python-Eggs/python_mercuryapi-0.5.3-py2.7-linux-armv7l.egg-tmp/mercury.so: undefined symbol: PyUnicode_AsUTF8
[Inferior 1 (process 2273) exited with code 01]

My program is very simple:

import serial
import mercury
import time

ser = serial.Serial(
    port='/dev/serial0',
    baudrate=9600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    timeout=1
)

reader = mercury.Reader("tmr:///dev/ttyUSB0", baudrate=115200)

def read_rfid():
    reader.set_region("EU3")
    reader.set_read_plan([1], "GEN2", read_power=1900)
    reader.start_reading(lambda tag: send(tag.epc.decode('utf-8'), str(tag.rssi)))

def send(epc, rssi):
    w = epc + ":" + rssi
    ser.write(w.encode('utf-8'))

while True:
    text = input()
    if text == "exit":
        break
    if text == "R":
        read_rfid()
    if text == "S":
        reader.stop_reading()
    print("> " + text)
    text = ""

Usually I get segmentation fault as soon multiple tags get read at the same time, very quickly. Really appreciated that your helping me on this one. Very very grateful

ambroweb avatar Jun 29 '20 20:06 ambroweb

Ok try these suggestions

  • Because of the while True , reader.start_reading() gets called every loop. It's not made be called multiple times as it launches multiple threads in the background. Use reader.read() if you want on-demand reading.
  • The syntax for reader.start_reading() is reader.start_reading(callback) so in your case it should just be reader.start_reading(send). And send() could be defined as
def send(tag):
    w = tag.epc + ":" + tag.rssi
    ser.write(w.encode('utf-8'))

I don't think your problem is related to the original problem, so if you can create a separate issue it would be appreciated. Hope that helps

HanYangZhao avatar Jun 29 '20 21:06 HanYangZhao