3

I'm maintaining an application that's been must run op Alpha OpenVMS (7.3-2) and Itanium OpenVMS (8.4). It's written in C++, compiler version is 6.5-046 on Alpha and 7.4-004 on IA64.

The issue I have is with LIB$SIGNAL(). As soon as it signals a fatal message, the program aborts.

First the code to reproduce this (as a DCL script that generates and builds the code):

$ create mtst.msg
.TITLE  Message file for MTST
.IDENT  'VERSION 1.1'
.FACILITY MTST,1 /PREFIX=MTST_
.SEVERITY INFORMATIONAL
HELLO       <Hello World> /fao_count=0
.SEVERITY SUCCESS
SUCCESS     <Opdracht succesvol uitgevoerd> /fao_count=0
.SEVERITY WARNING
WHOOPS      <Dit is een waarschuwing: !AZ> /fao_count=1
.SEVERITY ERROR
WHAAA       <Oeioeioei dat was op het randje> /fao_count=0
.SEVERITY   FATAL
AARGH       <Nu is het helemaal mis> /fao_count=0
.END
$!
$ create msgtest.h
#define __NEW_STARLET 1
#include<lib$routines.h>
#include<stsdef.h>

#pragma extern_model globalvalue

extern unsigned long MTST_HELLO;
extern unsigned long MTST_SUCCESS;
extern unsigned long MTST_WHOOPS;
extern unsigned long MTST_WHAAA;
extern unsigned long MTST_AARGH;

#pragma extern_model relaxed_refdef
$!
$ create msgctest.c
#include<msgtest.h>
#include<stdio>
#include<stdlib.h>

int main(void) {
    char* msgArgument = "Boe!";
    printf ("Test: info message...\n");
    LIB$SIGNAL(MTST_HELLO);
    printf("\n");

    printf ("Test: success message...\n");
    LIB$SIGNAL(MTST_SUCCESS);
    printf("\n");

    printf ("Test:  warning message...\n");
    LIB$SIGNAL(MTST_WHOOPS, 1, msgArgument);
    printf("\n");

    printf ("Test: error message...\n");
    LIB$SIGNAL(MTST_WHAAA);
    printf("\n");

    printf ("Test: fatal message...\n");
    LIB$SIGNAL(MTST_AARGH);
    printf("\n");

    printf ("Einde test!\n");
}
$!
$ create msgtest.cpp
#include<msgtest.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
#include <chfdef.h>
int main(void) {
    char* msgArgument = "Boe!";
    cout << "Using IOStream:" << endl << "Test: info message..." << endl;
    LIB$SIGNAL(MTST_HELLO);
    cout << endl << "Test: success message..." << endl;
    LIB$SIGNAL(MTST_SUCCESS);
    cout << endl << "Test:  warning message..." << endl;
    LIB$SIGNAL(MTST_WHOOPS, 1, msgArgument);
    cout << endl << "Test: error message..." << endl;
    LIB$SIGNAL(MTST_WHAAA);
    cout << endl << "Test: fatal message..." << endl;
    LIB$SIGNAL(MTST_AARGH);

    // Next line is, of course, never displayed...
    cout << endl << "Einde test!" << endl;

}
$!
$! Compile the message file
$ message mtst
$!
$! As a reference, build an executable using the C-source. Will always work both on Alpha and Itanium
$ cc/lis=[] /include=[] msgctest.c /warn=(disa=dollarid)/notrace
$ link msgctest,mtst  /map=[]/cross/notrace
$!
$! Now build the C++ based exe.
$ cxx/lis=[]/reposi=[] /include=[] msgtest.cpp /warn=(disa=dollarid)/notrace/standard=strict_ansi
$! Using this compile statement it works on Itanium:
$! cxx/lis=[]/reposi=[] /include=[] msgtest.cpp /warn=(disa=dollarid)/notrace
$! Using this compile statement it fails again:
$! cxx/lis=[]/reposi=[] /include=[] msgtest.cpp /warn=(disa=dollarid)/notrace/define=(__USE_STD_IOSTREAM)
$ cxxlink msgtest,mtst /map=[]/cross/notrace
$!

The C-source always works and on Alpha both scripts work.

When compiling without the /STANDARD it works well on Itanium, but in the original program I had problems using iostream: I need ANSI there, but a compile with /DEFINE=(__USE_STD_IOSTREAM) brought back the original issue.

$r msgtest
Test: info message...
%MTST-I-HELLO, Hello World

Test: success message...
%MTST-S-SUCCESS, Opdracht succesvol uitgevoerd

Test: inwarningfo message...
%MTST-W-WHOOPS, Dit is een waarschuwing: Boe!

Test: error message...
%MTST-E-WHAAA, Oeioeioei dat was op het randje

Test: fatal message...
%CXXL-F-TERMINATING, terminate() or unexpected() called
$

What I expect is this:

$ r msgctest
Test: info message...
%MTST-I-HELLO, Hello World

Test: success message...
%MTST-S-SUCCESS, Opdracht succesvol uitgevoerd

Test:  warning message...
%MTST-W-WHOOPS, Dit is een waarschuwing: Boe!

Test: error message...
%MTST-E-WHAAA, Oeioeioei dat was op het randje

Test: fatal message...
%MTST-F-AARGH, Nu is het helemaal mis
$

So... %CPP-?-WTF, help please :-/

Thanks in advance, Oscar

Note: in the original post I made yesterday, there was a different script with some more testcode like a try/catch. Of course that changed the testresult as user2116290 stated in his/her comment. I changed the DCL script to the original test to reproduce what I see in the originating app.

Oscar
  • 65
  • 6

1 Answers1

3

So far, I don't see a/the problem.

$ sh symb x
  X = 134316076   Hex = 0801802C  Octal = 01000300054
$ search *.lis 0801802C/noheader
                         0801802C    13 AARGH       <Nu is het helemaal mis> 

On Alpha (I tried it with HP C++ V7.1-015 for OpenVMS Alpha V8.3), you are catching your error code. Then you call abort() which signals 0x434, the OPCCUS, which looks OK to me.

On Alpha, if I remove the try/catch the c++-program behaves as the c-program. I have no access to an I64 with c++, so I can't double check what the result of an abort abort() will be on I64. It may just be %CXXL-F-TERMINATING.

New update:

It looks like the combination of strict ansi mode and standard iostreams triggers a C++ catch all handler, which catches the fatal VMS condition/exception. In your example it seems possible to disable catching VMS conditions with:

$ diff -ub old.cpp new.cpp
--- old.cpp     2015-11-11 19:42:52 +0100
+++ new.cpp     2015-11-11 19:49:10 +0100
@@ -1,8 +1,14 @@
 #include<msgtest.h>
 #include<iostream>
 #include<stdlib.h>
+#ifdef __ia64
+#include<cxx_exception.h>
+#endif
 using namespace std;
 int main(void) {
+#ifdef __ia64
+    cxxl$set_condition(pure_unix);
+#endif
     char* msgArgument = "Boe!";
     cout << "Using IOStream:" << endl << "Test: info message..." << endl;
     LIB$SIGNAL(MTST_HELLO);

Compiling, linking and running the changed example:

    $ cxx /standard=strict_ansi/lis/warn=(disa=dollarid)/notrace/incl=[]/repo=[] new.cpp
    $ link /map=new/full=demangled/cross/notrace new, mtst
    $ r new
    Using IOStream:
    Test: info message...
    %MTST-I-HELLO, Hello World

    Test: success message...
    %MTST-S-SUCCESS, Opdracht succesvol uitgevoerd

    Test:  warning message...
    %MTST-W-WHOOPS, Dit is een waarschuwing: Boe!

    Test: error message...
    %MTST-E-WHAAA, Oeioeioei dat was op het randje

    Test: fatal message...
    %MTST-F-AARGH, Nu is het helemaal mis
    $

Maybe that works for you as well.

user2116290
  • 1,062
  • 5
  • 6
  • I'm afraid you're right; I added the try/catch to see what was thrown, and that is indeed the expected code. That causes the Alpha version to fail as well. Removing the try/catch makes it work as expected now both on Alpha and IA64, so I need to trace back what I've been doing yesterday to reproduce it in my test script. I'll repost it here – Oscar Nov 05 '15 at 09:26
  • Ok, my original question is updates with a working script to reproduce this issue and the descriptions/results have been updated. At least, you explained why I wasn't able to reproduce the working Alpha version... totally overlooked it after a day digging in this issue... thanks for that! – Oscar Nov 05 '15 at 09:44
  • Maybe someone with access to an I64 system with C++ can give some insight. If not I would consider asking HP about this incompatibility. They should be able to explain the different behavior on the two platforms and/or the effect of the strict_ansi standard. I can think of a workaround/hack with VMS condition (exception) handlers, but it may not be worth the effort, when HP knows/has a workaround/fix for this "feature". PS: You probably use the same build commands on Alpha and I64, but you really need cxxlink only on Alpha. – user2116290 Nov 05 '15 at 18:19
  • Thanks for your update! Apart from the ECO patch, I also see a difference in the compiler version: V7.3-23 vs V7.4-004. I'll look further into that direction. PS: I do use the same compile/link cmds on both systems, so indeed using cxxlink. As for my original problem: for another projected some years ago I wrote a LIB$SIGNAL() for linux using VMS msg files: I use this now on VMS also ;) – Oscar Nov 07 '15 at 07:51