【问题标题】:LIB$SIGNAL issue with -F- atals on OpenVMSOpenVMS 上 -Fatals 的 LIB$SIGNAL 问题
【发布时间】:2015-11-04 13:01:35
【问题描述】:

我正在维护一个必须运行 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 源代码始终有效,并且在 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。当然,这改变了测试结果,正如他/她的评论中所说的 user2116290。 我将 DCL 脚本更改为原始测试,以重现我在原始应用中看到的内容。

【问题讨论】:

    标签: c++ openvms


    【解决方案1】:

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

    $ 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,所以我无法仔细检查 abort abort() 的结果将在 I64 上。它可能只是 %CXXL-F-TERMINATING。

    新更新:

    看起来严格 ansi 模式和标准 iostream 的组合触发了 C++ 捕获所有处理程序,该处理程序捕获致命的 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
        $
    

    也许这也适合你。

    【讨论】:

    • 恐怕你是对的;我添加了 try/catch 来查看抛出了什么,这确实是预期的代码。这也会导致 Alpha 版本失败。删除 try/catch 使其现在在 Alpha 和 IA64 上都按预期工作,所以我需要追溯我昨天一直在做的事情,以便在我的测试脚本中重现它。我会在这里重新发布它
    • 好的,我最初的问题是使用工作脚本更新以重现此问题,并且描述/结果已更新。至少,您解释了为什么我无法重现工作的 Alpha 版本……在研究了一天后完全忽略了它……谢谢!
    • 也许有人可以使用 C++ 访问 I64 系统,可以提供一些见解。如果不是,我会考虑向惠普询问这种不兼容性。他们应该能够解释两个平台上的不同行为和/或 strict_ansi 标准的影响。我可以考虑使用 VMS 条件(异常)处理程序的解决方法/破解,但是当 HP 知道/有此“功能”的解决方法/修复时,它可能不值得付出努力。 PS:你可能在 Alpha 和 I64 上使用相同的构建命令,但你真的只需要在 Alpha 上使用 cxxlink。
    • 感谢您的更新!除了 ECO 补丁,我还看到编译器版本的不同:​​V7.3-23 与 V7.4-004。我会进一步研究这个方向。 PS:我确实在两个系统上使用相同的编译/链接 cmds,所以确实使用 cxxlink。至于我最初的问题:对于几年前的另一个预测,我使用 VMS msg 文件为 linux 编写了一个 LIB$SIGNAL():我现在也在 VMS 上使用它;)
    猜你喜欢
    • 2023-03-19
    • 2011-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-19
    • 2016-09-28
    • 2011-05-05
    • 1970-01-01
    相关资源
    最近更新 更多