Operating System - OpenVMS
1751854 Members
6104 Online
108782 Solutions
New Discussion юеВ

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
Dennis Handly
Acclaimed Contributor

Re: Questions about C++ exceptions and signals.

>WW304289: 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.

Perhaps not as complex as that. On HP-UX, the compiler assumes only function calls can produce exceptions. In the first case there is a call, the second, there isn't.
Maxy2
Advisor

Re: Questions about C++ exceptions and signals.

Dennis, I think you are on the right track. Nevertheless, this behavior does appear to be contrary to what the documentation says is supposed to happen:

from http://h71000.www7.hp.com/commercial/cplus/docs/ugv_excp.html#exceptn_chap [with some "Alpha only" text omitted]:

[quote]
The C++ exception handling facility can also be used to catch OpenVMS conditions that are raised independently of C++ throw expressions. [...] C++ catch(...) handler will catch both C++ thrown exceptions and OpenVMS conditions. [...]

You can use the data type struct chf$signal_array & , defined in the system header file chfdef.h , to catch OpenVMS conditions and to obtain information about the raised conditions. The C++ exceptions support transfers control to catch(struct chf$signal_array &) handlers when it determines that an OpenVMS condition was raised independently of a C++ throw statement.
[/quote]

Can anyone point me in the direction of documentation that describes the "exceptions can only come from function calls" behavior?

Catching a signal raised by lib$signal seems to work fine, perhaps because the exception comes from a function call. The problem seems to come when the condition comes from forcing an access violation, divide by zero, or the like.

Thanks.

The following example outputs "Caught in main:12", but it was intended to output "Caught in foo:12":


#include
#include
#include

int foo()
{
try {
int x = *(int*)0;
return x;
} catch (struct chf$signal_array &obj) {
cout << "Caught in foo:" << obj.chf$l_sig_name << endl;
}
return 0;
}

int main ()
{
try {
int i = foo();
} catch (struct chf$signal_array &obj) {
cout << "Caught in main:" << obj.chf$l_sig_name << endl;
}
return 0;
}

WW304289
Frequent Advisor

Re: Questions about C++ exceptions and signals.

"
Can anyone point me in the direction of documentation that describes the "exceptions can only come from function calls" behavior?
"

I don't think this is documented. It also depends on the function. For example, the compiler "knows" that standard C functions do not throw C++ exceptions. In the example below, there is a function call inside try block but the program crashes when compiled in default optimization mode and does not crash when compiled /noopt.

#include
#include

int main ()
{
try {
return strlen(0);
} catch (...) {
puts("caught");
}
return 0;
}

I don't think the documentation makes it clear, but the fact of the matter is that without /exception=implicit, catching non-C++ exceptions in a C++ catch block is not guaranteed to work, and it would be very difficult to describe when it works and when it does not. Do 'help cxx /exception' for description of some compiler optimizations which are prohibited in /exception=implicit mode.

Thanks,
-Boris
Dennis Handly
Acclaimed Contributor

Re: Questions about C++ exceptions and signals.

>this behavior does appear to be contrary to what the documentation says is supposed to happen:

Sorry to confuse you, I was talking about HP-UX where I have documented the restriction from the Standard.

>Can anyone point me in the direction of documentation that describes the "exceptions can only come from function calls" behavior?

This is only N logical inferences from the fact you can't throw out of a signal handler. ;-)