This is the mail archive of the gcc@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]
Other format: [Raw text]

Re: catch(...) and forced unwind


On Tue, 16 Dec 2003 15:30:24 -0500, Jason Merrill <jason@redhat.com> wrote:

> Benjamin: Pending a resolution of these issues, I suggest that we work
> around the problem by disabling cancellation in the iostream try blocks.
> I'm playing with this now.

Thus.  Unfortunately, pthread_setcancelstate doesn't seem to actually
disable cancellation on my Fedora Core 1 laptop, so this doesn't actually
help.  I'll try to test it on an RHEL box soon.

Index: libstdc++-v3/include/bits/ios_base.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/ios_base.h,v
retrieving revision 1.36
diff -c -p -r1.36 ios_base.h
*** libstdc++-v3/include/bits/ios_base.h	16 Dec 2003 00:15:24 -0000	1.36
--- libstdc++-v3/include/bits/ios_base.h	16 Dec 2003 23:40:24 -0000
***************
*** 45,50 ****
--- 45,51 ----
  #include <bits/atomicity.h>
  #include <bits/localefwd.h>
  #include <bits/locale_classes.h>
+ #include <bits/gthr.h>
  
  namespace std
  {
*************** namespace std
*** 478,483 ****
--- 479,512 ----
  
      void 
      _M_init();
+ 
+     // The C++ I/O functions catch all exceptions and only rethrow them if
+     // badbit is set in exceptions().  This causes problems for pthread
+     // cancellation, which (currently) calls terminate if a catch block
+     // tries to finalize the cancellation exception.  So we use this struct
+     // to disable cancellation within the try block.
+     struct _Cancel_guard
+     {
+ #ifdef PTHREAD_CANCEL_DISABLE
+       int _M_oldstate;
+       _Cancel_guard (const ios_base &__i, iostate __bit)
+       {
+ 	if (__i._M_exception & __bit)
+ 	  // Don't suppress cancellation if it will be rethrown.
+ 	  _M_oldstate = -1;
+ 	else
+ 	  pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &_M_oldstate);
+       }
+ 
+       ~_Cancel_guard ()
+       {
+ 	if (_M_oldstate != -1)
+ 	  pthread_setcancelstate (_M_oldstate, NULL);
+       }
+ #else
+       _Cancel_guard (const ios_base &) {}
+ #endif
+     };
  
    public:
  
Index: libstdc++-v3/include/bits/istream.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/istream.tcc,v
retrieving revision 1.60
diff -c -p -r1.60 istream.tcc
*** libstdc++-v3/include/bits/istream.tcc	2 Dec 2003 02:48:49 -0000	1.60
--- libstdc++-v3/include/bits/istream.tcc	16 Dec 2003 23:40:25 -0000
*************** namespace std 
*** 116,121 ****
--- 116,122 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
*************** namespace std 
*** 138,143 ****
--- 139,145 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      long __l;
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __l);
*************** namespace std 
*** 169,174 ****
--- 171,177 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
*************** namespace std 
*** 191,196 ****
--- 194,200 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      long __l;
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __l);
*************** namespace std 
*** 222,227 ****
--- 226,232 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
*************** namespace std 
*** 244,249 ****
--- 249,255 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
*************** namespace std 
*** 266,271 ****
--- 272,278 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
*************** namespace std 
*** 289,294 ****
--- 296,302 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
*************** namespace std 
*** 311,316 ****
--- 319,325 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
*************** namespace std 
*** 334,339 ****
--- 343,349 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
*************** namespace std 
*** 356,361 ****
--- 366,372 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
*************** namespace std 
*** 378,383 ****
--- 389,395 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
*************** namespace std 
*** 400,405 ****
--- 412,418 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
  	      __ng.get(*this, 0, *this, __err, __n);
  	    }
*************** namespace std 
*** 422,427 ****
--- 435,441 ----
  	{
  	  try
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::failbit);
  	      if (!__copy_streambufs(this->rdbuf(), __sbout))
  		__err |= ios_base::failbit;
  	    }
*************** namespace std 
*** 449,454 ****
--- 463,469 ----
  	{
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      __c = this->rdbuf()->sbumpc();
  	      // 27.6.1.1 paragraph 3
  	      if (!traits_type::eq_int_type(__c, __eof))
*************** namespace std 
*** 478,483 ****
--- 493,499 ----
  	{
   	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      int_type __cb = this->rdbuf()->sbumpc();
  	      // 27.6.1.1 paragraph 3
  	      if (!traits_type::eq_int_type(__cb, traits_type::eof()))
*************** namespace std 
*** 510,515 ****
--- 526,532 ----
  	{
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const int_type __idelim = traits_type::to_int_type(__delim);
  	      const int_type __eof = traits_type::eof();
  	      __streambuf_type* __sb = this->rdbuf();
*************** namespace std 
*** 549,554 ****
--- 566,572 ----
  	{
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const int_type __idelim = traits_type::to_int_type(__delim);
  	      const int_type __eof = traits_type::eof();	      
  	      __streambuf_type* __this_sb = this->rdbuf();
*************** namespace std 
*** 588,593 ****
--- 606,612 ----
  	{
            try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const int_type __idelim = traits_type::to_int_type(__delim);
  	      const int_type __eof = traits_type::eof();
  	      __streambuf_type* __sb = this->rdbuf();
*************** namespace std 
*** 637,642 ****
--- 656,662 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const int_type __eof = traits_type::eof();
  	      __streambuf_type* __sb = this->rdbuf();
  	      int_type __c;
*************** namespace std 
*** 673,678 ****
--- 693,699 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      __c = this->rdbuf()->sgetc();
  	      if (traits_type::eq_int_type(__c, traits_type::eof()))
  		__err |= ios_base::eofbit;
*************** namespace std 
*** 697,702 ****
--- 718,724 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      _M_gcount = this->rdbuf()->sgetn(__s, __n);
  	      if (_M_gcount != __n)
  		__err |= (ios_base::eofbit | ios_base::failbit);
*************** namespace std 
*** 721,726 ****
--- 743,749 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      // Cannot compare int_type with streamsize generically.
  	      streamsize __num = this->rdbuf()->in_avail();
  	      if (__num >= 0)
*************** namespace std 
*** 754,759 ****
--- 777,783 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const int_type __eof = traits_type::eof();
  	      __streambuf_type* __sb = this->rdbuf();
  	      if (!__sb 
*************** namespace std 
*** 782,787 ****
--- 806,812 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const int_type __eof = traits_type::eof();
  	      __streambuf_type* __sb = this->rdbuf();
  	      if (!__sb 
*************** namespace std 
*** 810,815 ****
--- 835,841 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      __streambuf_type* __sb = this->rdbuf();
  	      if (__sb)
  		{
*************** namespace std 
*** 837,842 ****
--- 863,869 ----
        pos_type __ret = pos_type(-1);
        try
  	{
+ 	  ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	  if (!this->fail())
  	    __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
  	}
*************** namespace std 
*** 855,860 ****
--- 882,888 ----
        ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
        try
  	{
+ 	  ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	  if (!this->fail())
  	    {
  	      // 136.  seekp, seekg setting wrong streams?
*************** namespace std 
*** 882,887 ****
--- 910,916 ----
        ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
        try
  	{
+ 	  ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	  if (!this->fail())
  	    {
  	      // 136.  seekp, seekg setting wrong streams?
*************** namespace std 
*** 912,917 ****
--- 941,947 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(__in, ios_base::badbit);
  	      typename __istream_type::int_type __cb = __in.rdbuf()->sbumpc();
  	      if (!_Traits::eq_int_type(__cb, _Traits::eof()))
  		__c = _Traits::to_char_type(__cb);
*************** namespace std 
*** 943,948 ****
--- 973,979 ----
  	{
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(__in, ios_base::badbit);
  	      // Figure out how many characters to extract.
  	      streamsize __num = __in.width();
  	      if (__num <= 0)
*************** namespace std 
*** 1025,1030 ****
--- 1056,1062 ----
  	{
  	  try
  	    {
+ 	      ios_base::_Cancel_guard __g(__in, ios_base::badbit);
  	      __str.erase();
  	      streamsize __w = __in.width();
  	      __size_type __n;
*************** namespace std 
*** 1084,1089 ****
--- 1116,1122 ----
  	{
  	  try
  	    {
+ 	      ios_base::_Cancel_guard __g(__in, ios_base::badbit);
  	      __str.erase();
  	      __int_type __idelim = _Traits::to_int_type(__delim);
  	      __streambuf_type* __sb = __in.rdbuf();
Index: libstdc++-v3/include/bits/ostream.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/ostream.tcc,v
retrieving revision 1.50
diff -c -p -r1.50 ostream.tcc
*** libstdc++-v3/include/bits/ostream.tcc	2 Dec 2003 02:48:49 -0000	1.50
--- libstdc++-v3/include/bits/ostream.tcc	16 Dec 2003 23:40:25 -0000
*************** namespace std 
*** 105,110 ****
--- 105,111 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_put_type& __np = __check_facet(this->_M_num_put);
  	      if (__np.put(*this, *this, this->fill(), __n).failed())
  		__err |= ios_base::badbit;
*************** namespace std 
*** 128,133 ****
--- 129,135 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      bool __b = false;
  	      char_type __c = this->fill();
  	      ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
*************** namespace std 
*** 161,166 ****
--- 163,169 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_put_type& __np = __check_facet(this->_M_num_put);
  	      if (__np.put(*this, *this, this->fill(), __n).failed())
  		__err |= ios_base::badbit;
*************** namespace std 
*** 185,190 ****
--- 188,194 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      bool __b = false;
  	      char_type __c = this->fill();
  	      ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
*************** namespace std 
*** 219,224 ****
--- 223,229 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_put_type& __np = __check_facet(this->_M_num_put);
  	      if (__np.put(*this, *this, this->fill(), __n).failed())
  		__err |= ios_base::badbit;
*************** namespace std 
*** 243,248 ****
--- 248,254 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_put_type& __np = __check_facet(this->_M_num_put);
  	      if (__np.put(*this, *this, this->fill(), __n).failed())
  		__err |= ios_base::badbit;
*************** namespace std 
*** 266,271 ****
--- 272,278 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_put_type& __np = __check_facet(this->_M_num_put);
  	      if (__np.put(*this, *this, this->fill(), __n).failed())
  		__err |= ios_base::badbit;
*************** namespace std 
*** 289,294 ****
--- 296,302 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      const __num_put_type& __np = __check_facet(this->_M_num_put);
  	      if (__np.put(*this, *this, this->fill(), __n).failed())
  		__err |= ios_base::badbit;
*************** namespace std 
*** 312,317 ****
--- 320,326 ----
  	{
  	  try
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::failbit);
  	      if (!__copy_streambufs(__sbin, this->rdbuf()))
  		__err |= ios_base::failbit;
  	    }
*************** namespace std 
*** 342,347 ****
--- 351,357 ----
  	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
  	  try
  	    {
+ 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	      int_type __put = this->rdbuf()->sputc(__c); 
  	      if (traits_type::eq_int_type(__put, traits_type::eof()))
  		__err |= ios_base::badbit;
*************** namespace std 
*** 370,376 ****
        if (__cerb)
  	{
  	  try
! 	    { _M_write(__s, __n); }
  	  catch (...)
  	    { this->_M_setstate(ios_base::badbit); }
  	}
--- 380,389 ----
        if (__cerb)
  	{
  	  try
! 	    {
! 	      ios_base::_Cancel_guard __g(*this, ios_base::badbit);
! 	      _M_write(__s, __n);
! 	    }
  	  catch (...)
  	    { this->_M_setstate(ios_base::badbit); }
  	}
*************** namespace std 
*** 388,393 ****
--- 401,407 ----
        ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
        try
  	{
+ 	  ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	  if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
  	    __err |= ios_base::badbit;
  	}
*************** namespace std 
*** 406,411 ****
--- 420,426 ----
        pos_type __ret = pos_type(-1);
        try
  	{
+ 	  ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	  if (!this->fail())
  	    __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
  	}
*************** namespace std 
*** 422,427 ****
--- 437,443 ----
        ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
        try
  	{
+ 	  ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	  if (!this->fail())
  	    {
  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
*************** namespace std 
*** 448,453 ****
--- 464,470 ----
        ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
        try
  	{
+ 	  ios_base::_Cancel_guard __g(*this, ios_base::badbit);
  	  if (!this->fail())
  	    {
  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
*************** namespace std 
*** 478,483 ****
--- 495,501 ----
  	{
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(__out, ios_base::badbit);
  	      const streamsize __w = __out.width();
  	      streamsize __len = 1;
  	      _CharT* __cs = &__c;
*************** namespace std 
*** 509,514 ****
--- 527,533 ----
  	{
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(__out, ios_base::badbit);
  	      const streamsize __w = __out.width();
  	      streamsize __len = 1;
  	      char* __cs = &__c;
*************** namespace std 
*** 538,543 ****
--- 557,563 ----
  	{
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(__out, ios_base::badbit);
  	      const streamsize __w = __out.width();
  	      streamsize __len = static_cast<streamsize>(_Traits::length(__s));
  	      if (__w > __len)
*************** namespace std 
*** 581,586 ****
--- 601,607 ----
  	  
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(__out, ios_base::badbit);
  	      const streamsize __w = __out.width();
  	      streamsize __len = static_cast<streamsize>(__clen);
  	      if (__w > __len)
*************** namespace std 
*** 614,619 ****
--- 635,641 ----
  	{
  	  try 
  	    {
+ 	      ios_base::_Cancel_guard __g(__out, ios_base::badbit);
  	      const streamsize __w = __out.width();
  	      streamsize __len = static_cast<streamsize>(_Traits::length(__s));
  	      if (__w > __len)

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