Skip to main content

We have the Micro Focus Visual COBOL(v6.0.0.138) application setup on Linux (RHEL 8) and the database is MS-SQL.

The Cobol application communicates to an External application using a 'C' socket program. A Cobol module calls the ‘C’ socket program passing the required information (Server name, Port number) using a pointer. At the point of calling the ‘C’ program, the application fails with the message as below,

Execution error : file 'system/bin/CallSocket.gnt'

error code: 114, pc=0, call=1, seg=0

114     Attempt to access item beyond bounds of memory (Signal 11)

Please find below the program logic which invokes the C program, 

           MOVE 1                              TO WS-UNSTR-PTR.
           MOVE ZERO                           TO WS-UNSTR-CTR.
           MOVE ZERO                           TO WS-UNSTR-FLD-CTR
           MOVE SPACES                         TO WSOK-HST-NM.

           UNSTRING          WS-SRV-NM
               DELIMITED BY  SPACES
               INTO          WSOK-HST-NM
               COUNT IN      WS-UNSTR-CTR
               WITH POINTER  WS-UNSTR-PTR
               TALLYING IN   WS-UNSTR-FLD-CTR
               ON OVERFLOW   CONTINUE
           END-UNSTRING.

           MOVE WS-UNSTR-CTR         TO WSOK-HST-NM-LEN
		   
           MOVE WSOK-HST-NM-LEN          TO LCPRG-LOOKUP-NM-LEN.
		   
           CALL WSOK-ADDR-SET-PGM   USING WSOK-HST-NM     
                                          LCPRG-LOOKUP-NM-ADDR-PTR.		   

      *Start of WSOK-ADDR-SET-PGM										  									      
           SET ADDR-ADDRESS-POINTER TO ADDRESS OF ADDR-DATA-ITEM.		   
      *End of WSOK-ADDR-SET-PGM	

           MOVE LENGTH OF LCPRG-COMMAREA-INFO TO LCPRG-COMMAREA-LEN.

           CALL 'CPRG' USING BY REFERENCE
                                LCPRG-COMMAREA-INFO.
									  						

Please find the error reported in the MFTrace log,

05:27:39.812 MF.RTS 50 0 3 0 "CallSocket"
05:27:39.814 MF.RTS 23 1 0 0 "Cprg.so" 00007F796C5D1230
05:27:39.814 MF.RTS 255 3 114 3 "<NULL>"
05:27:39.836 MF.RTS 140 1 2 "
Execution error : file '/system/bin/CallSocket.gnt'
error code: 114, pc=0, call=1, seg=0
114     Attempt to access item beyond bounds of memory (Signal 11)"

Kindly provide your suggestions to resolve this issue.


#Linux
#c
#SQL
#C
#COBOL
#VisualCOBOL
#MicroFocusVisualCobol

We have the Micro Focus Visual COBOL(v6.0.0.138) application setup on Linux (RHEL 8) and the database is MS-SQL.

The Cobol application communicates to an External application using a 'C' socket program. A Cobol module calls the ‘C’ socket program passing the required information (Server name, Port number) using a pointer. At the point of calling the ‘C’ program, the application fails with the message as below,

Execution error : file 'system/bin/CallSocket.gnt'

error code: 114, pc=0, call=1, seg=0

114     Attempt to access item beyond bounds of memory (Signal 11)

Please find below the program logic which invokes the C program, 

           MOVE 1                              TO WS-UNSTR-PTR.
           MOVE ZERO                           TO WS-UNSTR-CTR.
           MOVE ZERO                           TO WS-UNSTR-FLD-CTR
           MOVE SPACES                         TO WSOK-HST-NM.

           UNSTRING          WS-SRV-NM
               DELIMITED BY  SPACES
               INTO          WSOK-HST-NM
               COUNT IN      WS-UNSTR-CTR
               WITH POINTER  WS-UNSTR-PTR
               TALLYING IN   WS-UNSTR-FLD-CTR
               ON OVERFLOW   CONTINUE
           END-UNSTRING.

           MOVE WS-UNSTR-CTR         TO WSOK-HST-NM-LEN
		   
           MOVE WSOK-HST-NM-LEN          TO LCPRG-LOOKUP-NM-LEN.
		   
           CALL WSOK-ADDR-SET-PGM   USING WSOK-HST-NM     
                                          LCPRG-LOOKUP-NM-ADDR-PTR.		   

      *Start of WSOK-ADDR-SET-PGM										  									      
           SET ADDR-ADDRESS-POINTER TO ADDRESS OF ADDR-DATA-ITEM.		   
      *End of WSOK-ADDR-SET-PGM	

           MOVE LENGTH OF LCPRG-COMMAREA-INFO TO LCPRG-COMMAREA-LEN.

           CALL 'CPRG' USING BY REFERENCE
                                LCPRG-COMMAREA-INFO.
									  						

Please find the error reported in the MFTrace log,

05:27:39.812 MF.RTS 50 0 3 0 "CallSocket"
05:27:39.814 MF.RTS 23 1 0 0 "Cprg.so" 00007F796C5D1230
05:27:39.814 MF.RTS 255 3 114 3 "<NULL>"
05:27:39.836 MF.RTS 140 1 2 "
Execution error : file '/system/bin/CallSocket.gnt'
error code: 114, pc=0, call=1, seg=0
114     Attempt to access item beyond bounds of memory (Signal 11)"

Kindly provide your suggestions to resolve this issue.


#Linux
#c
#SQL
#C
#COBOL
#VisualCOBOL
#MicroFocusVisualCobol

A likely cause of such a problem is that the LCPRG-COMMAREA-INFO data item does not match what the C program CPRG is expecting. Is the server name null terminated in your COBOL code or does it pass an explicit length to the C code ? Is the port number defined as an int in the C code and if so, is it defined as COMP-5 in your COBOL code ? 

It might be helpful if you could attach the defintion of  LCPRG-COMMAREA-INFO and the corresponding C structure.


A likely cause of such a problem is that the LCPRG-COMMAREA-INFO data item does not match what the C program CPRG is expecting. Is the server name null terminated in your COBOL code or does it pass an explicit length to the C code ? Is the port number defined as an int in the C code and if so, is it defined as COMP-5 in your COBOL code ? 

It might be helpful if you could attach the defintion of  LCPRG-COMMAREA-INFO and the corresponding C structure.

HI Gael,

The server name passed from COBOL code is not null terminated but the length of the server name is being passed to the C code. Initially, the system is passing only the Server IP address to the C code to look up the IP and hence the Port number is passed at later stage only. 

Please find below the LCPRG-COMMAREA-INFO and C structure for the Lookup of the IP address,

01 LCPRG-COMMAREA-INFO.
05 LCPRG-RQST-CD PIC S9(08) COMP-5.
88 LCPRG-RQST-LOOKUP VALUE +01.

05 LCPRG-RETRN-CD PIC S9(08) COMP-5.
88 LCPRG-RETRN-OK VALUE ZERO, +10.
88 LCPRG-RETRN-INVALID-REQUEST VALUE +99.
05 LCPRG-ERR-ERROR-NUM PIC S9(18) COMP-5.
05 LCPRG-RQST-AREA PIC X(48).

05 LCPRG-LOOKUP-INFO REDEFINES
LCPRG-RQST-AREA.
10 LCPRG-LOOKUP-NM-LEN PIC 9(18) COMP-5.
10 LCPRG-LOOKUP-NM-ADDR-PTR USAGE IS POINTER.
10 LCPRG-LOOKUP-IP-ADDR-ID PIC 9(18) COMP-5.
10 FILLER PIC X(24).

C Program

lookupIP(commarea);
			   

void lookupIP(COMMAREA* commarea)
{
	struct hostent *lpHostEntry;
	char szServerName[MAXHOSTNAME];
	BYTE* serverName = commarea->common.lookup.hostname;
	LENGTH nameLength = commarea->common.lookup.strLength;
	IP_ADDRESS* address = &(commarea->common.lookup.ip_address);

	if (commarea->common.lookup.hostname == 0 ||
		commarea->common.lookup.strLength == 0)
	{
		commarea->status = CallSocket_RETRN_INVALD_RQST;
		logCommarea("lookupIP failed: invalid hostname or length", commarea);
		return;
	}

	logCommarea("lookupIP started", commarea);

	/* Find the server */

    if (nameLength > MAXHOSTNAME-1)
    {
        commarea->status = CallSocket_RETRN_ERR_GETHOST;
		logCommarea("lookupIP failed: nameLength too long", commarea);
        return;
    }

	strncpy_s(szServerName, MAXHOSTNAME, serverName, nameLength);
	szServerName[nameLength]='\\0';

	lpHostEntry = gethostbyname(szServerName);

    if (lpHostEntry == NULL)
    {
        commarea->status = CallSocket_RETRN_ERR_GETHOST;
		logCommarea("lookupIP failed: error getting host by name", commarea);
        return;
    }

	/* TODO: fix address type assumption. */

	memcpy((BYTE*)address, lpHostEntry->h_addr_list[0],
		lpHostEntry->h_length);

	logCommarea("lookupIP ended", commarea);

	return;
}

Appreciate your response!! Thanks


HI Gael,

The server name passed from COBOL code is not null terminated but the length of the server name is being passed to the C code. Initially, the system is passing only the Server IP address to the C code to look up the IP and hence the Port number is passed at later stage only. 

Please find below the LCPRG-COMMAREA-INFO and C structure for the Lookup of the IP address,

01 LCPRG-COMMAREA-INFO.
05 LCPRG-RQST-CD PIC S9(08) COMP-5.
88 LCPRG-RQST-LOOKUP VALUE +01.

05 LCPRG-RETRN-CD PIC S9(08) COMP-5.
88 LCPRG-RETRN-OK VALUE ZERO, +10.
88 LCPRG-RETRN-INVALID-REQUEST VALUE +99.
05 LCPRG-ERR-ERROR-NUM PIC S9(18) COMP-5.
05 LCPRG-RQST-AREA PIC X(48).

05 LCPRG-LOOKUP-INFO REDEFINES
LCPRG-RQST-AREA.
10 LCPRG-LOOKUP-NM-LEN PIC 9(18) COMP-5.
10 LCPRG-LOOKUP-NM-ADDR-PTR USAGE IS POINTER.
10 LCPRG-LOOKUP-IP-ADDR-ID PIC 9(18) COMP-5.
10 FILLER PIC X(24).

C Program

lookupIP(commarea);
			   

void lookupIP(COMMAREA* commarea)
{
	struct hostent *lpHostEntry;
	char szServerName[MAXHOSTNAME];
	BYTE* serverName = commarea->common.lookup.hostname;
	LENGTH nameLength = commarea->common.lookup.strLength;
	IP_ADDRESS* address = &(commarea->common.lookup.ip_address);

	if (commarea->common.lookup.hostname == 0 ||
		commarea->common.lookup.strLength == 0)
	{
		commarea->status = CallSocket_RETRN_INVALD_RQST;
		logCommarea("lookupIP failed: invalid hostname or length", commarea);
		return;
	}

	logCommarea("lookupIP started", commarea);

	/* Find the server */

    if (nameLength > MAXHOSTNAME-1)
    {
        commarea->status = CallSocket_RETRN_ERR_GETHOST;
		logCommarea("lookupIP failed: nameLength too long", commarea);
        return;
    }

	strncpy_s(szServerName, MAXHOSTNAME, serverName, nameLength);
	szServerName[nameLength]='\\0';

	lpHostEntry = gethostbyname(szServerName);

    if (lpHostEntry == NULL)
    {
        commarea->status = CallSocket_RETRN_ERR_GETHOST;
		logCommarea("lookupIP failed: error getting host by name", commarea);
        return;
    }

	/* TODO: fix address type assumption. */

	memcpy((BYTE*)address, lpHostEntry->h_addr_list[0],
		lpHostEntry->h_length);

	logCommarea("lookupIP ended", commarea);

	return;
}

Appreciate your response!! Thanks

Hi,

It was the definition of COMMAREA I was asking about when I mentioned the corresponding C structure. Based on definition in the COBOL program does it look something like this (obviously the names don't match your C code, it's the overall structure and types that are relevant) ? 

typedef struct
{
    int request_code; /* 4 byte */
    int return_code; /* 4 byte */
    long long error_num; /* 8 byte */
    union
    {
        char request_area[48];
        struct
        {
            long long name_len; /* 8 byte */
            char *name_ptr;     /* 8 byte for 64-bit or 4 byte for 32-bit*/
            long long ip_addr_id; /* 8 byte */
            char filller2[24];
        };
    };
} COMMAREA;

Are you compiling to 64-bit code ? If you aren't there will be an alignment issue as the C compiler will include padding after the pointer so a four byte filler would be needed in the COBOL structure.

In your C code the method is called lookupIP but your COBOL code is calling CPRG so is it definitely calling the correct code ? I'm not especially familiar with how symbols are resolved when calling callable shared objects on Linux from .gnt code (I'm a Windows person, sorry !) so hopefully an expert can add some extra info to help you.

Have you tried debugging the C code ?