I implement a output buffer LogStreamBuf derived from std::streambuf,
It is used in multithread environment with lots of cout, SEGV error occurred when a large amount of output in a short period of time,
the bt likes below, the param __n is invalid when copy, in my opinion it seems like thread safe problem, But I cannot find a solution to fix.
Please any advice to help, thanks very much!
(gdb) bt
#0 0xb698ff64 in memcpy () at ../sysdeps/arm/armv7/multiarch/memcpy_impl.S:487
#1 0xb6b5a4dc in std::char_traits<char>::copy (__n=4294967295, __s2=0xb3ef984a "60\340", <incomplete sequence \333>, __s1=<optimized out>)
at /home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/gcc.git~linaro-7.5-2019.12-stage2/arm-linux-gnueabihf/libstdc++-v3/include/bits/char_traits.h:350
#2 std::basic_streambuf<char, std::char_traits<char> >::xsputn (this=0xa4db5c <gLogStreamBuf>, __s=0xb3ef984a "60\340", <incomplete sequence \333>, __n=2)
at /home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/gcc.git~linaro-7.5-2019.12-stage2/arm-linux-gnueabihf/libstdc++-v3/include/bits/streambuf.tcc:90
#3 0xb6b482c8 in std::basic_streambuf<char, std::char_traits<char> >::sputn (__n=<optimized out>, __s=<optimized out>, this=0xa4db5c <gLogStreamBuf>)
at /home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/gcc.git~linaro-7.5-2019.12-stage2/arm-linux-gnueabihf/libstdc++-v3/include/streambuf:451
#4 std::ostreambuf_iterator<char, std::char_traits<char> >::_M_put (__len=<optimized out>, __ws=<optimized out>, this=<synthetic pointer>)
at /home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/gcc.git~linaro-7.5-2019.12-stage2/arm-linux-gnueabihf/libstdc++-v3/include/bits/streambuf_iterator.h:282
#5 std::__write<char> (__len=<optimized out>, __ws=<optimized out>, __s=...)
at /home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/gcc.git~linaro-7.5-2019.12-stage2/arm-linux-gnueabihf/libstdc++-v3/include/bits/locale_facets.h:121
#6 std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<unsigned long> (this=<optimized out>, __s=..., __io=...,
__fill=<optimized out>, __fill@entry=32 ' ', __v=<optimized out>, __v@entry=60)
at /home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/gcc.git~linaro-7.5-2019.12-stage2/arm-linux-gnueabihf/libstdc++-v3/include/bits/locale_facets.tcc:933
#7 0xb6b483aa in std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put (this=<optimized out>, __s=..., __io=..., __fill=32 ' ', __v=60)
at /home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/gcc.git~linaro-7.5-2019.12-stage2/arm-linux-gnueabihf/libstdc++-v3/include/bits/locale_facets.h:2515
#8 0xb6b4f8f2 in std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::put (__v=60, __fill=<optimized out>, __io=..., __s=...,
this=0xb6b94178 <(anonymous namespace)::num_put_c>)
at /home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/gcc.git~linaro-7.5-2019.12-stage2/arm-linux-gnueabihf/libstdc++-v3/include/bits/locale_facets.h:2376
#9 std::ostream::_M_insert<unsigned long> (this=0xa005f0 <std::cout@@GLIBCXX_3.4>, __v=60)
at /home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/gcc.git~linaro-7.5-2019.12-stage2/arm-linux-gnueabihf/libstdc++-v3/include/bits/ostream.tcc:73
LogStreamBuf's implementation
LogStreamBuf gLogStreamBuf;
#define kInBufSize 48*1024
LogStreamBuf::LogStreamBuf()
{
fInBuf = new char[kInBufSize];
setbuf( fInBuf, kInBufSize );
setp( fInBuf, (fInBuf + kInBufSize) );
setg( fInBuf, fInBuf, (fInBuf + kInBufSize) );
}
void LogStreamBuf::RedirectStreams()
{
cout << "Redirecting output to LogStreamBuf!"<<endl;
cout.rdbuf(this);
}
int LogStreamBuf::overflow( int ch )
{
Lock();
for(char *p=gptr(); p < epptr(); p++) {
// writes characters to the associated output sequence from the put area
}
setp( fInBuf, (fInBuf + InBufLen()) );
setg( fInBuf, fInBuf, (fInBuf + InBufLen()) );
Unlock();
}
int LogStreamBuf::sync()
{
Lock();
for(char *p=gptr(); p < pptr(); p++) {
// sync characters pointer p to the associated output sequence from the put area
count++;
}
gbump(count);
Unlock();
}
int LogStreamBuf::underflow()
{
setg( fInBuf, fInBuf, (fInBuf + InBufLen()) );
return sgetc();
}
ostream& MacAddress::Print( ostream& ostrm ) const
{
int oldFill = ostrm.fill();
uint8 macAddress[6];
Get(macAddress[0], macAddress[1], macAddress[2],
macAddress[3], macAddress[4], macAddress[5]);
ostrm.fill( '0' );
ostrm << hex
<< setw(2) << right << (unsigned int) macAddress[0] << ':'
<< setw(2) << right << (unsigned int) macAddress[1] << ':'
<< setw(2) << right << (unsigned int) macAddress[2] << ':'
<< setw(2) << right << (unsigned int) macAddress[3] << ':' <=====bt shows the problem starts from here
<< setw(2) << right << (unsigned int) macAddress[4] << ':'
<< setw(2) << right << (unsigned int) macAddress[5]
<< dec;
ostrm.fill(oldFill);
return ostrm;
}
inline std::ostream& operator<<( std::ostream& ostrm, const MacAddress& ins )
{
return ins.Print( ostrm );
}
cout << "Current Sucriber's MACaddr " << pSucriber->macAddress() << endl; <<=== the cout sentence
err
Program terminated with signal SIGSEGV, Segmentation fault.