This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: exception handling (egsc-1.0.3, linux)
Hello Alexandre,
below the test program that causes a segmentation fault. I stripped
out all the unimportant things so that it is easy to understand. The
stat function provokes a exception.
Today I compiled the program under AIX 4.1 with gcc-2.8.1 and it
works fine on that target.
The program fails with egcs-1.0.3 release and gcc-2.8.1 under Linux
2.0.34.
Harald Maier
PS: Sorry but I have problems with generating my "From:" address.
Probably it is now better. If it is still wrong then my reply
address is <maierh@myself.com>.
Harald Maier <maierh@ate.maierh> writes:
!!! wrong address !!!
> I tried the test program too and I didn't get an error. But I have an
> similar problem when I throw an exception in an ostream manipulator. I
> will try to build a small test context.
>
--- test program ---------------------------------------------------
#include <string>
#include <iomanip.h>
#include <strstream.h>
#include <string>
class file_name
{
string _name;
public:
file_name();
file_name( const char *fn );
void set_name( const char *n );
string base(); // returns the file name without path part
};
file_name::file_name()
{
}
file_name::file_name( const char *n )
: _name(n)
{
}
void file_name::set_name( const char *n )
{
_name = n;
}
string file_name::base()
{
size_t index = 0;
size_t size = _name.size();
index = _name.rfind( "/" );
if( index < size )
return _name.substr( index + 1, size - index - 1 );
else
return _name;
}
#define fout cout << source(__FILE__,__LINE__)
#define ferr cerr << source(__FILE__,__LINE__)
template<class P1, class P2>
class omanip2
{
ostream & (*_f)( ostream &, P1, P2 );
P1 _a;
P2 _b;
public:
omanip2( ostream& (*f)(ostream&, P1, P2), P1 a, P2 b)
:_f(f), _a(a), _b(b){}
friend ostream& operator << ( ostream &o, const omanip2<P1,P2>&m){
return (*m._f)(o,m._a,m._b);
}
};
#define DEFINE_MANIP_FN2(type, function, P1, P2) \
ostream & manip_##function##( ostream &o, P1, P2 ); \
inline type<P1,P2> function ( P1 a, P2 b ) \
{ return type<P1,P2> (manip_##function,a,b); }
DEFINE_MANIP_FN2( omanip2, fld, int, int );
DEFINE_MANIP_FN2( omanip2, fld, int, ios::fmtflags );
DEFINE_MANIP_FN2( omanip2, source, const char *, int );
ostream & manip_fld( ostream &o, int len, int prec )
{
o.width( len );
o.precision( prec );
o.unsetf( ios::left );
o.setf( ios::right|ios::fixed );
return o;
}
ostream & manip_fld( ostream &o, int len, ios::fmtflags flags )
{
o.width( len );
o.setf( flags );
return o;
}
ostream & manip_source( ostream &o, const char *file, int line )
{
file_name f(file);
o.unsetf( ios::left );
o
<< fld( 10, ios::right ) << f.base().c_str() << ":"
<< fld( 3, ios::right ) << line
<< ":"
;
return o;
}
#include <sys/stat.h>
#include <unistd.h>
class file_stat
{
int _errno;
string _file_name;
struct stat _stat_buf;
public:
file_stat();
file_stat( const char *s );
~file_stat();
bool stat();
bool exists();
long size() { return _stat_buf.st_size; }
void file_name( const char *s ) { _file_name = s; }
const char * file_name() { return _file_name.c_str(); }
};
file_stat::file_stat()
:_errno(0)
{
}
file_stat::file_stat( const char *s )
:_errno(0)
,_file_name(s)
{
}
file_stat::~file_stat()
{
}
bool file_stat::stat()
{
if( !_file_name.length() )
return true;
if( ::stat( _file_name.c_str(), &_stat_buf ) == -1 )
{
_errno = errno;
//if( _errno != ENOENT )
{
throw _file_name.c_str();
}
return false;
}
return true;
}
bool file_stat::exists()
{
return stat();
}
int main( int argc, char **argv )
{
try {
const char *existing_file = argv[0];
const char *none_existing_file = "this_file_doesnt_exist";
file_stat s2( existing_file );
//file_stat s2( none_existing_file );
s2.stat();
fout << s2.file_name() << ":" << s2.size() << endl;
fout << s2.exists() << endl;
file_stat s3( none_existing_file );
s3.stat(); // stat throws an exception
fout << s3.exists() << endl;
} catch( const char * s ) {
fout << "Exception: " << s << endl;
}
}
// COMMENTS:
// Then I substitute the macro fout with cout all works fine.
// fout calls the macro
// cout << source( __FILE__, __LINE__ )
//
// Then I switch the s2 instantiation with the out commented "none
// existing file" instantiation, s2.stat() throws the exception
// correctly.
//
// I tried it with the gcc-2.8.1 too. The behavior was identical.
//
// egcs-version:
// Reading specs from
// /usr/local/lib/gcc-lib/i686-pc-linux-gnulibc1/egcs-2.90.29/specs
// gcc version egcs-2.90.29 980515 (egcs-1.0.3 release)
// gcc-version:
// Reading specs from
// /usr/lib/gcc-lib/i686-pc-linux-gnulibc1/2.8.1/specs
// gcc version 2.8.1
// AIX 4.1 and gcc version 2.8.1 works fine