【问题标题】:Memory fault error in LINUX but not in UNIXLINUX 中的内存错误错误,但 UNIX 中没有
【发布时间】:2011-10-12 02:13:03
【问题描述】:

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

#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();
        }

【问题讨论】:

  • Oracle 参与其中。 任何事情都可能出错。 运行

标签: linux memory fault


【解决方案1】:
char para_name[25];
strcpy(para_name, "Para = no_geo_cursor_process");
//                          1         2
//                 12345678901234567890123456789 (one extra for the NULL).

这是一个可能行不通的事情。如果你写超出数组的末尾,这是未定义的行为(你不能把二十九块饼干放入为二十五块构建的饼干罐中(a)

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

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


此外,正如 cmets 中所指出的,您在几行中提供了没有对应值的 printf 格式字符串:

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

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


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

【讨论】:

  • 感谢 paxdiablo 的回复.. 只是一个额外的问题,我的一个队友更新了以下行: printf("No Rows for update_no: %s\n"); 更改为:printf(" update_no 没有行:\n");并且内存故障消失了。这是否只是一个误导性问题,而 para_name 定义确实是问题
  • @EB:这些也是也是错误,它们同样可能导致崩溃,就像 paxdiablo 显示的错误一样(有很多地方你有@987654327 @ 在您的printf() 格式中,但没有相应的参数,例如printf("SQL Select Error in - get_update_timestamp: %s\n"); - 您需要全部修复)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-23
  • 1970-01-01
  • 2011-11-10
  • 2015-07-20
相关资源
最近更新 更多