Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to catch all runtime exception

373 views
Skip to first unread message

chris

unread,
Nov 15, 2005, 1:30:21 AM11/15/05
to
Hi,

I write some code guarded with exception handling...
simplified code look like this...


int main(int argc, char* argv[]){


try{

// code that might be throw runtime exception
// .....
// .....
}
catch(...){

}

return 0;
}

but when I ran the code, how come the code throw uncaught runtime
exception ?
I think the catch(...) block should catch all runtime exception ...
Or am I wrong ?

Thanks in advance

Neelesh Bodas

unread,
Nov 15, 2005, 1:51:31 AM11/15/05
to

Not sure what you mean by "runtime exception". "runtime_error"s
(range_error etc) will be caught by catch(...). If you are talking
about floating point exceptions etc, they are asyncronous events and
hence are not handelled by C++ exception handling mechanism.

Posting the actual code might help.

> Thanks in advance

chris

unread,
Nov 15, 2005, 2:08:35 AM11/15/05
to
Thanks Neelesh Bodas,

So, there's no way in C++ I can handle any runtime exception ?
Anyway, I'm coming from Java environment, and all exception
inherited from Exception class, so I can caught all runtime
exception. the point is, how can I prevent my code to "explode",
caused by uncaught exception.

Alf P. Steinbach

unread,
Nov 15, 2005, 2:17:23 AM11/15/05
to
* chris:

In C++, if you have an integer divide by zero, say, you have a bug that
should be fixed.

There is no guarantee of exceptions for bug manifestations.

Neither is there such a guarantee in Java, but in Java you have a better
chance of suppressing the most common _immediate_ effects of bugs, the
Ostrich policy of "what I don't see doesn't exist", until the bugs have
multiplied & migrated to the point where the code can't be rescued.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

yuvalif

unread,
Nov 15, 2005, 3:08:25 AM11/15/05
to
I once wrote a C++ class that convert OS signals to exceptions. The
problem is what to do when you catch the signal, as Alf said, when you
encounter a bug you should fix it. But if you have a program that does
large iterations and kind of clean itself between iterations it might
be helpfull:

#ifndef SIG_EXCEPT_H
#define SIG_EXCEPT_H

/*******************************************************************************
File name : sigexception.h
Programmer : Yuval Lifshitz
Date : 03-sep-2003
Description : Try/Catch mechanism for OS signals.
Usage example:

TRY {
// write code here
}

CATCH {
// write code here
ex.WriteMsg();
cout << "signal number = " << ex.getSignal() << endl;
}

Notes: (1) This mechanism is NOT thread safe.
(2) The CATCH macro must follow immediatly after the
closing brackets of the TRY macro
(3) inside the CATCH block there exists a local variable
named ex holding the thrown signal data.

Change log : 23-sep-2004 make gcc compatible
add thread index hashing
*******************************************************************************/

// include files
#include <stack>
#include <iostream>
#include <pthread.h>
#include <signal.h>
#include <setjmp.h>

// signal description list - used at the psignal function
extern const char *const sys_siglist[];

// jump function type
extern "C" {
typedef void (*jump_func_t)(int);
}

// main class definition
class TryCatchAsync
{
public:

// const and enum
enum {MAX_THREAD_NUM = 100};

//---------------------------
// internal class/type definitions
//---------------------------

//---------------------------------------------------------------
// Class Name : sigjmp_container
// Description : Container to encapsulate the sigjmp_buf type.
// This is done for the conviniece of allocation,
// since the original type is an array of integers.
//----------------------------------------------------------------
class sigjmp_container {
private:
sigjmp_buf m_sigbuf;

public:
sigjmp_container() {}
~sigjmp_container() {}

operator sigjmp_buf * ()
{
return &m_sigbuf;
}

sigjmp_buf * get_buf()
{
return &m_sigbuf;
}
};

//-----------------------------------------------
// Class Name : Exception
// Description : The exception thrown by the try
//-----------------------------------------------
class Exception {
public:
Exception(int sig) : m_sig(sig) {}

int getSignal() const
{
return m_sig;
}

void WriteMsg() const
{
psignal(m_sig, "signal thrown");
}

private:

int m_sig;
};

// jump adresses stack type
typedef std::stack<sigjmp_container> jump_stack_t;

// the constructor is used to generate the array of jump functions
// the object should be instanciated only once - but has no effect
// if instanciated more then once, since the relevant execution
// is done in compile time

// constructor
TryCatchAsync();

// destructor
~TryCatchAsync() {}

// static member functions
static void SigMaskAdd(int sig);
static void Push(sigjmp_container &curr_addr);
static void Throw();
static int GetThreadIndex();

// member functions
template <int func_id>
static void Jump(int sig)
{
pthread_t pt = GetThreadIndex();
m_sig[pt] = sig;
siglongjmp(*(sigjmp_buf *)m_addr[pt].top().get_buf(), 1);
}

private:

// data members
static int m_sig[MAX_THREAD_NUM];
static jump_stack_t m_addr[MAX_THREAD_NUM];
static jump_func_t m_jump_func[MAX_THREAD_NUM];
};

//-----------------------------------------------
// Class Name : JUMP_FUNC_GENERATOR
// Description : a template struct that instanciate
// an array of different "Jump" functions.
// Note: this is done in a "generative programming"
// method in compile time.
//-----------------------------------------------
template <int N>
struct JUMP_FUNC_GENERATOR
{
JUMP_FUNC_GENERATOR(jump_func_t *jump_func_arr)
{
jump_func_arr[N-1] = TryCatchAsync::Jump<N-1>;
JUMP_FUNC_GENERATOR<N-1> tmp_creator(jump_func_arr);
tmp_creator = tmp_creator; // to avoid "unusead variable" warning
}
};

// termination condition for the generative process
template <>
struct JUMP_FUNC_GENERATOR<0>
{
JUMP_FUNC_GENERATOR(jump_func_t *jump_func_arr)
{
jump_func_arr[0] = TryCatchAsync::Jump<0>;
}
};

//------------------
// macro definitions
//------------------

#define SIG_INIT \
TryCatchAsync::SigMaskAdd(SIGFPE); \
TryCatchAsync::SigMaskAdd(SIGSEGV); \
TryCatchAsync::SigMaskAdd(SIGILL); \
TryCatchAsync::SigMaskAdd(SIGBUS);
// note: new signals should be added in the SIG_INIT macro

#define TRY SIG_INIT try { TryCatchAsync::sigjmp_container curr_addr;\
if (sigsetjmp(*(sigjmp_buf *)curr_addr, 1) == 0) { \
TryCatchAsync::Push(curr_addr); \
} \
else { \
TryCatchAsync::Throw(); \
}

#define CATCH } catch(TryCatchAsync::Exception &ex)

#endif // RSEXCEPT_H

0 new messages