0

I would like to call Cobol program through java jni C code. After calling my java code I got a following error: A fatal error has been detected by the Java Runtime Environment: SIGSEGV (0xb) at pc=fffffffff2667174, pid=1174405432, tid=4

This is my Cobol program(XCOBFUNC.cob) which I compiled on Tandem:ecobol -c -Wshared XCOBFUNC.cob

    ?ENV COMMON;INNERLIST
    ?INSPECT, SYMBOLS

    IDENTIFICATION DIVISION.
    PROGRAM-ID.    XCOBFUNC.
    AUTHOR. TEST.

    ENVIRONMENT DIVISION.
    CONFIGURATION SECTION.
        SOURCE-COMPUTER.        TANDEM-K2006.
        OBJECT-COMPUTER.        TANDEM-K2006.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01 D-RESULT        PIC S9(09) COMP.

    LINKAGE SECTION.
    77 D-STRING        PIC X(20).
    77 D-SHORT         PIC 9(04) COMP.
    77 D-LARGE         PIC 9(08) COMP.

    PROCEDURE DIVISION USING D-STRING, D-SHORT, D-LARGE.
    000-INIT.
        DISPLAY "I AM DOING COBOL NOW".
        COMPUTE D-RESULT = D-LARGE / D-SHORT.
        DISPLAY "D-STRING = " D-STRING.
        DISPLAY "D-LARGE = " D-LARGE.
        DISPLAY "D-SHORT = " D-SHORT.
        DISPLAY "D-RESULT = " D-RESULT.
        DISPLAY "LEAVING COBOL PROGRAM NOW".
        EXIT-PROGRAM.

This is my C source file(HelloJNI.c):

#include <jni.h>
#include <stdio.h>
#include "HelloJNI.h"
#include "cobincl.h"

// Implementation of native method sayHello() of HelloJNI class
JNIEXPORT jshort JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj, jint par1, jstring jName) {

   char outCStr[128] = "From C Program";
   jshort error = 0;
   short ds;
   long dl;
   char *tx = "Displayed in COBOL";

   const char *name = (*env)->GetStringUTFChars(env, jName, 0);
   int i;
   jint result = par1 + 5;


   printf("Hello World!\n");
   printf("par1 = %d \n", par1);
   printf("par1 = %s \n", name);

   (*env)->ReleaseStringUTFChars(env, jName, name);

   ds = 100;
   dl = 40000;

   XCOBFUNC(tx, &ds, &dl);   

   printf("ds = %d\n", ds);

   printf("I am back in C now and program is ending.\n");   

   return error;
}

This is my C header file(HelloJNI.h):

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */

#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloJNI
 * Method:    sayHello
 * Signature: (ILjava/lang/String;)S
 */
JNIEXPORT jshort JNICALL Java_HelloJNI_sayHello
  (JNIEnv *, jobject, jint, jstring);

#ifdef __cplusplus
}
#endif
#endif

This is my cobincl.h:

void XCOBFUNC (char *, short *, long *);
#pragma FUNCTION XCOBFUNC (cobol)

This is my Makefile:

CC=/usr/bin/c89
ELD=/usr/bin/eld

RM=rm -f

CFLAGS= -g -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/oss -I /G/system/system -I./include -Wallow_cplusplus_comments \
        -Wextensions -D_XOPEN_SOURCE_EXTENDED=1 -Wnowarn=141,209,1506,262 \
        -Wcall_shared -Wsystype=oss -Wtarget=tns/e -Wmap -Wverbose

#LDFLAGS = -set floattype IEEE_float -set SYSTYPE OSS -set HIGHPIN ON \
#          -set CPlusPlusDialect neutral -dll -m -verbose \
#          -l zcobdll -lcre -lcrtl -export_all

LDFLAGS = -set floattype IEEE_float -set SYSTYPE OSS -set HIGHPIN ON \
          -set CPlusPlusDialect neutral -dll -m -verbose \
          -lcre -lcrtl -l zcobdll -export_all


ALL = libhello.so

.SUFFIXES: .java .class .h .c .o 

.c.o: 
    $(CC) $(CFLAGS) -c $<

all: $(ALL)

clean:
    @$(RM) *.o *.so

HelloJNI.o: cobincl.h HelloJNI.h HelloJNI.c

libhello.so: HelloJNI.o XCOBFUNC.o
      $(ELD) HelloJNI.o XCOBFUNC.o -o libhello.so $(LDFLAGS)

This is my java code:

public class HelloJNI {
   static {
      System.loadLibrary("hello"); // Load native library at runtime
                                   // hello.dll (Windows) or libhello.so (Unixes)
   }

   public HelloJNI() {

   }

   public void sendToC() {

       int par1 = 5;
       String name = "Test";


       short temp = sayHello(par1, name);
       System.out.println("temp = " + temp);
   }



   // Declare a native method sayHello() that receives nothing and returns void
   private native short sayHello(int par1, String name);
   //private native String sayHello(int par1, String name, String[] tokensKeys, String[] tokensValues);

   // Test Driver
   public static void main(String[] args) {
      //new HelloJNI().sayHello();  // invoke  the native method
      HelloJNI myObject = new HelloJNI();

      myObject.sendToC();

   }
}

I appreciate any help and it would be great if anyone can show me any examples on how java through JNI C program can call Cobol program on HP Tandem Non-Stop.

Please see from compilation process:

File: /usr/local/home/urily/Java_C_COBOL/c/libcobol.so
    Segment(Read/Write/Execute)       Address             Size 
---------------------------------------------------------------------------
    text(Read/Execute)          0x0000000078000000     0x00002000


File: libhello.so
    Segment(Read/Write/Execute)
      Section                         Address             Size
---------------------------------------------------------------------------
    text(Read/Execute)          0x0000000078000000     0x00001000
      .tandem_info              0x0000000078000190     0x00000198
      .lic                      0x0000000078000328     0x00000188
      .dynamic                  0x00000000780004b0     0x00000150
      .liblist                  0x0000000078000600     0x00000020
      .dynstr2                  0x0000000078000620     0x00000032
      .IA_64.unwind             0x0000000078000658     0x00000048
      .IA_64.unwind_info        0x00000000780006a0     0x00000018
      .IA_64.unwind.strings     0x00000000780006b8     0x0000004a
      .rconst                   0x0000000078000710     0x00000030
      .plt                      0x0000000078000740     0x00000020
      .text                     0x0000000078000780     0x00000080
      .hash                     0x0000000078000800     0x000000dc
      .dynsym                   0x00000000780008e0     0x00000360
      .dynstr                   0x0000000078000c40     0x000001bd
      .hashval                  0x0000000078000e00     0x00000090
      .rela.dyn                 0x0000000078000e90     0x00000030

I see that segment of libhello.so and libcobol.so have the same address 0x0000000078000000. I have created libcobol.so manually by two steps:

  1. cobol -c -Wcall_shared -Wsystype=oss -Wmap XCOBFUNC.cob
  2. /usr/bin/eld XCOBFUNC.o -o libcobol.so -dll -m -verbose -l zcobdll -lcre -lcrtl

How do you create a text segment with different addresses since right now they both have the same addresses?

Below my hs_err_pid.log

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=fffffffff2667174, pid=620757215, tid=4
#
# JRE version: 6.0
# Java VM: Java HotSpot(TM) Server VM (16.3-b01-svcnedccadmin:2011apr20-08:12 mixed mode nsk oss-ia64 )
# Problematic frame:
# C  [(DLL zcrtldll)+0x0]  printf + 0xF0 (DLL zcrtldll)+0x0
#
#  Please report this error to HP customer support.
#

---------------  T H R E A D  ---------------

Current thread (8330800):  JavaThread "main" [_thread_in_native, id=4, stack(809e000,81a1400)]


Frame 0: __stdio_fp + 0x171 (DLL zcrtldll)
        pc    : 0xfffffffff2667171
        ra    : 0xfffffffff26d6bf0
        sp    : 0x081a0510
        psp   : 0x081a0540
        cfm   : 0x0000020c      sol(ins+locals)=4, sof(ins+locals+outs)=12, sor=0
        bsp   : 0x081a1a10
        fpsr  : 0x9804c8a74433f
        pr    : 0x00008cbd
        br[0] : 0xfffffffff26d6bf0
        br[1] : 0x640303a0
        br[2] : 0x00000000
        br[3] : 0x00000000
        br[4] : 0x00000000
        br[5] : 0x00000000
        br[6] : 0xfffffffff26d6b00
        br[7] : 0xfffffffff90babc0
        lc    : 0x00000000
        ec    : 0x00000000

        gr0   : 0x00000000      0
        gr1   : 0x6cec84b0      1827439792
        gr2   : 0x6cec8608      1827440136
        gr3   : 0x7de00010      2111832080
        gr4   : 0x6cec84b0      1827439792
        gr5   : 0x081a0908      135923976
        gr6   : 0x080a2000      134881280
        gr7   : 0x0829e800      136964096
        gr8   : 0x64011640      1677792832
        gr9   : 0x00000008      8
        gr10  : 0x08330800      137562112
        gr11  : 0x00000000      0
        gr12  : 0x081a0510      135922960
        gr13  : 0xe0000002300009b6      -2305842999818450506
        gr14  : 0x7de00010      2111832080
        gr15  : 0x7de00028      2111832104
        gr16  : 0xfffffffff26d6b00      -227710208
        gr17  : 0x00000000      0
        gr18  : 0x00000000      0
        gr19  : 0x00000000      0
        gr20  : 0x7dde01e0      2111701472
        gr21  : 0x081a0870      135923824
        gr22  : 0x081a0878      135923832
        gr23  : 0x081a2038      135929912
        gr24  : 0x7dde0100      2111701248
        gr25  : 0x7dde0100      2111701248
        gr26  : 0x8000000000000000      -9223372036854775808
        gr27  : 0x6cf24918      1827817752
        gr28  : 0x0000000c      12
        gr29  : 0x00000001      1
        gr30  : 0x00000000      0
        gr31  : 0x00000000      0
        gr32  : 0x00000001      1
        gr33  : 0xc00000000000050d      -4611686018427386611
        gr34  : 0xfffffffff26d6bf0      -227709968
        gr35  : 0x6cec84b0      1827439792
        gr36  : 0x081a0800      135923712
        gr37  : 0x8330fcc00000000       590833344963411968
        gr38  : 0x081a08b4      135923892
        gr39  : 0x0c6221a8      207757736
        gr40  : 0x64099e10      1678351888
        gr41  : 0x7eec9bb0      2129435568
        gr42  : 0x08325fa0      137519008
        gr43  : 0x08325fa0      137519008
        fr1   : (0x0ffff,0x8000000000000000)    1

Stack: [809e000,81a1400],  sp=81a0540,  free space=%pk
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [(DLL zcrtldll)+0x0]  printf + 0xF0 (DLL zcrtldll)+0x0

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  HelloJNI.sayHello()V+0
j  HelloJNI.main([Ljava/lang/String;)V+7
v  ~StubRoutines::call_stub

---------------  P R O C E S S  ---------------

Java Threads: ( => current thread )
  106de800 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=12, stack(10a69000,10aa8800)]
  106da200 JavaThread "CompilerThread1" daemon [_thread_blocked, id=10, stack(10965000,109e4800)]
  1059b600 JavaThread "CompilerThread0" daemon [_thread_blocked, id=9, stack(10861800,108e1000)]
  106d4800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=8, stack(107e0000,1081f800)]
  106b4000 JavaThread "Finalizer" daemon [_thread_blocked, id=7, stack(1075e000,1079d800)]
  1062c400 JavaThread "Reference Handler" daemon [_thread_blocked, id=6, stack(1062f800,1066f000)]
=>8330800 JavaThread "main" [_thread_in_native, id=4, stack(809e000,81a1400)]

Other Threads:
  105a6800 VMThread [stack: 105a9000,105e8800] [id=5]
  106c2e00 WatcherThread [stack: 803c800,804c000] [id=11]

VM state: not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

Heap
 def new generation   total 3712K, used 228K [8450000, 8850000, 99a0000)
  eden space 3328K,   6% used [8450000, 8489150, 8790000)
  from space 384K,   0% used [8790000, 8790000, 87f0000)
  to   space 384K,   0% used [87f0000, 87f0000, 8850000)
 tenured generation   total 8192K, used 0K [99a0000, a1a0000, c450000)
   the space 8192K,   0% used [99a0000, 99a0000, 99a0100, a1a0000)
 compacting perm gen  total 65536K, used 1865K [c450000, 10450000, 10450000)
   the space 65536K,   2% used [c450000, c6225a0, c622600, 10450000)
No shared spaces configured.


VM Arguments:
java_command: HelloJNI
Launcher Type: SUN_STANDARD

Environment Variables:
JAVA_HOME=/usr/tandem/java
PATH=/bin:/bin/unsupported:/usr/bin:/usr/ucb:/usr/tandem/java/bin:/usr/tandem/javaexth10/bin:/usr/tandem/sqlmx/bin:/usr/tandem/java/jre/bin:/usr/tandem/jdbcMx/current/bin:/usr/oracle/ggs:/usr/tandem/nssoap/t0865h01_AAX/tools:.:
SHELL=/bin/sh


---------------  S Y S T E M  ---------------

OS:uname:NONSTOP_KERNEL dnb1 J06 19 NSE-W

CPU:total 1

Memory: 4k page, physical 0k

vm_info: Java HotSpot(TM) Server VM (16.3-b01-svcnedccadmin:2011apr20-08:12) for nsk oss-ia64 JRE (1.6.0), built on Apr 20 2011 09:18:56 by "svcnedccadmin" with c89

time: Mon May  9 18:51:12 2016
elapsed time: 1 seconds
user207421
  • 305,947
  • 44
  • 307
  • 483
uril
  • 11
  • 6
  • How can I link C function that calls Cobol and is located in shared library to Cobol object. – uril May 07 '16 at 15:55
  • 2
    That's a lot of information, and it's unlikely that there is someone familiar with Java **and** C **and** JNI **and** COBOL and is willing to dig though this. (Those people likely do $$$ per hour with other stuff ;-)). Maybe you can narrow it down: Does the plain Java-JNI-C call (without COBOL) work? Does a plain C program that does the COBOL call work? Or does the problem really only occur in this complex/specific setup? – Marco13 May 08 '16 at 02:05
  • Plain Java-JNI-C is working.Plain C program that call COBOL is working. – uril May 09 '16 at 19:12
  • Sorry, although I personally will (likely) not be able to help: When the JVM crashes with a SIGSEGV, it should write some `hs_err_....txt` file. This may contain some helpful information. (Note that it may also contain your computer name and some settings that you might want to omit when you post it here). – Marco13 May 09 '16 at 22:23
  • I added my hs_err_....txt file inside my question. Also I see that segment of libhello.so and libcobol.so have the same address 0x0000000078000000. I have created libcobol.so manually by two steps: 1. cobol -c -Wcall_shared -Wsystype=oss -Wmap XCOBFUNC.cob 2. /usr/bin/eld XCOBFUNC.o -o libcobol.so -dll -m -verbose -l zcobdll -lcre -lcrtl How do you create a text segment with different addresses since right now they both have the same addresses? – uril May 09 '16 at 23:20
  • It isn't clear from your question where the error is. How far into execution do you get? Into the C? Into the COBOL? Back into the C? And what does the part about text segments have to do with it? – user207421 May 09 '16 at 23:49
  • Hello Marco, do you have any simple examples on how to solve it? – uril May 09 '16 at 23:50
  • Sorry, I'm not familiar with COBOL (and also not with makefiles and the details of the linking process on unix, considering all the possible linker flags etc). Just to be sure: When you comment out the line `XCOBFUNC(tx, &ds, &dl);`, it works and prints the statements from the C function!? – Marco13 May 10 '16 at 08:48
  • From the `hs_err`, it looks like it crashed in the `printf` function, which seens to be located in `zcrtl.dll` in your case. – Marco13 May 10 '16 at 08:51
  • It's crashed on first statement inside the C function. Even if I comment out XCOBFUNC(tx, &ds, &dl); it's crashed as soon I link with XCOBFUNC.o. If I don't link with XCOBFUNC.o and comment out XCOBFUNC(tx, &ds, &dl); it's working correctly. I even put object XCOBFUNC.o in library(libcobol.so) and tried to link, but had the same problem. – uril May 10 '16 at 16:55
  • I'm not aware that there's a lot of Tandem experience on this site, and even less when actively interfacing with Java. Talk to your Tandem technical people, or the vendor, which I think is HP these days. – Bill Woodger May 11 '16 at 16:59

1 Answers1

0

i dunno what is tandem:ecobol, my gnucobol example works:

CallingCOBOL.java:

class CallingCOBOL {
    private native void adaptor(String from_java);
    public static void main(String[] args) {
        new CallingCOBOL().adaptor("Hello world!");
    }
    static {
        System.loadLibrary("adaptor");
    }
}

adaptor.c:

#include "dlfcn.h"
#include "jni.h"
#include "libcob.h"
#include "adaptor.h"
#include "stdio.h"
JNIEXPORT void JNICALL Java_CallingCOBOL_adaptor(JNIEnv * env, jobject obj, jstring string_from_java) {
    cob_init(0, NULL);
    void * sub_cob;
    sub_cob = dlopen("./libsub-cob.so", RTLD_NOW);
    if (!sub_cob) {
        puts("error no lib found");
        return;
    }
    puts("lib loaded");
    void(*proc_cob)(char*) = (void(*)(char*))dlsym(sub_cob, "proc__cob");
    if (proc_cob) {
        printf("proc addr is %p\n", proc_cob);
    } else {
        puts("proc addr is null");
    }
    const char *temp = (*env)->GetStringUTFChars(env, string_from_java, 0);
    puts("took string from java environment");
    proc_cob(temp);
    puts("cobol proc run ok");
    (*env)->ReleaseStringUTFChars(env, string_from_java, 0);
    dlclose(sub_cob);
    return;
}

sub-cob.cbl:

identification division.
program-id. sub-cob.
environment division.
configuration section.
data division.
working-storage section.
01 temp-string pic x(20) based.
01 pchar usage pointer.
01 my-string pic x(20).
linkage section.
01 string-from-java pic x(20).
procedure division.
sub-cob section.
goback.
entry "proc-cob" using by reference string-from-java.
display "entry proc-cob".
set pchar to address of string-from-java.
display "pchar set".
set address of temp-string to pchar.
display "temp-string set"
string temp-string delimited by x"00" into my-string.
display "my-string set".
display my-string.
goback.

makefile:

default:
        javac CallingCOBOL.java;
        javah CallingCOBOL;
        mv CallingCOBOL.h adaptor.h;
        gcc -shared -fPIC adaptor.c -I/usr/java/jdk1.8.0_92/include/linux -I/usr/java/jdk1.8.0_92/include -lcob -olibadaptor.so;
        cobc sub-cob.cbl -free -olibsub-cob.so;
clean:
        rm CallingCOBOL.class;
        rm adaptor.h;
        rm libadaptor.so;
        rm libsub-cob.so;