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

FD leak for serial port #69

Open
anatoly-savchenkov opened this issue May 30, 2021 · 5 comments
Open

FD leak for serial port #69

anatoly-savchenkov opened this issue May 30, 2021 · 5 comments
Labels

Comments

@anatoly-savchenkov
Copy link

I my script I need to re-initialize Instrument from time to time. After couple of months of uptime it failed with 'Too many open files' error. Investigation showed that serial devices were kept open thus causing a leak of file descriptors. Adding a destructor with self.serial.close() call inside solves the problem.

@j123b567
Copy link
Collaborator

Probably close_port_after_each_call can help as workaround.

@anatoly-savchenkov
Copy link
Author

I also think it should help but I didn't try. It was easier for me to patch my local copy and add a destructor.

@pyhys pyhys added the bug label Aug 8, 2021
@pyhys
Copy link
Owner

pyhys commented Aug 10, 2021

It is possible to close the serial port using instrument.serial.close()

However, it would be interesting to know what caused the problem in the first place.

@anatoly-savchenkov
Copy link
Author

That's a good question. Probably it's a buggy HW, I see Linux loses USB to Modbus converter and I have to reset it (dmesg output):
[436791.627904] ftdi_sio ttyUSB1: FTDI USB Serial Device converter now disconnected from ttyUSB1
[436791.636480] ftdi_sio 1-1.1:1.0: device disconnected
[436791.840510] usb 1-1.1: reset full-speed USB device number 4 using ehci-pci
[436792.074717] ftdi_sio 1-1.1:1.0: FTDI USB Serial Device converter detected
[436792.081689] usb 1-1.1: Detected FT232RL
[436792.087552] usb 1-1.1: FTDI USB Serial Device converter now attached to ttyUSB2

Right before that happens minimalmodbus throws the following exception:
Checksum error in rtu mode: 'ø\x86' instead of '~I' . The response is: '\x00\x03\x04\x00\x06²$ø\x86' (plain response: '\x00\x03\x04\x00\x06²$ø\x86')

Obviously after calling usbreset, FD is no longer valid (but still open which causes the leak) and I need to re-open the port.

Any idea what to try before we conclude it's a HW issue?

@j123b567
Copy link
Collaborator

If there is an usb error, the port is recreated, but if the file is opened, then it can't reuse the same name, so e.g. if you are using /dev/ttyUSB1 then the new port /dev/ttyUSB2 is created, so you should close the first one and open the second one.

If you are on the recent linux (or it is easy to obtain UDEV rule to do so), you should find symlink to the serial port in the directory /dev/serial/by-path/ which will point exactly and persistantly acros reboots and usb errors to the same serial converter in the same USB port so you no longer need to solve if it is ttyUSB1 or ttyUSB2.

With this setup (using exclusively /dev/serial/by-path/), I'm using this little hack to solve similar problem like you.

import serial
import minimalmodbus

class SerialAutoOpen(serial.Serial):
    def open(self):
        try:
            super().open()
        except IOError:
            pass

    def close(self):
        try:
            super().close()
        except IOError:
            pass
        self.is_open = False

    def write(self, data):
        self.open()
        try:
            return super().write(data)
        except IOError:
            self.close()
            raise

minimalmodbus.serial.Serial = SerialAutoOpen

instrument = minimalmodbus.Instrument(...)

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

No branches or pull requests

3 participants