This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Two problems in bastring located and fixed: Race-condition on multiprocessors and bug in compare


Hi,

recently, a colleague and I have discovered and fixed two
problems in the basic_string implementation of gcc-2.95.2.

The first bug is in the compare function of basic_string, which
causes it to fail when length-limited comparing a string with a
an equal c-style-string as char *

The second one occurs only in multi-threaded programs on
multi-processor machines, due to a missing protection against
parallel execution in the reference counting of basic_string.

The only problem with the patch for the second problem is
that it might not compile on SCO as indicated by the following
comment which follows below the patched source lines:

    // This opcode exists as a .byte instead of as a mnemonic for the
    // benefit of SCO OpenServer 5.  The system assembler (which is
    // essentially required on this target) can't assemble xaddl in
    //COFF mode.

I hope these changes make it into the gcc-distribution as others
might benefit from it. These bugs took us rather long to locate :-)

Regards,

Axel Habermann


The patches follow:

diff -rc gcc-2.95.2/libstdc++/std/bastring.cc gcc-2.95.2-patched/libstdc++/std/bastring.cc
*** gcc-2.95.2/libstdc++/std/bastring.cc	Mon Nov 30 10:40:56 1998
--- gcc-2.95.2-patched/libstdc++/std/bastring.cc	Wed Jul  5 12:21:09 2000
***************
*** 423,428 ****
--- 423,432 ----
    int r = traits::compare (data () + pos, s, rlen);
    if (r != 0)
      return r;
+   // the following two lines were missing, so this compare function
+   // fails in case the two strings are equal. panther 00-Jun-05
+   if (rlen == n)   
+     return 0;
    return (length () - pos) - n;
  }
  
diff -rc gcc-2.95.2/libstdc++/std/bastring.h gcc-2.95.2-patched/libstdc++/std/bastring.h
*** gcc-2.95.2/libstdc++/std/bastring.h	Wed Jun  2 01:27:35 1999
--- gcc-2.95.2-patched/libstdc++/std/bastring.h	Sat May 27 14:43:45 2000
***************
*** 72,80 ****
  
      charT* data () { return reinterpret_cast<charT *>(this + 1); }
      charT& operator[] (size_t s) { return data () [s]; }
-     charT* grab () { if (selfish) return clone (); ++ref; return data (); }
  #if defined __i486__ || defined __i586__ || defined __i686__
!     void release ()
        {
  	size_t __val;
  	// This opcode exists as a .byte instead of as a mnemonic for the
--- 72,86 ----
  
      charT* data () { return reinterpret_cast<charT *>(this + 1); }
      charT& operator[] (size_t s) { return data () [s]; }
  #if defined __i486__ || defined __i586__ || defined __i686__
!     charT* grab () { if (selfish) return clone (); 
!       // replaced ++ref with locked assembler instruction, kiwi 26.5.2000
!       asm ("lock; addl %0, (%1)"
!            : : "a" (1), "d" (&ref)
!            : "memory");
!       return data (); }
! 
!     void release () 
        {
  	size_t __val;
  	// This opcode exists as a .byte instead of as a mnemonic for the
***************
*** 106,111 ****
--- 112,118 ----
  	  delete this;
        }
  #else
+     charT* grab () { if (selfish) return clone (); ++ref; return data (); }
      void release () { if (--ref == 0) delete this; }
  #endif


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]