Espigah / java-simple-serial-connector

Automatically exported from code.google.com/p/java-simple-serial-connector
0 stars 0 forks source link

readBytes() causes segmentation fault (0xb) resulting in JVM crash #53

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. establish connection to serial device
2. read from it
3. disconnect the serial device
4. go back to step one 30-40 times until JVM crashes with a SIGSEGV

What is the expected output? What do you see instead?
Expected: no jvm crash
What I see:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007fc53d01020b, pid=3414, tid=140485301135104
#
# JRE version: 7.0_25-b15
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.25-b01 mixed mode linux-amd64 
compressed oops)
# Problematic frame:
# 
[error occurred during error reporting (printing problematic frame), id 0xb]

# Failed to write core dump. Core dumps have been disabled. To enable core 
dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/sj20297/Desktop/hs_err_pid3414.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
#
Aborted (core dumped)

What version of the product are you using? On what operating system?
JSSC v 2.6, x64. 64 bit Ubuntu 10.4, JDK1.7_u45_x64.

Please provide any additional information below.

I created a wrapper that abstracts the readBytes into a readLine() method, it 
is a very simple method based on a 500ms polling interval and 2000ms read 
timeout by default. Here is the code:

public final String readLine(int readTimeOutMS) throws Exception{
        if (!open) { throw new Exception("Could not read: There is no open serial port."); }

        StringBuffer s = new StringBuffer();

        // start time
        DateTime curTime = new DateTime();
        DateTime timeOutTime = curTime.plusMillis(readTimeOutMS);

        logger.debug("Beginning read loop with {} ms timeout", readTimeOutMS);
        while (curTime.isBefore(timeOutTime)) {
            logger.debug("Reading bytes...");
            byte[] b = null;
            int inputBufferBytesCount = this.serialPort.getInputBufferBytesCount();
            logger.debug("There are {} bytes on the input buffer", String.valueOf(inputBufferBytesCount));
            if (inputBufferBytesCount > 0)
                b = this.serialPort.readBytes();

            if(b != null)
            {
                s.append(new String(b));
                timeOutTime = curTime.plusMillis(readTimeOutMS); //set timeout time to keep reading since we are getting stuff
            }
            Thread.sleep(readTimeOutMS / 4); //we want to read ~4 times
            curTime = new DateTime();
        }

        String returnStr = s.toString();

        returnStr = returnStr.replace((char)0x00, ' '); //other code does not like NUL chars

        return returnStr;
    } // end readLine method

The time metric is being kept by an external datetime library, joda-time. I 
have utilized unit tests to ensure that this problem is not related to my 
abstraction layer. This is actually one library of many in my overarching 
framework in development. I have extracted the bare minimum from it and created 
test code that simply writes simple commands to a linux-shell enabled serial 
device and reads from it. Through debugging, I have narrowed the problem down 
to SerialPort.readBytes(). Something funky appears to be happening down in the 
native code that ultimately causes a SIGSEGV.

My test code and full implementation are attached, as well as the error log. 
This happens every single run, and has been tested on both a mac and linux 
environment. 

I would appreciate if somebody knowledgeable about this library could 
investigate this issue, the prospects for me are that I will have to swap to 
another library, but it seems like this one is very stable by various 
testimonies.

Original issue reported on code.google.com by sjung...@gmail.com on 25 Oct 2013 at 6:52

Attachments:

GoogleCodeExporter commented 9 years ago
Here is the source code of my full implementation as well as the test code 
which resides in the main() method.

Original comment by sjung...@gmail.com on 25 Oct 2013 at 6:55

Attachments:

GoogleCodeExporter commented 9 years ago
Cause of this problem was a serial port handles leakage. Then you invoke 
connect method you get serial port list with getPortNames() method and after 
30-40 iterations application crash with open handles overflow. This issue fixed 
in 2.7.0 version

Original comment by scream3r.org@gmail.com on 20 Jan 2014 at 4:06