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

Windows fatal exception: stack overflow on serial.Serial with JLink CDC #728

Open
epac-tom opened this issue Jan 9, 2024 · 0 comments
Open

Comments

@epac-tom
Copy link

epac-tom commented Jan 9, 2024

I am trying to create a list of ports, and whether they are in use or not, and I am running up against a stack overflow.
When using a Nordic devkit, that enumerates as a JLink CDC UART Port, if the port has been opened by any terminal program, and closed again, it is causing an issues with pyserial.
When I run the following code, stripped down from my application, I get a stack overflow.

import faulthandler; faulthandler.enable()
import serial.tools.list_ports
import traceback
import re

def check_open(comport):
    print(f"Checking port {comport}")
    port_is_open = False
    try:
        ser = serial.Serial(
            port=comport,
            baudrate=9600,
            bytesize=serial.SEVENBITS,
            parity=serial.PARITY_EVEN,
            stopbits=serial.STOPBITS_ONE,
        )
        ser.isOpen()
        port_is_open = True

    except (IOError,PermissionError,):
        pass
    except Exception as e:
        print(traceback.format_exc())
    return port_is_open

def get_number_from_port(x):
    return re.search(r"\((COM.*?)\)", x).group(1)

def label_in_use_ports(listOfPorts):
    try:
        new_list = []
        for port in listOfPorts:
            if check_open(get_number_from_port(str(port))):
                new_list.append(str(port))
            else:
                new_list.append(f"[Already In Use] - {str(port)}")
        return new_list
    except Exception as e:
        print(f"Exception::{traceback.format_exc()}")
        return None

print(label_in_use_ports(serial.tools.list_ports.comports()))

If the port, COM4, hasn't been previously opened then there are no issues:

python -Xfaulthandler basic.py 
Checking port COM7
Checking port COM4
Checking port COM24
Checking port COM18
['COM7 - USB-SERIAL CH340 (COM7)', 'COM4 - JLink CDC UART Port (COM4)', 'COM24 - nRF Connect USB CDC ACM (COM24)', 'COM18 - Intel(R) Active Management Technology - SOL (COM18)']

If the port is open, again this is fine:

python -Xfaulthandler basic.py 
Checking port COM7
Checking port COM4
Checking port COM24
Checking port COM18
['COM7 - USB-SERIAL CH340 (COM7)', '[Already In Use] - COM4 - JLink CDC UART Port (COM4)', 'COM24 - nRF Connect USB CDC ACM (COM24)', 'COM18 - Intel(R) Active Management Technology - SOL (COM18)']

But if I then close it, I get a stack overflow

python -Xfaulthandler basic.py 
Checking port COM7
Checking port COM4
Windows fatal exception: stack overflow

Current thread 0x0000a200 (most recent call first):
  File "C:\Python310\lib\site-packages\serial\serialwin32.py", line 221 in _reconfigure_port
  File "C:\Python310\lib\site-packages\serial\serialwin32.py", line 80 in open
  File "C:\Python310\lib\site-packages\serial\serialutil.py", line 244 in __init__
  File "C:\Python310\lib\site-packages\serial\serialwin32.py", line 33 in __init__
  File "basic.py", line 10 in check_open
  File "basic.py", line 33 in label_in_use_ports
  File "basic.py", line 42 in <module>
Checking port COM24
Checking port COM18
['COM7 - USB-SERIAL CH340 (COM7)', '[Already In Use] - COM4 - JLink CDC UART Port (COM4)', 'COM24 - nRF Connect USB CDC ACM (COM24)', 'COM18 - Intel(R) Active Management Technology - SOL (COM18)']

It usually takes ~200ms to run, in the last case it takes ~4.2s.

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

1 participant