在OpenVMS上使用-F- atals的LIB $ SIGNAL问题

时间:2015-11-04 13:01:35

标签: c++ openvms

我维护的应用程序必须运行Alpha OpenVMS(7.3-2)和Itanium OpenVMS(8.4)。 它是用C ++编写的,编译器版本在Alpha上为6.5-046,在IA64上为7.4-004。

我遇到的问题是LIB $ SIGNAL()。一旦它发出致命信息,程序就会中止。

首先重现此代码(作为生成和构建代码的DCL脚本):

$ 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
$!

C-source始终有效,而Alpha上的两个脚本都有效。

在没有/ STANDARD的情况下进行编译时,它在Itanium上运行良好,但在原始程序中我使用iostream时遇到问题:我需要ANSI,但是使用/ DEFINE =(__ USE_STD_IOSTREAM)进行编译会带回原始问题。

$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
$

我的期望是:

$ 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
$

所以...%CPP - ? - WTF,求助: - /

提前致谢, 奥斯卡

注意:在我昨天发表的原始帖子中,有一个不同的脚本,其中包含一些像try / catch这样的测试代码。当然,这改变了用户2116290在他/她的评论中所述的测试结果。 我将DCL脚本更改为原始测试,以重现我在原始应用程序中看到的内容。

1 个答案:

答案 0 :(得分:3)

到目前为止,我还没有看到问题。

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

在Alpha上(我使用HP C ++ V7.1-015 for OpenVMS Alpha V8.3进行了尝试),您正在捕获您的错误代码。然后你调用abort(),它发出信号0x434,OPCCUS,看起来对我好。

在Alpha上,如果我删除了try / catch,那么c ++程序就像c程序一样。我无法访问带有c ++的I64,因此我无法仔细检查I64中止中止()的结果。它可能只是%CXXL-F-TERMINATING。

新更新:

看起来严格的ansi模式和标准的iostreams的组合触发了C ++ catch all处理程序,它捕获了致命的VMS条件/异常。在您的示例中,似乎可以通过以下方式禁用捕获VMS条件:

$ 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);

编译,链接和运行更改的示例:

    $ 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
    $

也许这也适合你。