[Search for users]
[Overall Top Noters]
[List of all Conferences]
[Download this site]
Title: | C++ |
Notice: | Read 1.* and use keywords (e.g. SHOW KEY/FULL KIT_CXX_VAX_VMS) |
Moderator: | DECCXX::AMARTIN |
|
Created: | Fri Nov 06 1987 |
Last Modified: | Thu Jun 05 1997 |
Last Successful Update: | Fri Jun 06 1997 |
Number of topics: | 3604 |
Total number of notes: | 18242 |
3525.0. "Exception handling: targetted catch clause not found (AVMS)" by PTHRED::SHARRIS () Wed Apr 02 1997 15:19
Since we upgraded our cluster to VMS V7.1, we've noticed problems with a
particular test that uses C++ exception handling. We don't run this test
often, so I don't know if this is related to the V7.1 upgrade or just the
version of C++ or something else.
We are using C++ V5.3-005, and this problem occurs only on AlphaVMS, altho we
have the same version of C++ on VAX/VMS. However, our VAX/VMS systems are
still V7.0, not V7.1. The problem doesn't seem to occur on UNIX either.
I've read notes 3004, 3032, 3061, 3137 so I know there were problems with
exception handling in this version of C++, but I'm still wondering if this is
the same problem or not. I haven't seen anything with quite the same signature
error.
The problem is that when we throw an exception, we get this:
Internal C++ runtime error, targetted catch clause not found.
%DEBUG-I-DYNIMGSET, setting image RB_CONSUMER
%SYSTEM-F-OPCDEC, opcode reserved to Digital fault at PC=0000000000035034, PS=0000001B
break on unhandled exception at CXXL$CALL_CLEANUP+20 in %TASK 5
DBG> show calls
module name routine name line rel PC abs PC
CXXL$CALL_CLEANUP 0000000000000014 0000000000035034
----- the above appears to be a null frame in the same scope as the frame below
SKSTREAM ? ?
SKSTREAM 0000000000000000 0000000000031908
*RB_CONSUMER UnitConsumer::MakeRequest
15493 00000000000003CC 0000000000030D94
*RB_CONSUMER UnitConsumer::TimerCallback
15553 0000000000000028 0000000000031370
*RB_CONSUMER Timer::TimerAgent
14668 000000000000005C 00000000000301A4
SHARE$PTHREAD$RTL 0000000000000000 00000000004E6148
SHARE$PTHREAD$RTL 0000000000000000 00000000004D7294
0000000000000000 0000000000000000
----- the above appears to be a null frame in the same scope as the frame below
SHARE$PTHREAD$RTL ? ?
0000000000000000 FFFFFFFF83B0B16C
DBG>
Is this a known problem???? Is there anything we can be doing that
would cause this kind of error???
Also note that we get this message when we try running an image that was LINKED
on V7.0:
run/debug rb_consumer_sav.exe
OpenVMS Alpha DEBUG Version V7.1-000
%DEBUG-E-INCDSTNES, incorrect DST nesting in module CXXL$VMS_CXX_EXC, compiler error
-DEBUG-I-DSTLOC, error occurs 00001779 bytes from beginning of DST
%DEBUG-I-INITIAL, Language: C, Module: CXXL$VMS_CXX_EXC
DBG>
I know something like this was mentioned in note 3004.*, but when
I tried adding a copy constructor, it seemed to have no affect on
the original accvio.
Part of the code follows, but I'm not including the entire set of sources
because even with them, it's not easy to reproduce the error. We
only see this error when this 'client' program communicates via RPC
with Resource Broker, causes a server to get started, and then tries to
communicate with the server, and the communication gets an error such that
it throws an exception. It actually happens EVERY time on AlphaVMS
because of the timing, but the setup for you would be fairly brutal. If you
can't tell anything from what is here, I'd be glad to work with you on
our version here in ZK2-3.
Thanks,
Sue Harris
======================================
$ cxx /exception=clean/define=PTHREAD_USE_D4 /debug/noopt /INCLUDE=([]) skstream
Building client executable...
$ cxx /exception=clean/define=PTHREAD_USE_D4 /debug/noopt /INCLUDE=([]) rb_consumer
$ cxxlink /debug /exe=rb_consumer.exe rb_consumer.obj, -
skstream.obj, -
sys$library:rb$option.opt/opt, -
sys$input:/opt
SYS$LIBRARY:CMA$OPEN_LIB_SHR/SHARE
SYS$LIBRARY:CMA$LIB_SHR/SHARE
SYS$LIBRARY:CMA$OPEN_RTL/SHARE
SYS$LIBRARY:CMA$RTL/SHARE
// skstream.h
// Copyright (C) 1995, 1996 by John C. Wang. All Rights Reserved.
//
// You may distribute this file with your product in either of two ways:
// IN SOURCE CODE FORM: You must include this file in its entirety.
// IN OBJECT CODE FORM: You must give proper acknowledgements to the author(s)
// of this program. This may take the form of credits on the start-up screen.
//
// IN ANYCASE, THIS SOFTWARE IS DISTRIBUTED WITHOUT ANY KIND OF EXPLICIT OR
// IMPLICIT WARRANTIES AND THE AUTHORS ARE NOT RESPONSIBLE FOR ANY EVENTS THAT
// OCCURS AS A RESULT OF USING THIS SOFTWARE.
//
// History:
// [JCW 95-Dec-04] created
// [JCW 95-Dec-20] comments added for distribution 95a
// [JCW 96-Jan-01] removed UDP capabilities from skstream
#ifndef __SOCKET_STREAM__
#define __SOCKET_STREAM__
#include <iostream.h>
#ifndef _WIN32
typedef int SOCKET;
#include <sys/socket.h>
#else
# include <winsock.h>
#endif
//
// sockbuf
//
class sockbuf : public streambuf
{
public:
sockbuf( SOCKET & );
sockbuf( SOCKET &, char *, int );
virtual ~sockbuf();
virtual int overflow(int =EOF) ;
virtual int underflow() ;
virtual int sync();
protected:
char *_buffer ;
// sockbuf specific
SOCKET &_socket ;
} ;
//
// skstream
//
class skstream : public iostream {
public:
// constants
enum service
{
ftp = 21, //tcp
telnet = 23, //tcp
smtp = 25, //tcp mail
time = 37, //tcp timserver
name = 42, //tcp nameserver
nameserver = 53, //tcp domain # name-domain server
finger = 79, //tcp
http = 80, //tcp
pop = 109, //tcp postoffice
pop2 = 109, //tcp # Post Office
pop3 = 110, //tcp postoffice
nntp = 119 //tcp usenet # Network News Transfer
} ;
enum role
{
server ,
client
} ;
// methods
skstream( void );
skstream( const char *addr, int, const role = client ) ;
skstream( SOCKET );
~skstream( void );
void open( const char *addr, const service, const role = client ) ;
void close( void ) ;
int is_open( void ) const ;
void attach( SOCKET = 0 );
SOCKET getsocket() const ;
char *getpeername( char * = NULL, int = 0) const ;
unsigned short getport( void ) const ;
protected:
SOCKET _socket ;
sockbuf _sockbuf ;
// platform dependent library housekeeping
inline void init( void ) ;
inline void shutdown( void ) ;
};
#endif // ndef __SOCKET_STREAM__
// skstream.cpp
// Copyright (C) 1995, 1996 by John C. Wang. All Rights Reserved.
//
// You may distribute this file with your product in either of two ways:
// IN SOURCE CODE FORM: You must include this file in its entirety.
// IN OBJECT CODE FORM: You must give proper acknowledgements to the author(s)
// of this program. This may take the form of credits on the start-up screen.
//
// IN ANYCASE, THIS SOFTWARE IS DISTRIBUTED WITHOUT ANY KIND OF EXPLICIT OR
// IMPLICIT WARRANTIES AND THE AUTHORS ARE NOT RESPONSIBLE FOR ANY EVENTS THAT
// OCCURS AS A RESULT OF USING THIS SOFTWARE.
//
// History:
// [JCW 95-Dec-04] created
// [JCW 95-Dec-20] comments added for distribution 95a
// [JCW 96-Jan-01] removed UDP capabilities from skstream
#include "skstream.h"
#include <assert.h>
#ifndef _WIN32
# include <stdlib.h> // NULL && free()
# include <string.h> // strdup() needed later
# define INVALID_SOCKET ( -1 )
# define SOCKET_ERROR ( -1 )
typedef struct sockaddr_in SOCKADDR_IN;
# define SO32
# define MPTN
extern "C" {
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <netdb.h>
}
#define sock_init() 0
#include <unistd.h>
#include <arpa/inet.h>
#ifdef __VMS
#define getpeername_size_t size_t
#else
#define getpeername_size_t int
#endif
#else // _WIN32
#define getpeername_size_t int
#endif // _WIN32
#ifdef _DEBUG
#define dassert(x) assert(x)
#define debug(x) x
#else
#define dassert(x)
#define debug(x)
#endif //def _DEBUG
//
// skstream
//
void skstream::init( void )
{
// platform dependent initialization
try {
#ifdef _WIN32
const WORD wMinVer = 0x0101; // request v 1.1
WSADATA wsaData;
if( 0 != WSAStartup( wMinVer, &wsaData ) )
#else
if ( sock_init( ) != 0 )
#endif
throw "Cannot init socket library." ;
}
catch( char *error )
{
throw error ;
}
}
void skstream::shutdown( void )
{
// platform dependent shutdown
try {
#ifdef _WIN32
if( 0 != WSACleanup() )
throw "Cannot shutdown socket library." ;
#else
return;
#endif
}
catch( char *error )
{
throw error ;
}
}
skstream::skstream( void ) : _sockbuf( _socket ), iostream( &_sockbuf )
{
init() ;
attach( INVALID_SOCKET ) ;
}
skstream::skstream( const char *addr, int port, const role side )
:_sockbuf( _socket ), iostream( &_sockbuf )
{
ios::init(&_sockbuf);
init() ;
attach( INVALID_SOCKET ) ;
open( addr, (service)port, side ) ;
}
skstream::skstream( SOCKET sock ) : _sockbuf( _socket ), iostream( &_sockbuf )
{
init() ;
attach( sock ) ;
}
skstream::~skstream( void )
{
close() ;
shutdown() ;
}
int skstream::is_open( void ) const
{
return ( INVALID_SOCKET != getsocket() ) ;
}
void skstream::open( const char *addr, const service port,
const role side )
{
if( is_open() )
close() ;
try {
printf ("going to try the create");
// 1. Create socket
if( INVALID_SOCKET == ( _socket = ::socket( PF_INET, SOCK_STREAM, 0 ) ) )
throw "Socket creation error." ;
// 2. Bind
printf ("going to try the bind");
SOCKADDR_IN sa ;
sa.sin_family = AF_INET ;
#ifdef _WIN32
sa.sin_addr.S_un.S_addr = INADDR_ANY ;
#else
sa.sin_addr.s_addr = INADDR_ANY;
#endif
sa.sin_port = side == client ? 0 : htons( (unsigned short)port ) ;
// rationale: no client requires fixed port number, so let system assign
if( SOCKET_ERROR == ::bind( _socket, (sockaddr *)&sa, sizeof( sa ) ) )
throw "Binding error." ;
// From now on the two sides are very much different
if( side == skstream::client )
{
printf ("going to try the connect");
// 3(cli). Connect
SOCKADDR_IN sa ;
sa.sin_family = AF_INET ;
hostent *he ;
#ifdef _WIN32
if( NULL == ( he = ::gethostbyname( addr ) ) )
throw "Cannot resolve remote server." ;
sa.sin_addr.S_un.S_addr = *(unsigned long *)( he->h_addr_list[ 0 ] ) ;
#else
/*
** The prototype for BSD (OS/2) sockets has a non-const paramater
** for gethostbyname()... any C++ compiler worth squat is going
** to choke on an attempt to pass a const char* to a char* :-)
** Make a copy of the string locally as a work-around.
*/
char *tmps = strdup( addr );
printf ("going to try the gethostbyname");
if( NULL == ( he = ::gethostbyname( tmps ) ) )
throw "Cannot resolve remote server." ;
free( tmps );
sa.sin_addr.s_addr = *(unsigned long *)( he->h_addr_list[ 0 ] );
#endif
sa.sin_port = htons( port ) ;
printf ("going to try the connect (again)\n");
if( SOCKET_ERROR == ::connect( _socket, (sockaddr *)&sa, sizeof( sa ) ) )
throw "Connection error." ; <---------------------------------------the error happens here
}
else
{
// 3(svr). Listen
printf ("try listen");
if( SOCKET_ERROR == ::listen( _socket, 1 ) )
throw "Listening error." ;
// 4. Accept
SOCKET commsock ;
printf ("try accept");
if( INVALID_SOCKET == ( commsock = ::accept( _socket, NULL, NULL ) ) )
throw "Accepting error." ;
#ifdef _WIN32
if( SOCKET_ERROR == ::closesocket( _socket ) )
#else
printf ("try close");
if( SOCKET_ERROR == ::close( _socket ) )
#endif
throw "Cannot close server socket." ;
_socket = commsock ;
}
}
catch( char * )
{
// instead of throwing, user will find out by testing is_open()
printf ("close in catch block");
close() ;
}
}
void skstream::close( void )
{
try {
if( is_open() )
{
_sockbuf.sync() ;
#ifdef _WIN32
if( SOCKET_ERROR == ::closesocket( _socket ) )
#else
if( SOCKET_ERROR == ::close( _socket ) )
#endif
throw "Cannot close socket." ;
}
_socket = INVALID_SOCKET ;
}
catch( char *error )
{
throw error ;
}
}
void skstream::attach( SOCKET sock )
{
_socket = sock ;
}
SOCKET skstream::getsocket() const
{
return _socket ;
}
char *skstream::getpeername( char *buf, int size ) const
{
try {
SOCKADDR_IN sa ;
getpeername_size_t sasize = sizeof( sa ) ;
if( SOCKET_ERROR ==::getpeername( getsocket(), (sockaddr *)&sa, &sasize ) )
throw "Cannot get peer name." ;
if (buf) {
strncpy( buf, inet_ntoa( sa.sin_addr ), size - 1 ) ;
return buf ;
}
else return inet_ntoa( sa.sin_addr );
}
catch( char * )
{
return NULL ;
}
}
unsigned short skstream::getport( void ) const
{
try {
SOCKADDR_IN sa ;
getpeername_size_t sasize = sizeof( sa ) ;
if( SOCKET_ERROR ==::getpeername( getsocket(), (sockaddr *)&sa, &sasize ) )
throw "Cannot get peer name." ;
return ntohs( sa.sin_port ) ;
}
catch( char * )
{
return ntohs( IPPORT_RESERVED ) ;
}
}
//
// sockbuf
//
sockbuf::sockbuf( SOCKET &sock ) : _socket( sock ), streambuf( NULL, 0 )
{
const int insize = 0x4000 ; // allocate 16k buffer each for input and output
const int outsize = 0x4000 ;
const int bufsize = insize + outsize ;
_buffer = new char [ bufsize ] ;
if( this != setbuf( _buffer, bufsize ) )
_buffer = NULL ;
else
{
setp( _buffer, _buffer + insize ) ;
setg( _buffer + insize, _buffer + bufsize, _buffer + bufsize ) ;
}
}
sockbuf::sockbuf( SOCKET &sock, char *buf, int length )
: _socket( sock ), streambuf( buf, length )
{
_buffer = NULL ;
setp( buf, buf + length / 2 ) ;
setg( buf + length / 2, buf + length, buf + length ) ;
}
sockbuf::~sockbuf()
{
delete[] _buffer ;
_buffer = NULL ;
}
int sockbuf::overflow( int nCh )
{
try
{
if( _socket == INVALID_SOCKET )
throw "Invalid socket!" ;
if( pptr() - pbase() <= 0 )
// nothing to send
return 0 ;
int size ;
if( SOCKET_ERROR == ( size = ::send( _socket, pbase(), pptr() - pbase(), 0 ) ) )
throw "(TCP) Cannot send." ;
if( size == 0 )
// remote site has closed this connection
return EOF ;
if( nCh != EOF ) // size >= 1 at this point
{
size-- ;
*( pbase() + size ) = nCh ;
}
// move remaining pbase() + size .. pptr() - 1 => pbase() .. pptr() - size - 1
for( char *p = pbase() + size; p < pptr(); p++ )
*( p - size ) = *p ;
const int newlen = ( pptr() - pbase() ) - size ;
setp( pbase(), epptr() ) ;
pbump( newlen ) ;
return 0 ;
}
catch( char * )
{
// instead of throwing, user will find out by testing fail()
return EOF ;
}
}
int sockbuf::underflow()
{
try
{
// if get area not empty, return first character
// else fill up get area and return 1st character
if( _socket == INVALID_SOCKET )
throw "Invalid socket!" ;
if( egptr() - gptr() > 0 )
return *gptr() ;
// fill up from eback to egptr
int size ;
if( SOCKET_ERROR == ( size = ::recv( _socket, eback(), egptr() - eback(), 0 ) ) )
throw "(TCP) Receive error." ;
if( size == 0 )
// remote site has closed this connection
return EOF ;
// move rcvd data from eback() .. eback() + size to egptr() - size .. egptr()
const int delta = egptr() - ( eback() + size ) ;
for( char *p = eback() + size - 1; p >= eback(); p-- )
{
dassert( p + delta >= eback() ) ;
dassert( p + delta < egptr() ) ;
*( p + delta ) = *p ;
}
setg( eback(), egptr() - size, egptr() ) ;
return *gptr() ;
}
catch( char * )
{
// instead of throwing, user will find out by testing eof()
return EOF ;
}
}
int sockbuf::sync()
{
if( EOF == overflow() )
return EOF ; // ios will set the fail bit
else
{
// empty put and get areas
setp( pbase(), epptr() ) ;
setg( eback(), egptr(), egptr() ) ;
return 0 ;
}
}
T.R | Title | User | Personal Name | Date | Lines |
---|
3525.1 | can you try 5.4 or 5.5? | HNDYMN::MCCARTHY | A Quinn Martin Production | Fri Apr 04 1997 08:40 | 15 |
| Following your notes:
3004: You say you have added a copy ctor so that should not be the problem
3032: You don't have any try blocks within the code-example catch blocks
so that should not be it.
3061: You are using /noopt so that should remove this problem
3137: There isn't a solution posted except "upgrade" and some issues of
a third party requireing 5.3.
Along those lines - is there any way you can try this using a 5.4 or even a
5.5 compiler? If the problem is in the generated exception handling, or
even in the object code provided by the compiler, the answer to a problem
report would be "fixed in next release" (at least I hope it is).
Brian J.
|
3525.2 | being worked | HNDYMN::MCCARTHY | A Quinn Martin Production | Mon Apr 07 1997 08:30 | 5 |
| Working this off line (images produced on a OpenVMS V6.2 system using 5.5
do not show the problem but linking those objects on the other system is
causing hangs).
bjm
|