Hi,
I am not sure if this is a code or hardware problem anymore, but I'm hoping someone will have some insight. Bear with me for the long explanation.
I have a Desktop with Hardy Heron (yes it has to be hardy heron sigh) for which I am writing code to read from a serial port. In this case, it opens the USB port. I have an IMU on the port that puts in data. I started trying this as an Orocos component and then as a separate program, and would like to move it back to Orocos, however, the memory error occurs in both cases.
The port is opened in a constructor ala:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
//Configure and open the serial port here-set everything statically here (maybe change later to be user configurable)
pname = COM1; //May need an & here
buffindex = 0;
// Open the port
if((fd = open (pname, O_RDWR | O_EXCL | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
{
//RTT::Logger::log() << RTT::Logger::Error << "[Serialinterface] rror with open() on port. Make sure exists." << RTT::Logger::endl;
return;
}
else
{
oldflags = fcntl(fd, F_GETFL, 0);
if (oldflags == -1) {
status=GETFL_ERROR;
//RTT::Logger::log() << RTT::Logger::Error << "[Serialinterface] GET_FL Error: -2" << RTT::Logger::endl;
return;}
oldflags |= O_NONBLOCK; //set the NONBLOCK flag //nonblocked
if(fcntl(fd, F_SETFL, oldflags)==-1) {
status=SETFL_ERROR;
//RTT::Logger::log() << RTT::Logger::Error << "[Serialinterface] SET_FL Error: -3" << RTT::Logger::endl;
return;}
}
// Get the attributes
if (tcgetattr( fd, &p_termios)==-1)
{
close( fd );
return;
}
|
etc. etc. with the port settings. It has a Serial port read function or 2 ala:
1 2 3 4 5 6 7 8 9 10 11
|
int SSL::connieLogger::GrabData(uint8_t* buffer, int length)
{
static bool neveragain = false;
static uint8_t* recvbuf = new uint8_t[length];
buffindex = 0;
//printf("buf 0 \n");
buffindex = ReadSerial(recvbuf,length);
if(buffindex > 0){
printf("BI %d \n", buffindex);}
|
which is intended to read a specific length of code. Tha read function occurs in:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
int SSL::connieLogger::ReadSerial(uint8_t* buff, int length)
{
// If you want to set delay between reads, set VMIN = number of bytes expected, VTIME=1 (100 ms wait), no FNDELAY
bufptr = buff;
nbytes=0;
while (((nbytes = read(fd, bufptr, 1)) > 0) )//&& ((buff+length)>bufptr))
{
//printf("Bufptr: %d \n", *bufptr);
bufptr += nbytes;
}
return (bufptr-buff); //return the number of characters read
}
|
where you can see I have commented out the specific length and just read whatever is on the port.
In the main function I have a while loop that calls the GrabData function until the user hits Ctrl-C to quit.
While the program is running, everything is fine. However, as soon as ctrl-c is hit, the following error occurs:
+++ Caught exit request - shutting down ...
*** glibc detected *** ./a.out: free(): invalid next size (fast): 0x0804e140 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7d76a85]
/lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7d7a4f0]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7f42b11]
./a.out[0x804977b]
./a.out[0x80497a5]
./a.out[0x80497de]
./a.out[0x8049840]
./a.out[0x8049359]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7d21450]
./a.out(__gxx_personality_v0+0x51)[0x8048cf1]
======= Memory map: ========
08048000-0804c000 r-xp 00000000 08:01 1820383 /home/
|
While the Orocos component is running, this happens every time there is data on the port. As a separate program, this only happens on quit. There are usually 496 bytes on the port. The buffer I am storing in is 2056 long.
The Valgrind program was recommended for debugging so I have that output:
==26063== Syscall param read(buf) points to unaddressable byte(s)
==26063== at 0x40007F2: (within /lib/ld-2.7.so)
==26063== by 0x804A4CF: SSL::connieLogger::GrabData(unsigned char*, int) (in /home/ndamore/Desktop/SerialTest/a.out)
==26063== by 0x8049190: main (in /home/ndamore/Desktop/SerialTest/a.out)
==26063== Address 0x42ad1b8 is 0 bytes after a block of size 2,056 alloc'd
==26063== at 0x4022F14: operator new[](unsigned) (vg_replace_malloc.c:268)
==26063== by 0x804A45B: SSL::connieLogger::GrabData(unsigned char*, int) (in /home/ndamore/Desktop/SerialTest/a.out)
==26063== by 0x8049190: main (in /home/ndamore/Desktop/SerialTest/a.out)
BI 4464
valgrind: m_mallocfree.c:210 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
valgrind: Heap block lo/hi size mismatch: lo = 4294967295, hi = 72549442.
Probably caused by overrunning/underrunning a heap block's bounds.
==26063== at 0x3801806D: report_and_quit (m_libcassert.c:140)
==26063== by 0x38018361: vgPlain_assert_fail (m_libcassert.c:200)
|
I think it may be a hardware problem with how the USB port is setup and drivers or something, but I am not sure.
I should also note, that when I replace the read function with a set of fake data passed to the pointer, everything is fine. This seems to have something to do with the read function itself and I am stuck.
Suggestions would be much appreciated.
Thanks in advance.