LINUX 中出现内存故障错误,但 UNIX 中没有

发布于 2024-12-09 12:08:18 字数 5134 浏览 0 评论 0原文

我们正在运行一个 ksh 脚本,该脚本调用更新表的 ProC 程序。 该程序在 UNIX 中运行成功,但是当我们在 LINUX RHEL55 中运行它时,它会导致内存故障错误 当我们尝试调试内存故障错误之前的最后一条语句时,它指向我们对游标执行 Fetch 后的点,并尝试使用获取的值来更新表 这是代码片段

#define PROGRAM  "n377wlocgeo"    /* name of this program */

#define USERNAME "/"               /* ORACLE username */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>


   /* Include the ORACLE communication Area, a structure through which
   ORACLE makes additional runtime Status available to the program
   The ORACA=YES must be specified to enable use of oraca */

   EXEC SQL INCLUDE ORACA;
   EXEC ORACLE OPTION (ORACA=YES);

   EXEC SQL INCLUDE SQLCA;


/*---------------------------------------------------------------------------
 WORKING STORAGE */

/* GLOBAL EXTERNAL VARIABLES */


char *ptr;                 /* pointer for record layout */
char timestamp[26] = "\0"; /* current date and time */


/* Counters */
int   rec_err_ctr = 0;
int   cnt_rec = 0;

long  update_no_ctr = 0;
long  update_geo_ctr = 0;

long  update_no_pr_ctr = 0;
long  update_no_us_ctr = 0;

int   no_fetch_rec_ctr = 0;
int   geo_fetch_rec_ctr = 0;

int   commit_ctr = 0;


int  ws_err_sqlcode;
char para_name[25];         /* hold for displaying what paragraph abended */
char err_para_name[25];     /* hold for displaying what paragraph abended */
char abend_msg[240];


/*Pgm Control Vars */

char  error_in_job = 'N';
char  no_fetch_ended = 'N';
char  geo_fetch_ended = 'N';
char  clear_psl_cd[12];



 /* UNIX ENVIRONMENT VARIABLES  */
char debug[2];

 /* Function delarations */
 void initpara();        /* connect to Oracle  */
 void get_env_vars();    /* get the unix environment variables into C program */
 void get_timestamp();   /* get the date and time from the system */

 void connect_oracle();
 void disconnect_oracle();

 void get_update_timestamp();

 void end_transaction();
 void error_routine();
 void echofields();           /* for debugging, echo all fields parsed */

 void no_geo_cursor_process();
 void geo_cursor_process();
 void sql_no_update();
 void sql_geo_update();
 void sql_no_pr_update();
 void sql_no_us_update();



EXEC SQL BEGIN DECLARE SECTION;


 varchar      hv_psl_cd[12];
 varchar      hv_rec_udt_ts[20];
 varchar      hv_geo_cny_cd[03];
 varchar      hv_geo_psl_cd[12];
 varchar      hv_geo_typ_cd[4];
 varchar      hv_cny_cd[03];


/* Cursor to set defaults for countries with no geo classification */
 EXEC SQL DECLARE NO_GEO_CUR CURSOR FOR
      SELECT   CNY_CD
              ,PSL_CD
      FROM TDLOCTN_BASE
      WHERE CNY_CD NOT IN ('US', 'PR')
          AND GEO_ARA_PSL_CSF_CD is null
      GROUP BY CNY_CD, PSL_CD
      ORDER BY CNY_CD, PSL_CD;


  EXEC SQL DECLARE GEO_CUR CURSOR FOR
      SELECT GEO_CNY_CD,
             GEO_PSL_CD,
             GEO_TYP_CD
      FROM TDLOC_GEO_CD_EXT
      GROUP BY GEO_CNY_CD,GEO_PSL_CD,GEO_TYP_CD
      ORDER BY GEO_CNY_CD,GEO_PSL_CD;


EXEC SQL END DECLARE SECTION;

/*----------------------------------------------------------
 PROCEDURE DIVISION
------------------------------------------------------------
   MAINLINE */

/*------------------------------------------------------------*/
 int main(int argc, char **argv)

   {


      printf ("Starting");

      get_timestamp();

      printf("PGM BEGIN DATE/TIME : %s \n", timestamp );

     initpara();

     if ( strcmp(debug, "Y") == 0 )
           get_timestamp();
           printf("main while loop: %s\n", timestamp);

      /* get max rec_udt_tms for cursor process */
      get_update_timestamp();

      /* open the cursor and fetch all rows for defaults  . */

      no_geo_cursor_process();

     if ( error_in_job == 'Y' )
          exit(2);
      else
          exit(0);
   }


/*------------------------------------------------------------*/
  void get_timestamp()

  {
    strcpy(para_name, "Para = get_timestamp");
    if ( strcmp(debug, "Y") == 0 )
           printf("function: get_timestamp\n");

    struct tm *tm_now;
    time_t secs_now;

/no_geo_cursor

    EXEC SQL
        SELECT TRUNC(MAX(REC_UDT_TS))
               INTO :hv_rec_udt_ts
         FROM TDLOCTN_BASE;



    if ( sqlca.sqlcode == 0 )
        printf("CHAR  %-25s : %s \n", "hv_rec_udt_ts", hv_rec_udt_ts.arr);
    else
       {
         printf("SQL Select Error in - get_update_timestamp: %s\n");
         strcpy(abend_msg, sqlca.sqlerrm.sqlerrmc);
         printf("SQL ERROR CODE: %d\n", sqlca.sqlcode);
         printf("SQL ERROR MSG: %s\n", abend_msg);
         error_routine();
        }
  }

 void no_geo_cursor_process ()

   {
     strcpy(para_name, "Para = no_geo_cursor_process");
     if ( strcmp(debug, "Y") == 0 )
          printf("function: no_geo_cursor_process\n");

     EXEC SQL
        OPEN NO_GEO_CUR;

     if ( sqlca.sqlcode == 0 )
        printf("Cursor Opened: %s\n");
     else
        {
         printf("SQL Open Error in - no_geo_cursor_process: %s\n");
         strcpy(abend_msg, sqlca.sqlerrm.sqlerrmc);
         printf("SQL ERROR CODE: %d\n", sqlca.sqlcode);
         printf("SQL ERROR MSG: %s\n", abend_msg);
         error_routine();
        }

We are running a ksh script that calls a ProC program that updates a table.
The program runs successfully in UNIX but when we run it in LINUX RHEL55 , it is causing a memory fault error
When we tried to debug where the last statement before the Memory fault error, it points to the point after we do a Fetch on the cursor and tries to use the values fetched to update a table
Here is a snippet of the code

#define PROGRAM  "n377wlocgeo"    /* name of this program */

#define USERNAME "/"               /* ORACLE username */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>


   /* Include the ORACLE communication Area, a structure through which
   ORACLE makes additional runtime Status available to the program
   The ORACA=YES must be specified to enable use of oraca */

   EXEC SQL INCLUDE ORACA;
   EXEC ORACLE OPTION (ORACA=YES);

   EXEC SQL INCLUDE SQLCA;


/*---------------------------------------------------------------------------
 WORKING STORAGE */

/* GLOBAL EXTERNAL VARIABLES */


char *ptr;                 /* pointer for record layout */
char timestamp[26] = "\0"; /* current date and time */


/* Counters */
int   rec_err_ctr = 0;
int   cnt_rec = 0;

long  update_no_ctr = 0;
long  update_geo_ctr = 0;

long  update_no_pr_ctr = 0;
long  update_no_us_ctr = 0;

int   no_fetch_rec_ctr = 0;
int   geo_fetch_rec_ctr = 0;

int   commit_ctr = 0;


int  ws_err_sqlcode;
char para_name[25];         /* hold for displaying what paragraph abended */
char err_para_name[25];     /* hold for displaying what paragraph abended */
char abend_msg[240];


/*Pgm Control Vars */

char  error_in_job = 'N';
char  no_fetch_ended = 'N';
char  geo_fetch_ended = 'N';
char  clear_psl_cd[12];



 /* UNIX ENVIRONMENT VARIABLES  */
char debug[2];

 /* Function delarations */
 void initpara();        /* connect to Oracle  */
 void get_env_vars();    /* get the unix environment variables into C program */
 void get_timestamp();   /* get the date and time from the system */

 void connect_oracle();
 void disconnect_oracle();

 void get_update_timestamp();

 void end_transaction();
 void error_routine();
 void echofields();           /* for debugging, echo all fields parsed */

 void no_geo_cursor_process();
 void geo_cursor_process();
 void sql_no_update();
 void sql_geo_update();
 void sql_no_pr_update();
 void sql_no_us_update();



EXEC SQL BEGIN DECLARE SECTION;


 varchar      hv_psl_cd[12];
 varchar      hv_rec_udt_ts[20];
 varchar      hv_geo_cny_cd[03];
 varchar      hv_geo_psl_cd[12];
 varchar      hv_geo_typ_cd[4];
 varchar      hv_cny_cd[03];


/* Cursor to set defaults for countries with no geo classification */
 EXEC SQL DECLARE NO_GEO_CUR CURSOR FOR
      SELECT   CNY_CD
              ,PSL_CD
      FROM TDLOCTN_BASE
      WHERE CNY_CD NOT IN ('US', 'PR')
          AND GEO_ARA_PSL_CSF_CD is null
      GROUP BY CNY_CD, PSL_CD
      ORDER BY CNY_CD, PSL_CD;


  EXEC SQL DECLARE GEO_CUR CURSOR FOR
      SELECT GEO_CNY_CD,
             GEO_PSL_CD,
             GEO_TYP_CD
      FROM TDLOC_GEO_CD_EXT
      GROUP BY GEO_CNY_CD,GEO_PSL_CD,GEO_TYP_CD
      ORDER BY GEO_CNY_CD,GEO_PSL_CD;


EXEC SQL END DECLARE SECTION;

/*----------------------------------------------------------
 PROCEDURE DIVISION
------------------------------------------------------------
   MAINLINE */

/*------------------------------------------------------------*/
 int main(int argc, char **argv)

   {


      printf ("Starting");

      get_timestamp();

      printf("PGM BEGIN DATE/TIME : %s \n", timestamp );

     initpara();

     if ( strcmp(debug, "Y") == 0 )
           get_timestamp();
           printf("main while loop: %s\n", timestamp);

      /* get max rec_udt_tms for cursor process */
      get_update_timestamp();

      /* open the cursor and fetch all rows for defaults  . */

      no_geo_cursor_process();

     if ( error_in_job == 'Y' )
          exit(2);
      else
          exit(0);
   }


/*------------------------------------------------------------*/
  void get_timestamp()

  {
    strcpy(para_name, "Para = get_timestamp");
    if ( strcmp(debug, "Y") == 0 )
           printf("function: get_timestamp\n");

    struct tm *tm_now;
    time_t secs_now;

/no_geo_cursor

    EXEC SQL
        SELECT TRUNC(MAX(REC_UDT_TS))
               INTO :hv_rec_udt_ts
         FROM TDLOCTN_BASE;



    if ( sqlca.sqlcode == 0 )
        printf("CHAR  %-25s : %s \n", "hv_rec_udt_ts", hv_rec_udt_ts.arr);
    else
       {
         printf("SQL Select Error in - get_update_timestamp: %s\n");
         strcpy(abend_msg, sqlca.sqlerrm.sqlerrmc);
         printf("SQL ERROR CODE: %d\n", sqlca.sqlcode);
         printf("SQL ERROR MSG: %s\n", abend_msg);
         error_routine();
        }
  }

 void no_geo_cursor_process ()

   {
     strcpy(para_name, "Para = no_geo_cursor_process");
     if ( strcmp(debug, "Y") == 0 )
          printf("function: no_geo_cursor_process\n");

     EXEC SQL
        OPEN NO_GEO_CUR;

     if ( sqlca.sqlcode == 0 )
        printf("Cursor Opened: %s\n");
     else
        {
         printf("SQL Open Error in - no_geo_cursor_process: %s\n");
         strcpy(abend_msg, sqlca.sqlerrm.sqlerrmc);
         printf("SQL ERROR CODE: %d\n", sqlca.sqlcode);
         printf("SQL ERROR MSG: %s\n", abend_msg);
         error_routine();
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谁的年少不轻狂 2024-12-16 12:08:18
char para_name[25];
strcpy(para_name, "Para = no_geo_cursor_process");
//                          1         2
//                 12345678901234567890123456789 (one extra for the NULL).

这可能是行不通的。如果您写入超过数组末尾,则这是未定义的行为(您不能将二十九块饼干放入为二十五块饼干制作的饼干罐中(a)

增加 para_name 的大小code> 来解决这个问题。

可能在某些系统上工作的原因是,未定义行为的可能结果之一就是它只是工作。当然,这并不是一个好主意。你应该尽可能避免它。


此外,正如评论中指出的,您有几行提供了 printf 格式字符串,但没有相应的值:

printf("SQL Select Error in - get_update_timestamp: %s\n");
printf("Cursor Opened: %s\n");

这也是未定义的行为,并且可能会导致问题,通常是通过使用发生的任何值作为字符串指针放置在堆栈上。您可以从字符串中删除有问题的 %s,或者找出您想要在消息中包含的字符串并将其添加到 printf 参数中。


(a) 当然,除非你想要饼干碎:-)

char para_name[25];
strcpy(para_name, "Para = no_geo_cursor_process");
//                          1         2
//                 12345678901234567890123456789 (one extra for the NULL).

That's one thing that's probably not going to work. It's undefined behaviour if you write past the end of an array (you cant put twenty-nine biscuits into a biscuit tin built for twenty-five (a))

Increase the size of para_name to fix that problem.

The reason it may work on some systems is that one of the possible outcomes of undefined behaviour is that it just works. That doesn't make it a good idea, of course. You should avoid it as much as possible.


In addition, as pointed out in the comments, you have a few lines where you provide printf format strings with no corresponding values:

printf("SQL Select Error in - get_update_timestamp: %s\n");
printf("Cursor Opened: %s\n");

This is also undefined behaviour and will likely cause problems, usually by using whatever values happens to have been placed on the stack as a string pointer. You can just remove the offending %s from the string or, alternatively, figure out what string you wanted to include in the message and add that to the printf arguments.


(a) Unless you want biscuit crumble, of course :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文