【问题标题】:Pro*C program run properly in AIX but not in RHELPro*C 程序在 AIX 中正常运行,但在 RHEL 中无法正常运行
【发布时间】:2021-03-14 13:10:12
【问题描述】:

我在运行使用 proC 代码完成的二进制文件时遇到了一些麻烦。我可以在我的新服务器 RHEL (7.8) 中编译它(没有警告),但它会循环直到失败。我制作了一个简单的 proC 脚本来测试编译(见下文)。该脚本可以在我以前的服务器 AIX (6.1.0.0) 中轻松运行。数据库是 Oracle 11c。

  • AIX 中的 Oracle 客户端:.../oracle/10.2
  • RHEL 中的 Oracle 客户端:.../oracle/12102/cli64

这是我要编译和执行的简单代码:

#include "demo.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlca.h>
#include <oraca.h>

int code_erreur;
char libelle_erreur[200];

EXEC ORACLE OPTION (ORACA=YES);

EXEC SQL BEGIN DECLARE SECTION;
    VARCHAR username[30];
    VARCHAR password[30];
    VARCHAR host[30];

    VARCHAR dynstmt[80];
    VARCHAR mData[81];

EXEC SQL END DECLARE SECTION;

int connect()
{
    printf("\nConnection to %s@%s\n",username.arr,host.arr);

    EXEC SQL CONNECT :username IDENTIFIED BY :password USING :host;

    printf("Connection established\n");
    return 0;
}

void sqlerr()
{
    code_erreur = sqlca.sqlcode;
    strcpy(libelle_erreur,sqlca.sqlerrm.sqlerrmc);
    printf("SQL ERROR : %d,%s ;\n", code_erreur,libelle_erreur);
    printf("sqlca.sqlerrd : %d\n",sqlca.sqlerrd[2]);
}

int loadData()
{
    int lIter;

    strcpy(dynstmt.arr, "SELECT BANNER FROM V$VERSION\n");
    dynstmt.len = strlen(dynstmt.arr);

    printf("%s", (char *)dynstmt.arr);

    EXEC SQL PREPARE S FROM :dynstmt;
    EXEC SQL DECLARE lCursorData CURSOR FOR S;
    EXEC SQL OPEN lCursorData;

    for (lIter=0;lIter<10;lIter++)
    {
        EXEC SQL WHENEVER NOT FOUND DO break;
        EXEC SQL FETCH lCursorData INTO :mData;
        printf("%s\n", mData.arr);
    }
    EXECL SQL CLOSE lCursorData;
    return 0;
}

void main()
{
    int lRetour=0;
    printf("Start demo\n");

    strcpy((char *)username.arr,"USER");
    username.len=(unsigned short)strlen((char *)username.arr);

    strcpy((char *)password.arr,"PASS");
    password.len=(unsigned short)strlen((char *)password.arr);

    strcpy((char *)host.arr,"HOST");
    host.len=(unsigned short)strlen((char *)host.arr);

    EXEC SQL WHENEVER SQLERROR do sqlerr();
    lRetour = connect();
    lRetour = loadData();

    EXEC SQL COMMIT WORK RELEASE;

    printf("End demo\n");
    exit(0);
}

当我在我的 AIX 服务器上编译并执行它时,我得到了:

Start demo

Connection to USER@HOST
Connection established
SELECT BANNER FROM V$VERSION
[...]
End demo

但是当我在 RHEL 上编译并执行它时,二进制循环直到出现内存错误:

[...]
Connection to USER@HOST

Connection to USER@HOST

Connection to USER@HOST
Memory fault

当然,我希望在 RHEL 中获得相同的 AIX 结果。

【问题讨论】:

  • 听起来像是堆栈覆盖(或堆栈溢出)的情况​​。实际值HOST是多长时间?
  • 8 个字符长

标签: compilation rhel oracle-pro-c


【解决方案1】:

您的connect 函数应定义为static,否则它将替换libc 中的connect(2) 库函数。

@@ -20,7 +20,7 @@

 EXEC SQL END DECLARE SECTION;

-int connect()
+static int connect()
 {
     printf("\nConnection to %s@%s\n",username.arr,host.arr);

@@ -57,7 +57,7 @@

【讨论】:

  • 它就像一个魅力。您知道为什么它在我的 AIX 服务器上有效吗?也许是由于不推荐使用的对象?
  • 在 AIX 上解析外部符号是不同的。试试这个:dump -X32_64 -Tv .../libclntsh.so | grep -w connect 它说EXTref /usr/lib/libc.a(shr_64.o) connect,这意味着它将使用来自共享对象/usr/lib/libc.a(shr_64.o)connect 函数,而不是来自任何其他地方。在 Linux 上,glibc-loader 将使用第一个可用的 connect 从它找到的任何地方。
猜你喜欢
  • 2021-12-15
  • 2020-09-16
  • 2016-03-29
  • 1970-01-01
  • 2019-02-22
  • 2022-08-12
  • 1970-01-01
  • 2017-02-08
  • 1970-01-01
相关资源
最近更新 更多