Bug 40797

Summary: Exceptions in std::streambuf methods causing core-dump
Product: [Retired] Red Hat Raw Hide Reporter: Enrico Scholz <rh-bugzilla>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED DEFERRED QA Contact: David Lawrence <dkl>
Severity: medium Docs Contact:
Priority: medium    
Version: 1.0CC: drepper
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2001-05-15 23:18:40 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Enrico Scholz 2001-05-15 23:18:36 UTC
Description of Problem:

It is impossible to throw exceptions in the overflow() method of own
std::streambuf subclasses.

I think this happens because streambuf::overflow() is called by C functions
and gcc can not pass exceptions through them. But the C++ standard says in
27.5.2.4.5 [lib.streambuf.virt.put]:

| int_type overflow(int_type c = traits::eof());
| ...
| Returns: traits::eof() or throws an exception if the function fails.

so exceptions should be possible there


How Reproducible:

---- example.cc ------------
#include <iostream>

struct foo      :  public std::streambuf
{
        int overflow(int c = EOF) { throw int(42); }
};

int main()
        try
{
        foo             a;
        std::ostream    b(&a);

        b << '1';
}
catch (...) { std::cout << "Ok" << std::endl; }
------------------------


Steps to Reproduce:
1. compile and run program above


Actual Results:

$ ./a.out 
Aborted (core dumped)


Expected Results:

$ ./a.out 
Ok


Additional Information:

$gdb a.out core
(gdb) bt
#0  0x400c17f1 in __kill () from /lib/i686/libc.so.6
#1  0x400c15ca in raise (sig=6) at ../sysdeps/posix/raise.c:27
#2  0x400c2d72 in abort () at ../sysdeps/generic/abort.c:88
#3  0x40050efb in __default_terminate () at ../../gcc/libgcc2.c:3034
#4  0x40050f1a in __terminate () at ../../gcc/libgcc2.c:3034
#5  0x40051c55 in throw_helper (eh=0x4006ec80, pc=0x4010bf5b,
my_udata=0xbffff4d0, 
    offset_p=0xbffff4cc) at ../../gcc/libgcc2.c:3168
#6  0x40051e7a in __throw () at ../../gcc/libgcc2.c:3168
#7  0x08049217 in foo::overflow () at tmp/exc.cc:5
#8  0x40110720 in __overflow (f=0xbffff690, ch=49) at genops.c:200
#9  0x4010bf5c in _IO_putc (c=49, fp=0xbffff690) at putc.c:33
#10 0x40049738 in ostream::operator<< () from
/usr/lib/libstdc++-libc6.2-2.so.3
#11 0x08048fda in main () at tmp/exc.cc:14
#12 0x400b0177 in __libc_start_main (main=0x8048f90 <main>, argc=1,
ubp_av=0xbffff7ac, 
    init=0x8048be4 <_init>, fini=0x8049250 <_fini>, rtld_fini=0x4000e184
<_dl_fini>, 
    stack_end=0xbffff79c) at ../sysdeps/generic/libc-start.c:129


$ rpm -q glibc gcc
gcc-2.96-84
glibc-2.2.2-10

Comment 1 Jakub Jelinek 2001-05-16 12:50:52 UTC
gcc can pass exceptions through C functions if they were compiled with
-fexceptions. A couple of routines in glibc are (such as sort, bsearch, etc.),
most of them are not.
In this particular case:
#0  0x080491d8 in foo::overflow (this=0xbffff970, c=49) at o.C:5
#1  0x4010a200 in __overflow (f=0xbffff970, ch=49) at genops.c:200
#2  0x40105a4c in _IO_putc (c=49, fp=0xbffff970) at putc.c:33
#3  0x400446c8 in ostream::operator<< () from /usr/lib/libstdc++-libc6.2-2.so.3
genops.c was compiled with -fexceptions while putc.c was not.
This test fails with egcs 1.1.2 and gcc-2.95.2, but works with libstdc++-v3,
so IMHO it is not worth bloating glibc because of this when gcc 3.0 will be
out soon. A fully standard compliant libstdc++ is not anything below libstdc++-v3
anyway, so this is just yet another incompatibility.