Operating System - OpenVMS
cancel
Showing results for 
Search instead for 
Did you mean: 

Questions about C++ exceptions and signals.

 
SOLVED
Go to solution
Maxy2
Advisor

Questions about C++ exceptions and signals.

We're running V8.3 on IA64.

I'm writing some C++ code, and I have some questions about C++ exceptions and signals.

Can I invoke print a traceback directly? I have some exceptions that I am handling with C++ try-catch, and I would like the catch block to print a stack trace. I have found that I can call lib$signal with a non-severe condition code and let it propagate up all the way to the default traceback handler, which prints the traceback and then execution continues. Is there a better way to just print a traceback without raising a signal?

Second question: Is there a way to catch exceptions like an access violation or divide by zero using a C++ catch block? I've seen the trick of creating a condition handler to catch the signal and then throw a C++ exception from the handler. I'd prefer a solution, if one exists, that doesn't require a signal handler.
12 REPLIES 12
WW304289
Frequent Advisor
Solution

Re: Questions about C++ exceptions and signals.

"
Second question: Is there a way to catch exceptions like an access violation or divide by zero using a C++ catch block?
"

Yes, this is the default behaviour unless the compiler rearranges the code assuming that no C++ exception can be thrown (there is no /exception=implicit on IPF).

Also, to generate an exception for division by zero, you should compile /ieee=fast.

Thanks,
-Boris

$ cxx/ver
HP C++ V7.3-044 on OpenVMS IA64 V8.3
$ pipe cxx/ieee=fast t ; link t ; run t
C++ exception caught
C++ exception caught
$ pipe cxx t ; link t ; run t
C++ exception caught
Infinity
$

t.cxx
-----
#include

int foo() {
return *(int*)0;
}

int main() {
try {
int i = foo();
}
catch(...) {
puts("C++ exception caught");
}

try {
double x = 0.0;
double d = 1.0/x;
printf("%e\n", d);
}
catch(...) {
puts("C++ exception caught");
}
}
Dennis Handly
Acclaimed Contributor

Re: Questions about C++ exceptions and signals.

>I have some questions about C++ exceptions and signals.

Be aware this is non-standard and not portable to other OSes. Including HP-UX.
WW304289
Frequent Advisor

Re: Questions about C++ exceptions and signals.

Dennis is correct: this is not portable. A portable way would be to catch signal in a signal handler rather than in a C++ catch block.

A presense of a signal handler will make C++ run-time on VMS behave like on Unix, specifically, if there is a signal handler, the C++ run-time on VMS will allow the signal to propagate and be caught in the signal handler -- see below.

Thanks,
-Boris

$ pipe cxx t ; link t ; run t
C++ exception caught
$ pipe cxx/define=CATCH_UNIX_SIGNAL t ; link t ; run t
Unix signal caught
$

t.cxx
-----
#include
#include
#include

#ifdef CATCH_UNIX_SIGNAL
extern "C" void signal_handler(int sig) {
puts("Unix signal caught");
exit(0);
}
#endif

int foo() {
return *(int*)0;
}

int main() {
#ifdef CATCH_UNIX_SIGNAL
#ifdef __vms
signal(SIGBUS, signal_handler);
#else
signal(SIGSEGV, signal_handler);
#endif
#endif
try {
int i = foo();
}
catch(...) {
puts("C++ exception caught");
}
}
Maxy2
Advisor

Re: Questions about C++ exceptions and signals.

Why does this work?

#include
#include
#include

double foo()
{
double b=0.0;
return 11.0/b;
}

int main ()
{
try {
foo();
} catch (...) {
cout << "signal" << endl;
}
return 0;
}

dmqacxx /ieee_mode=fast test.cpp
dmqacxxlink test.obj
dmqarun test.exe
signal




And this does not?

#include
#include
#include

double foo()
{
try {
double b=0.0;
return 11.0/b;
} catch (...) {
cout << "signal" << endl;
}
return 0.0;
}

int main ()
{
foo();
return 0;
}

dmqacxx /ieee_mode=fast test.cpp
dmqacxxlink test.obj
dmqarun test.exe
%SYSTEM-F-FLTDIV_F, arithmetic fault, floating divide by zero at PC=0000000000010031, PS=0000001B
%TRACE-F-TRACEBACK, symbolic stack dump follows
image module routine line rel PC abs PC
TEST TEST foo 13143 0000000000000031 0000000000010031
TEST TEST main 13152 0000000000000292 0000000000010292
TEST TEST ELF$TFRADR 13154 00000000000003A2 00000000000103A2
0 FFFFFFFF80BA9392 FFFFFFFF80BA9392
DCL 0 000000000006BAF2 000000007AB8FAF2
%TRACE-I-END, end of TRACE stack dump
WW304289
Frequent Advisor

Re: Questions about C++ exceptions and signals.

I don't know why it works in one case and not in the other in your examples. It almost certainly has something to do with the compiler "rearranging the code" assuming that no exception can be thrown within certain section of code. Analyzing machine code (cxx/machine) could shed some light.

In fact, you cannot expect it to work reliably on IPF in either case. As I mentioned in one of the previous replies, there is no /exception=implicit on IPF which would instruct the compiler to expect C++ exception at any time thus preventing optimizations which could affect catching exceptions.

Thanks,
-Boris