Node-serialport: Memory leak on Raspberry Pi4 with Raspbian

Created on 2 Jul 2020  路  6Comments  路  Source: serialport/node-serialport

Summary of Problem

  • What are you trying to do?
    I try to use Serialport to connect a port on a Raspberry Pi4 with Raspbian installed. We have used the same setup before on a Raspberry Pi3 and it was working perfectly fine. Changing to Raspberry Pi4 results in the problem described below.

  • What happens?
    The result is, that the memory usage rises 1-2MB per second until it is full and the application crashes.

  • What should have happened?
    As in the other setups there should be no additional memory consumption so the Serialport library can be used in a stable setup.

This problem does not occur with the following setups:
Raspberry Pi3 + Raspbian
Raspberry Pi4 + Ubuntu Server
Raspberry Pi3 + Ubuntu Server

--> Any suggestions on what to change and/or is this a known issue that I am just not able to find in the recent issues?

--> In our real world setup, we list all Serialports with the function SerialPort.list() and try to connect to one port after another in the list. Apparently the error occurs and leads to the memory leak, when trying to establish a connection to a port and sending a command to a "faulty" port (like a port that has no device connected).

Code to Reproduce the Issue

--> For this code no device needs to be connected to the Pi.

const SerialPort = require('serialport')
const path = '/dev/ttyAMA0'  // or any other port, like '/dev/serial1'
const port = new SerialPort(path, { autoOpen: false })
port.open(function (err) {
        if (err) {
                console.log(err)
        } else {
                port.write('TESTDATA', (err) => {
                        console.log(err)
                })
        }
})

// Start reading from stdin so we don't exit.
console.log('--- Press key to continue ---')
process.stdin.resume()

Versions, Operating System and Hardware

  • [email protected] <-- same issue on [email protected]
  • Node.js v10.19.0 <-- same issue on Node.js v12.18.2 (and v14.5.0 @mawi-cs)
  • Linux Raspbian <-- not happening on Ubuntu Server
  • Raspberry Pi 4 <-- not happening on Raspberry Pi 3
stale-issue

Most helpful comment

When using Raspberry Pi OS on a Raspberry Pi 4, /dev/ttyAMA0 is the default Bluetooth UART. By default /dev/serial1 is a link to /dev/ttyAMA0 so it's the same device.

Running the following command from the command line does the same thing as the test code in the first post above:

echo TESTDATA > /dev/ttyAMA0

Running this command from the command line also results in issues. It doesn't result in memory leaks but it does result in the corresponding bash process blocking one of the 4 CPUs on the Pi 4 requiring 100% CPU.

Do you really want to use the Bluetooth UART and not the UART broken out to pins 8 and 10 on the Raspberry Pi GPIO header?

If the test program is modified to use /dev/ttyS0 (or /dev/serial0) then the test program will function as expected and the UART broken out to pins 8 and 10 on the Raspberry Pi GPIO header will transmit the string TESTDATA successfully.

All 6 comments

I have just tested this with Node 14.5.0 and Serialport 9.0.0 on my RPi 4 with the newest Raspi OS as it is called now, and i am getting the same results.

When using Raspberry Pi OS on a Raspberry Pi 4, /dev/ttyAMA0 is the default Bluetooth UART. By default /dev/serial1 is a link to /dev/ttyAMA0 so it's the same device.

Running the following command from the command line does the same thing as the test code in the first post above:

echo TESTDATA > /dev/ttyAMA0

Running this command from the command line also results in issues. It doesn't result in memory leaks but it does result in the corresponding bash process blocking one of the 4 CPUs on the Pi 4 requiring 100% CPU.

Do you really want to use the Bluetooth UART and not the UART broken out to pins 8 and 10 on the Raspberry Pi GPIO header?

If the test program is modified to use /dev/ttyS0 (or /dev/serial0) then the test program will function as expected and the UART broken out to pins 8 and 10 on the Raspberry Pi GPIO header will transmit the string TESTDATA successfully.

Thank you very much for pointing this out. In fact deactivating Blutooth solves the issue for us. But with your input we might just check that we do not connect to /dev/ttyAMA0 or /dev/serial1.

Is there anything one can find out if a port is UART like a property that can be read after opening the port? Then I could just not test the port (e.g. not send data to it) but skip it. In this case the solution would be more generic when trying to avoid such a situation.

Is there anything one can find out if a port is UART like a property that can be read after opening the port?

To the best of my knowledge all serialports are UARTs. Bluetooth uses a UART and the serialport broken out to pins 8 and 10 on the GPIO header is a UART. I don't know if node-serialport can be used to determine if a serialport on a Raspberry Pi is for Bluetooth. Perhaps there is information related to the topic in the data returned by SerialPort.list().

I can verify that a Serialport stream on all serial ports on a Raspberry Pi 4 running the August 2020 Raspbian Buster will result in a rapid memory leak if bluetooth is enabled at boot.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in a week no further activity occurs. Feel free continue the discussion or ask for a never-stale label to keep it open. If this is a support issue, consider sharing it on stack overflow to get more eyes on your problem.

Was this page helpful?
0 / 5 - 0 ratings