pyserial icon indicating copy to clipboard operation
pyserial copied to clipboard

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

Open epac-tom opened this issue 2 years ago • 0 comments

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.

epac-tom avatar Jan 09 '24 11:01 epac-tom