This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
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)