std::basic_ios<>::copyfmt() with registered callback (via 
std::ios_base::register_callback()) run-time SIGABRT 
---------------------------------------------------------------------------------------------------------------

                 Key: STDCXX-1058
                 URL: https://issues.apache.org/jira/browse/STDCXX-1058
             Project: C++ Standard Library
          Issue Type: Bug
          Components: 27. Input/Output
    Affects Versions: 4.2.1, 4.2.x, 4.3.x, 5.0.0
         Environment: Solaris 10 and 11, Red Hat Linux, OpenSuSE Linux
Sun C++ Compilers 12.1, 12.2, 12.3

Defect is independent of platform or compiler.

            Reporter: Stefan Teleman
             Fix For: 4.2.x, 4.3.x, 5.0.0


A stream with a registered callback via register_callback() SIGABRTs at 
run-time:

#include <iostream>
#include <fstream>

int x;

void testfun (std::ios_base::event ev, std::ios_base& iosobj, int index)
{
  x = index;

  switch (ev)
  {
    case std::ios_base::copyfmt_event:
      std::cerr << "copyfmt_event" << std::endl; break;
    case std::ios_base::imbue_event:
      std::cerr << "imbue_event" << std::endl; break;
    case std::ios_base::erase_event:
      std::cerr << "erase_event" << std::endl; break;
    default:
      std::cerr << "unknown" << std::endl; break;
  }
}

int main ()
{
  std::fstream f0;
  std::fstream f1;
  int i = 101;

  std::ios_base::event_callback e1 = &testfun;
  f0.register_callback (e1, i);

  x = 0;
  f0.imbue (std::cerr.getloc());
  if (x != i)
    std::cerr << "x: expected " << i << " got " << x << std::endl;

  x = 0;
  f0.copyfmt (f1);
  if (x != i)
    std::cerr << "x: expected " << i << " got " << x << std::endl;

  return 0;
}

Output from GCC 4.5.0:
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fstream.copyfmt][02/05/2012
 0:32:42][1340]>> ./test-gcc 
imbue_event
erase_event

Output from Sun C++ 12.2 with stlport4:
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fstream.copyfmt][02/05/2012
 0:32:44][1341]>> ./test-ss12-stlport 
imbue_event
erase_event
copyfmt_event
erase_event

Output from Sun C++ 12.2 with our stdcxx (patched):
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fstream.copyfmt][02/05/2012
 0:32:58][1342]>> ./test-ss12-stdcxx 
imbue_event
erase_event

Output from Pathscale 4.0.12.1 (which didn't patch stdcxx):
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fstream.copyfmt][02/05/2012
 0:33:03][1343]>> ./test-pathscale 
imbue_event
erase_event
*** glibc detected *** ./test-pathscale: double free or corruption (fasttop): 
0x 000000000605480 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x73286)[0x7f78cbb7f286]
/lib64/libc.so.6(cfree+0x6c)[0x7f78cbb8402c]
/opt/pathscale/ekopath-4.0.12.1/lib/4.0.12.1/x8664/64/libcxxrt.so(_ZdlPv+0xd)[0x
 f78cc097d63]
/opt/pathscale/ekopath-4.0.12.1/lib/4.0.12.1/x8664/64/libstl.so(_ZNSt8ios_base11
 C_usr_data10_C_deallocEPS0_+0x2d)[0x7f78cc300b5b]
======= Memory map: ========
00400000-00404000 r-xp 00000000 103:00 9582413                           
/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fstream.copyfmt/test-pathscale
00603000-00604000 r--p 00003000 103:00 9582413                           
/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fstream.copyfmt/test-pathscale
00604000-00605000 rw-p 00004000 103:00 9582413                           
/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fstream.copyfmt/test-pathscale
00605000-00626000 rw-p 00000000 00:00 0                                  [heap]

[ ... ]

I no longer have an unpatched stdcxx handy for the Sun C++ compilers available
to reproduce the defect with the Sun C++ compiler.

Defect is in file src/iostore.cpp, starting at line 275:

_C_usr->_C_iarray, _C_usr->_C_parray and _C_usr->_C_cbarray
are not set to NULL after deletion:

    _TRY {
        if (_C_usr) {
            // fire erase events (27.4.4.2, p17) - may throw
            if (_C_usr->_C_fire)
                (this->*_C_usr->_C_fire)(erase_event, true /* reentrant */);

            // delete existing arrays, if any; _C_usr will only be deleted
            // if `rhs' contains no user data (see below)
            operator delete (_C_usr->_C_iarray);
            _C_usr->_C_iarray = 0UL; // <----- !!
            operator delete (_C_usr->_C_parray);
            _C_usr->_C_parray = 0UL; // <----- !!
            operator delete (_C_usr->_C_cbarray);
            _C_usr->_C_cbarray = 0UL; // <----- !!
        }

Patch for 4.2.1 to follow shortly.


--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to