gotthardp / python-mercuryapi

Python wrapper for the ThingMagic Mercury API
MIT License
121 stars 62 forks source link

Segmentation Fault in python3.7 #101

Open mikcox opened 4 years ago

mikcox commented 4 years ago

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?

sebastian-bartkowiak commented 4 years ago

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

cspencer commented 4 years ago

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)
HanYangZhao commented 4 years ago

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

ambroweb commented 4 years ago

@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?

HanYangZhao commented 4 years ago

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?

ambroweb commented 4 years ago

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

HanYangZhao commented 4 years ago

Ok try these suggestions