This is the mail archive of the gcc-bugs@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]

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


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