Bug 14942 - glibc: libio, used from libstd++, not exception aware
Summary: glibc: libio, used from libstd++, not exception aware
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: glibc
Version: 6.2
Hardware: i386
OS: Linux
medium
high
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2000-08-01 02:57 UTC by Henner Zeller
Modified: 2008-05-01 15:37 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2000-08-01 02:57:43 UTC
Embargoed:


Attachments (Terms of Use)

Description Henner Zeller 2000-08-01 02:57:41 UTC
Hi,
This is no RedHat specific bug, but can be fixed easily with a little
patch.

The libstd++ uses parts of the basic libio-function in libc. 
Problems arise if the C++ code, called by these functions, throws
exceptions. Consider the following example:
------8<-- brokenioex.cc -----------------------------
/*
 * No Exception awareness in IO-lib
 * Provided by <hzeller>
 */
#include <iostream>
 
class mysb : public std::streambuf {
protected:
  virtual int overflow(int c) {
    throw 1;
  }
  virtual int underflow() {
    throw 1;
  }
};
 
int main() {
  mysb *sb = new mysb();
  iostream out(sb);
  try {
    // this calls implicitly functions in
    // genops.c
    out << "foo";
  }
  catch (...) {
    // catch: IO lib exception aware
    // otherwise this prog will abort
    return 0;
  }
}
-------------------------------------------

Calling the streambuffer's methods implicitly by using the iostream will
crash this program; the coredump reveals, that:

----------------------------------------------
$ gdb ./a.out core
(gdb) bt
#0  0x4009e861 in __kill () from /lib/libc.so.6
#1  0x4009e548 in raise (sig=6) at ../sysdeps/posix/raise.c:27
#2  0x4009fc71 in abort () at ../sysdeps/generic/abort.c:88
#3  0x4003e80b in __default_terminate () from
/usr/lib/libstdc++-libc6.1-2.so.3
#4  0x4003e82c in __terminate () from /usr/lib/libstdc++-libc6.1-2.so.3
#5  0x4003f284 in throw_helper (eh=0x40060f84, pc=0x400cd4f3,
my_udata=0xbffff85c, offset_p=0xbffff858) from
/usr/lib/libstdc++-libc6.1-2.so.3
#6  0x4003f43c in __throw () from /usr/lib/libstdc++-libc6.1-2.so.3
#7  0x804908b in mysb::overflow ()
#8  0x400cd4f4 in _IO_default_xsputn (f=0x804a540, data=0x804913c, n=3) at
genops.c:197
#9  0x4003a722 in streambuf::xsputn () from
/usr/lib/libstdc++-libc6.1-2.so.3
#10 0x40038624 in ostream::operator<< () from
/usr/lib/libstdc++-libc6.1-2.so.3
#11 0x8048e4c in main () 
-------------------------------------

.. the overflow() method is called from _IO_default_xsputn() which resides
in the libio/genops.c of the glibc. Unfortunatly, this file is not
compiled with '-fexceptions' so the program will crash here.

my (quick'n hacky) Solution:
Add 
 CPPFLAGS += -fexceptions
to the libio/Makefile in glibc-2.1.3
make this work. This probably can be narrowed down to the actual
functions affected (anyone has drawn a generic call graph ?)

I haven't checked yet, but this bug may be hidden in newer glibc's as
well. The actual problem is, that libstdc++ relies on the fact, that the
c functions, it is called back by, are exception save. So beyond this very
problem described here, it should be checked in libstdc++, which
c-functions do callbacks of C++ methods -- and make them exception save in
libc. This should be reported to the glibc/libstdc++-maintainers in the
first place since this is no RedHat specific bug.

I added this as patch:
=================== glibc-ioexceptions.patch
--- libio/Makefile      Wed Jun 30 08:54:14 1999
+++ libio/Makefile.new  Mon Jul 31 18:58:47 2000
@@ -42,6 +42,8 @@
 
 include ../Makeconfig
 
+CPPFLAGS += -fexceptions
+
 ifeq ($(versioning),yes)
 routines += oldiofopen oldiofdopen oldiofclose oldiopopen oldpclose \
            oldtmpfile 
===================

IMHO, this should be fixed soon, because this renders the very improved
exception handling in recent gcc versions almost useless if you have to
work around these kinds of problems - the average programmer may not even
be aware of. Thank you for your time.

ciao,
 -hen

Comment 1 Jakub Jelinek 2000-08-09 12:49:02 UTC
glibc-2.1.92 has libio which you can partly throw exceptions through.



Note You need to log in before you can comment on or make changes to this bug.