Menu

#673 bug in CALL-CONVENTION and CALL STDCALL literal

GC 3.x
open
None
7
2024-09-28
2020-08-22
Chuck H.
No

from what I understand in the programmers guide, CALL-CONVENTION 8 is supposed to be the same as STDCALL. This is WRONG according to the Programmer Guide bit 6 is supposed to be the same as STDCALL

Using the "STDCALL" option on a "CALL" statement is equivalent to using "CALL-CONVENTION 8" (only bit 3 set).

Using the "STATIC" option on a "CALL" statement is equivalent to using "CALL-CONVENTION 64" (only bit 6 set)

==========> conclusion

**The Programmer Guide is misleading "CALL-CONVENTION 64" is really the same as STDCALL "CALL-CONVENTION 8" is really the same as STATIC

3 Attachments

Related

Bugs: #673
Discussion: expand source code (COPY and INCLUDE)

Discussion

  • James K. Lowden

    James K. Lowden - 2020-09-09

    Let me try to boil this down.

    1. Section 7.8.5. (CALL) of the PG is inconsistent. The table in #5 (why are the paragraphs numbered, but tables have no names or numbers?) does not agree with the description of STDCALL and STATIC beneath it. Those descriptions should be reversed. That I can do.
    2. Conclusion item B is unclear to me. STDCALL cannot influence whether a name is resolved at link time, only how that name is used at runtime. IMO linker errors should never be followed by runtime errors, because link errors should prevent creation of the invalid binary (just as compile errors do).

    Bits 3 and 6 are independent, according to the documentation. It would be nice to have a test that does not rely on proprietary code (as DB2 is) that calls a function with 0, 8, 64, and 8+64.

    Documentationwise, the table in item 5 could be improved.

    • The bit numbers are irrelevant to the user, after whom the PG is named. The values in column 1 should be the ones used in CALL, not their bit positions.
    • The "unimplemented" values should be moved elsewhere. By definition, unimplemented values cannot occupy a bit position. The simple fact is that any bits set other than those that have an effect have no effect. What they would have done in another implementation is a topic for another day. Really: this "documentation" would better appear as a comment in the C code where the bit values are tested. When implemented, if ever, the PG can be augmented.
     

    Last edit: James K. Lowden 2020-09-09
  • Chuck H.

    Chuck H. - 2020-09-10

    James,

    thanks for replying to this issue. The issue with the documentation is easily resolved.

    The the Link and Execution issues are more troubling. So I downloaded the the VS2019 64 bit compiler so that I could test both the MinGW 32 and 64 bit compilers as well as the MS VS2019 32 and 64 bit compilers all against the same source code. DB2 supplies both 32 and 64 bit libraries to use for static linking. I'm using the DB2 Community Edition 11.5.4 which is available from IBM for free download / use.

    I used three version of source code all the same except for the calls to the DB2 modules. All of the modules include the SPECIAL-NAMES " CALL-CONVENTION 74 IS DB2API" phrase.

    The compile command used was the same for all of the tests except for the LIBRARY names for 64 bit or 32 bit.

    32 bit ===> cobc -x delet.cbl checkerr.cbl -fstatic-call -Id:/DB2/SQLLIB/include/cobol_mf -Ld:/DB2/SQLLIB/lib/win32 -ldb2api

    64 bit ===> cobc -x delet.cbl checkerr.cbl -fstatic-call -Id:/DB2/SQLLIB/include/cobol_mf -Ld:/DB2/SQLLIB/lib -ldb2api

    DELET.CBL uses CALL DB2API "literal"
    DELETC.CBL uses CALL STDCALL "literal"
    DELETA.CBL uses CALL "literal"

    For VS2019 64 bit compiler

    All three source codes compiled, linked and executed successfully.

    For VS2019 32 bit compiler

    All three source codes compiled and linked successfully. The DELET.CBL and DELETC.CBL versions executed successfully and the DELETA.CBL failed with this error "attempt to reference unallocated memory (signal SIGSEGV)".

    For the MinGW 64 bit compiler

    All three source codes compiled and linked successfully. However all 3 failed to execute successfully and encountered the same error, "attempt to reference unallocated memory (signal SIGSEGV)"

    For the MinGW 32 bit compiler

    The DELETA.CBL compiled and linked successfully but failed execution with the same error as above. The DELET.CBL and DELETC.CBL versions compiled successfully but failed to link as follows. Note that the MinGW COBOL compiler appears to be appending a "@0" to the end of the statically called DB2 modules. I have no idea why that is happening.p;

    F:\DB2TEMP>cobc -x delet.cbl checkerr.cbl -fstatic-call -Id:/DB2/SQLLIB/include/cobol_mf -Ld:/DB2/SQLLIB/lib/win32 -ldb2api
    C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x207): undefined reference to sqlgstrt@0' C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x2de): undefined reference tosqlgaloc@0'
    C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x413): undefined reference to sqlgstlv@0' C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x516): undefined reference tosqlgcall@0'
    C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x569): undefined reference to sqlgstop@0' C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x680): undefined reference tosqlgstrt@0'
    C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x757): undefined reference to sqlgaloc@0' C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x88c): undefined reference tosqlgstlv@0'
    C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x9ab): undefined reference to sqlgstlv@0' C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0xaca): undefined reference tosqlgstlv@0'
    C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0xbcd): undefined reference to sqlgcall@0' C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0xc20): undefined reference tosqlgstop@0'
    C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0xd4c): undefined reference to sqlgstrt@0' C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0xdd6): undefined reference tosqlgstls@0'
    C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0xed9): undefined reference to sqlgcall@0' C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0xf2c): undefined reference tosqlgstop@0'
    C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x1068): undefined reference to sqlgstrt@0' C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x116b): undefined reference tosqlgcall@0'
    C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x11be): undefined reference to sqlgstop@0' C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x12fa): undefined reference tosqlgstrt@0'
    C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x13fd): undefined reference to sqlgcall@0' C:\Users\spcwh2\AppData\Local\Temp\cob10672_0.o:cob10672_0.c:(.text+0x1450): undefined reference tosqlgstop@0'
    collect2.exe: error: ld returned 1 exit status

     
    • James K. Lowden

      James K. Lowden - 2020-09-10

      One other request, Chuck. Can you verify something for me?

      It's my belief that the C code produced by cobc is invariant with regard to OS or C compiler. That is, the C output from DELET.CBL is the same for all configurations you're testing.

      As you probably know, you can see the .c files with:

      cobc -C --save-temps delet.cbl
      

      Let's just make sure there's only one kind of input to the C compiler for each Cobol program.

      Just to be clear, the C files won't be byte-for-byte identical. They contain some "signature" information, such as when they were generated. You will see 5 lines that vary: 3 comments, and two compile-time constants (COB_MODULE_FORMATTED_DATE and COB_MODULE_TIME).

      It might be worthwhile to post your delet.c, just so I can compare with what I'm seeing.

      BTW, I'm having the same uphill struggle with DB2 on Linux that I had the first time I tried it several months ago: IBM makes it as hard as possible to install the client-side libraries. Under "installation methods", see There is no installation program for IBM Data Server Driver for ODBC and CLI or for IBM Data Server Driver Package on Linux® and UNIX. You must install the driver manually. It's almost as though they don't want me to....

       
  • James K. Lowden

    James K. Lowden - 2020-09-10

    Hi Chuck,

    Your first post described problems in the documentation, which we've addressed (not fixed, but understand) and raised concerns about how various flavors of CALL work or don't work. Now we're seeing that the same source code, compiled in different ways, exhibits different failure modes or, in the case of VS2019 64-bit, 100% success. That's a little weird, right? We should expect some runtime failures in every environment, because some of your test programs use CALL incorrectly for the db2api library.

    I think I can help, but first I have to be sure I understand exactly what you're doing. I'm sure you've heard it said, to have an intelligent discussion, first define the terms. Let's take a step back to make sure we know what we're saying.

    I downloaded the the VS2019 64 bit compiler so that I could test both the MinGW 32 and 64 bit compilers as well as the MS VS2019 32 and 64 bit compilers all against the same source code.

    • Do you mean you built cobc and libcob with all four combinations?
    • For each cobc, which C compiler is being invoked?

    Since DELET.CBL has different failure modes, we can focus on just that one file for now.

    It would be useful to see the output of cobc -v for each invocation. I would like to know which include files and libraries are being brought in at the C level, and what options are being used. I wonder, for example, what knob is being turned to produce a call to sqlgstrt@0 instead of just sqlgstrt.

    Particularly troubling is:

    For the MinGW 64 bit compiler
    All three source codes compiled and linked successfully. However all 3 failed to execute successfully and encountered the same error, "attempt to reference unallocated memory (signal SIGSEGV)"

    It's very confusing that all 3 programs work correctly using Microsoft's compiler, and none do using MinGW, when we know that some are designed to work and others fail. It takes real compiler magic to make a program succeed that's meant to fail.

    I will attempt to replicate your work in Linux as a baseline for comparison.

     
  • Chuck H.

    Chuck H. - 2020-09-10

    Hi James, first I did not build any of the compilers, the MinGW versions were downloaded from Arnold Trembley's site. The Microsoft VS2019 versions were downloaded from the site which Simon provided to me [https://ci.appveyor.com/project/GitMensch/gnucobol-3-x-vs]. Second, my background / experience is as a mainframe (Z/OS) COBOL programmer. I did take an introductory C programming class back in 1991 or 1992, but have not used C since then.

    I'll open a command prompt and provide the output from "cobc -v" a bit farther down.

    Another interesting and related discussion shows that using DYNAMIC calls to the DB2 modules does work with 64 bit Cygwin and MinGW compilers as tested by Laszso Erdos at the bottom of this disscussion thread [https://sourceforge.net/p/gnucobol/discussion/contrib/thread/e6744ecf/?page=1]

    the MinGW 64 compiler

    D:\GnuCOBOL64\bin>cobc -v
    cobc (GnuCOBOL) 3.1-rc1.0
    Built Jul 09 2020 07:15:24 Packaged Jul 01 2020 00:39:38 UTC
    C version (MinGW) "10.1.0"
    loading standard configuration file 'default.conf'
    cobc: error: no input files

    the MinGW 32 compiler

    D:\GnuCOBOL-31rc-NODB>cobc -v
    cobc (GnuCOBOL) 3.1-rc1.0
    Built Jul 04 2020 18:08:16 Packaged Jul 01 2020 00:39:30 UTC
    C version (MinGW) "6.3.0"
    loading standard configuration file 'default.conf'
    cobc: error: no input files

    the VS2019 64 compiler

    D:\GnuCOBOL_31_dev_vs_x64>cobc -v
    cobc (GnuCOBOL) 3.1-dev.20200726
    Built Jul 26 2020 23:43:38 Packaged Jul 26 2020 23:42:59 UTC
    C version (Microsoft) 1926
    loading standard configuration file 'default.conf'
    cobc: error: no input files

    the VS2019 32 compiler

    D:\GnuCOBOL_31_dev_vs>cobc -v
    cobc (GnuCOBOL) 3.1-dev.20200726
    Built Jul 26 2020 23:41:41 Packaged Jul 26 2020 23:40:58 UTC
    C version (Microsoft) 1926
    loading standard configuration file 'default.conf'
    cobc: error: no input files

    The command line compile is the same other than the name of the included DB2 lib directory. From what I can see no C header files are passed to the compiler other than it's default ones which are part of the compiler implementation.

    cobc -x delet.cbl checkerr.cbl -fstatic-call -Id:/DB2/SQLLIB/include/cobol_mf -Ld:/DB2/SQLLIB/lib/win32 -ldb2api

    Having worked with DB2 Z/OS for many years I'm somewhat familiar with the concept of building a SQLDA area. From the IBM DB2 LUW manual I found here at this site [https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwi81-iq3N_rAhWUAZ0JHaXXCA8QFjACegQIARAB&url=ftp%3A%2F%2Fpublic.dhe.ibm.com%2Fsoftware%2Fdata%2Fdb2%2Fad%2Fv8%2Fbldg%2Fprepapi.pdf&usg=AOvVaw1ko0awkDRcQmvkIDcbweMQ] Note that this downloads the manual as a PDF.

    I suspect SQLGALOC is allocating memory for an SQLDA structure in memory. However in the calls I don't see where a pointer is used to pass the address of that structure to the other modules which are actually building the SQLDA. So my suspicion is that the DB2 modules are putting data on the stack for subsequent calls. This would require that the "CALLEE" module be responsible for cleaning the stack NOT the "CALLER".

     
  • James K. Lowden

    James K. Lowden - 2020-09-11

    Thanks, Chuck. My experience is a mirror image of yours: I spent 1988 in CICS, where we used the "new" version of Cobol at the time, but have otherwise always worked in the vicinity of C.

    I have an answer for @0 from Raymond Chen. It signifies a stdcall function: Function names are decorated by a leading underscore and a trailing @-sign followed by the number of bytes of parameters taken by the function.

    Thanks for explaining where the compilers came from. Looking at the source code for cobc, I now think the emitted C code does vary based on which compiler was used to build cobc.

    I'm sorry I was unclear in my -v request. What I meant was to add -v to the command line when you compile DELET.CBL.

    Now, to some nuts and bolts, in both senses of nuts. sqlgstrt, to pick just one function, needs STDCALL. This we know from sqlaprep.h:

    SQL_API_RC SQL_API_FN
      sqlgstrt (
            char *,                            /* runtime program ID              */
            struct sqla_runtime_info *,        /* runtime information             */
            struct sqlca *);                   /* SQLCA                           */
    

    What that function returns and how it is called is declared in the line

    SQL_API_RC SQL_API_FN
    

    which are defined in sqlsystm.h:

    #if !defined SQL_API_RC
     #define SQL_API_RC      int
     #define SQL_STRUCTURE   struct
     #define SQL_POINTER
     #define SQL_API_FN      __stdcall
     #define SQL_API_INTR    __stdcall
     #define PSQL_API_FN     __stdcall *
    

    i.e., it returns int and is called with, ye olde __stdcall.

    So, this is what we know:

    • The C code emitted by cobc varies according to whether or not _WIN32 is defined. It is for VS; I'm not sure it is for minGW.
    • The db2api functions need STDCALL (or the equivalent bit set on) in the CALL.
    • stdcall functions are distinquished by their decoration, a leading _ and trailing @x, where x is supposed to be the number of bytes the function uses to pass its arguments on the stack. At least, that's what Raymond Chen said 16 years ago. That would explain your linker errors about functions ending in @0, because none of those functions use zero arguments. (Some number greater than zero should follow @.)

    Any call you make to db2api should use STDCALL. If you're so inclined, you can set both bits with 72 = 64 + 8, to force static linking; otherwise, linking is deferred until run time.

    We can no divide your issue into two parts:

    1. For calls with STDCALL, linker errors or incorrect execution.
    2. For calls without STDCALL, we can only expect bizarre behavior. At best, with bit 3 set on to force static linkage, we can expect linker errors.

    How does that compare to what you're seeing?

     

    Last edit: Simon Sobisch 2021-08-31
  • Chuck H.

    Chuck H. - 2020-09-12

    James, I tried to send an email to you directly but I suspect that your profile on sourceforge doesn' t allow people to send you emails.

    can you contact me at chaat@users.sourceforge.net ?

    then it might be easier to send you files / screen shots of WinMerge compares between generated C source code from MinGW and VS2019 compiles

    thanks

     
  • Chuck H.

    Chuck H. - 2020-09-13

    James, I've learned a bit more about C in the last couple of days. I've run a compile on all 4 compilers using the -S option to generate the Assembler code as well as the C code. I then studied the differences in the C code using Winmerge to compare the C source code files. They are nearly identical but not exactly the same. However when I looked at the Assembler files, particularily for the x86 compilers, the output was quite different. I was concentrating on the calls to the DB2 SQLGSTRT module as well as the others. I found that VS2019 and Gnu GCC produce two different styles of Assembler code. Also using the default compiler options, it looked like the GCC compiler is using the stack differently, putting more data on the stack before the call and then doing clean up of the stack after. According the the Microsoft documentation the STDCALL is that the CALLER is to load the parameters on the stack and the CALLEE is to clean the stack before returning.

    I was able to use the following compile options on the MinGW32 compiler to cause it to output Assembler code which looked very similar to the VS2019-32 output.

    cobc -S -A "-mpush-args -mno-accumulate-outgoing-args -mno-stack-arg-probe -m32 -mpreferred-stack-boundary=2 -masm=intel" -fstatic-call --save-temps -Id:/DB2/SQLLIB/include/cobol_mf -Ld:/DB2/SQLLIB/lib/win32 -ldb2api delet.cbl checkerr.cbl

    Even with this there is one glaring difference in the generated ASSEMBLER code. The VS2019 32 bit compiler generates the STDCALL with name mangling as follows, it prefixes the name with a single underscore character and appends @n, where n is the number of bytes pushed onto the stack. The GCC compiler mangles the name differently, the prefix is the same, but the suffix is @0 rather than the number of bytes pushed onto the stack. Hence the Linker can not find the @0 name in the library.

    here are the attached files. The zip files contain the output intermediate files from the different compilers using the -S option to generate the assember source code.

    MinGW-32-extra-C-options.zip
    MinGW32.zip
    MinGW64.zip
    vs32.zip
    vs64.zip

    The txt files contain the output of the -vvv option on the vs32 and MinGW32 with the extra options.

    MinGW32-compile-with-vvv.txt
    vs32-compile-with-vvv.txt

    So at this point I'm stuck as I don't know how to get the GCC compiler to generate the mangled STDCALL function names correctly.

    Please let me know if you need any more information to resolve this or if this is an issue that can't be resolved.

                thanks,  Chuck Haatvedt
    
     
    • James K. Lowden

      James K. Lowden - 2020-09-15

      The GCC compiler mangles the name differently, the prefix is the same, but the suffix is @0 rather than the number of bytes pushed onto the stack. Hence the Linker can not find the @0 name in the library.

      This finding is consistent with mine, below. No matter what I do, I can't get the executable to find the function it wants. That could be be because it's looking in the wrong place, or because it's asking for the wrong symbol (an incorrectly decorated name).

       
  • James K. Lowden

    James K. Lowden - 2020-09-15

    Hi Chuck,

    I haven't been able to get delet.cbl to run using Arnold's compiler, although I'm not sure where the trouble lies.

    Sticking just with this one program for the moment, I don't understand how to tell cobc or the C compiler to find the db2api functions. These things I do know:

    • The mnGW compiler from Arnold Trembly's site is 32-bit, as is the db2api library.
    • The DLL has STDCALL functions. It also might have versions of the same functions that don't need STDCALL.
    • The db2api DLLs are on my PATH.
    • I name the import library db2api.lib on the command line, along with a search path for it.
    • The build "works", but the program stops when it can't find the first symbol.

    For starters, here's the DLL with the "interesting" function:

    dumpbin /exports db2agapi.dll | awk "/gstrt|GSTRT/ {print}"
            295  126 00013550 SQLGSTRT
            296  127 00013550 SQLGSTRT@12
            627  272 00013550 sqlgstrt
            628  273 00013550 sqlgstrt@12
    

    That @12 signifies a STDCALL function needing 12 bytes on the stack, but it lacks the leading underscore. Maybe that matters. The symbol is provided as both upper and lower case, and seems to have both stdcall and cdecl versions.

    I think the C code emitted by cobc is correct. It produces:

            call_SQLGSTRT.funcvoid = cob_resolve_cobol ("SQLGSTRT", 0, 1);
          }
          b_2 = ((int (*)(void *, cob_s32_t, void *))call_SQLGSTRT.funcint_std) (content_1.data, (cob_s32_t)0LL, b_8);
    

    There's a lot of inside baseball there. cob_resolve_cobol looks up its argument (undecorated, it seems), and stores the function's address in the funcvoid member of the left-hand side. The next line invokes that function, and assigns its return code to b_2.

    (cobc codegen note: I'm not sure the above code is strictly correct. The variable call_SQLGSTRT is a union with two members that evaluate to the same address. Strictly speaking, the only safe use of union members is to read the member most recently written to. One should not write to U.a and read from U.b, even if they are at the same address, because the compiler has the "right" to optimize the object code. If it sees the written variable is never read, it might eliminate the write operation, leaving the read with indeterminate data. )

    So, we know there is a DLL, db2agapi.dll on the PATH that provides SQLGSTRT. We're pretty sure, examining the produced C, that delet.exe calls the function using the STDCALL convention. If we can just get the executable to find its library, we can hope to move on to a runtime error, because I don't have a DB2 server installed. ;-)

    In Windows, DLLs are described by so-called "import libraries". One names the import library on the command line,. The produced executable later uses the associated DLL, which is found by searching the PATH.

    Unlike Linux, on Windows there are no standard utilities to inspect the executable for its dependencies, or to trace (or control) the DLL search at run time. So I'm at a loss at the moment to say what search is being conducted, and why the function isn't found.

    To review:

    delet.cbl uses CALL STDCALL "SQLGSTRT"

    compiled as:

    cobc (GnuCOBOL) 3.1-rc1.0
    Built     Jul 04 2020 17:17:54  Packaged  Jul 01 2020 00:39:30 UTC
    C version (MinGW) "6.3.0"
    loading standard configuration file 'default.conf'
    command line:   cobc -v -x --save-temps -o delet -L C:\Program Files\IBM\SQLLIB\lib -ldb2api delet.cbl
    preprocessing:  delet.cbl -> delet.i
    return status:  0
    parsing:        delet.i (delet.cbl)
    return status:  0
    translating:    delet.i -> delet.c (delet.cbl)
    executing:      gcc -c -I"C:\Program Files (x86)\cobol\include" -o "delet.o"
                    "delet.c"
    return status:  0
    executing:      gcc -Wl,--export-all-symbols -Wl,--enable-auto-import
                    -Wl,--enable-auto-image-base -o "delet" "delet.o"
                    -L"C:\Program Files (x86)\cobol\lib" -L/mingw/lib -lcob -lm
    return status:  0
    

    With environment:

    673> set cob
    COB_CFLAGS=-I"C:\Program Files (x86)\cobol\include"
    COB_CONFIG_DIR=C:\Program Files (x86)\cobol\config
    COB_COPY_DIR=C:\Program Files (x86)\cobol\copy
    COB_LDFLAGS=-L"C:\Program Files (x86)\cobol\lib"
    COB_LIBRARY_PATH=C:\Program Files (x86)\cobol\extras;C:\Program Files\IBM\SQLLIB\lib
    COB_MAIN_DIR=C:\Program Files (x86)\cobol\
    

    fails as:

    C:\Users\Administrator\projects\cobol\673>delet
    Sample COBOL program: DELET
    Enter your user id (default none):
    BEFORE FIRST CALL TO SQLGSTRT
    libcob: error: module 'SQLGSTRT' not found
    

    Also fails if the import library is explicitly defined.

    command line:   cobc -v -x --save-temps -o delet -L C:\Progra~1\IBM\SQLLIB\lib -ldb2api delet.cbl
    preprocessing:  delet.cbl -> delet.i
    return status:  0
    parsing:        delet.i (delet.cbl)
    return status:  0
    translating:    delet.i -> delet.c (delet.cbl)
    executing:      gcc -c -I"C:\Program Files (x86)\cobol\include" -o "delet.o"
                    "delet.c"
    return status:  0
    executing:      gcc -Wl,--export-all-symbols -Wl,--enable-auto-import
                    -Wl,--enable-auto-image-base -o "delet" "delet.o" "-L
                    C:\Progra~1\IBM\SQLLIB\lib -ldb2api" -L/mingw/lib -lcob -lm
    return status:  0
    

    same error when run:

    Sample COBOL program: DELET
    Enter your user id (default none): 
    BEFORE FIRST CALL TO SQLGSTRT
    libcob: error: module 'SQLGSTRT' not found
    
     
  • James K. Lowden

    James K. Lowden - 2020-09-15

    Update: I wrote a tiny C program that only calls sqlgstrt. It fails to link with a noteable message:

    gcc  -I"C:\Progra~1\IBM\SQLLIB\include"  -osqlgstrt.exe sqlgstrt.c -L C:\Progra~1\IBM\SQLLIB\lib -ldb2api
    C:\Program Files (x86)\cobol\bin/ld.exe: C:\Progra~1\IBM\SQLLIB\lib/db2api.lib(DB2APP64.dll): Recognised but unhandled machine type (0x8664) in Import Library Format archive
    C:\Users\ADMINI~1\AppData\Local\Temp\2\ccmLim5T.o:sqlgstrt.c:(.text+0x3e): undefined reference to `sqlgstrt@12'
    collect2.exe: error: ld returned 1 exit status
    make: *** [sqlgstrt.exe] Error 1
    

    This is asking for sqlgstrt@12, which is good (probably), but complaining about stumbling on a 64-bit DLL. That DLL isn't in its way; there is a 32-bit version (db2app.dll), and in any case that's not the one it needs, which is db2agapi.dll.

    No luck so far getting my simple program to link with Visual Studio, either.

     
    • James K. Lowden

      James K. Lowden - 2020-09-15

      Solved that particular mystery. The path to the 32-bit import library is

      C:\Progra~1\IBM\SQLLIB\lib\win32
      

      With that path adjusted, my simple static linked C program works: no hits, no runs, no errors.

      No luck on the Cobol side, yet, but tomorrow is another day in Tara.

       
  • James K. Lowden

    James K. Lowden - 2020-09-22
    • Status: open --> pending
    • Group: unclassified --> GC 4.0
    • Priority: 5 - default --> 7
     
  • James K. Lowden

    James K. Lowden - 2020-09-22

    This bug is real, but limited to 32-bit Windows. STDCALL is used only on Windows, and is ignored by 64-bit compilation. Whether or not it will be fixed is undetermined.

    The problem is that calls marked STDCALL in Cobol generate an incomplete function prototype in C, causing gcc to generate an incorrectly decorated name that subsequently cannot be resolved, either by the linker (if STATIC) or otherwise at runtime.

    Reportedly the Microsoft compiler does not exhibit the same behavior, but that report hasn't been independently verified.

    One workaround is to use -include C/header/file.h on the cobc command line. That lets the C header file provide the function prototypes and suppresses their generation by cobc. Inconvenient, but then workarounds usually are. Not brittle, though: if the cobol passes incorrect parameters, the generated C will not conform to the provided prototype, and a C compilation error ensues.

     
  • Simon Sobisch

    Simon Sobisch - 2021-01-05
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,57 +1,9 @@
    -I've tested with the MinGW 3.1rc and the MS VS2019 Dev versions.
    -
    -I've attached 2 cobol source files which make static calls to some IBM DB2 modules
    -DELET.CBL uses CALL STDCALL literal
    -DELETC.CBL uses CALL DB2API literal
    -
    -both use SPECIAL NAMES CALL-CONVENTION 8 IS DB2API.
    -
     from what I understand in the programmers guide, CALL-CONVENTION 8 is supposed to be the same as STDCALL. This is WRONG according to the Programmer Guide bit 6 is supposed to be the same as STDCALL
    
     Using the "STDCALL" option on a "CALL" statement is equivalent to using "CALL-CONVENTION 8" (only bit 3 set).
    
     Using the "STATIC" option on a "CALL" statement is equivalent to using "CALL-CONVENTION 64" (only bit 6 set)
    
    -When compiling them both on MinGW notice that the CALL DB2API version encounters errors.
    -It also fails at execution time
    -
    -F:\DB2SAMPLE>
    -F:\DB2SAMPLE>cobc -x deletc.cbl checkerr.cbl -fstatic-call -Id:/DB2/SQLLIB/include/cobol_mf -Ld:/DB2/SQLLIB/lib/win32 -ldb2api
    -
    -F:\DB2SAMPLE>cobc -x delet.cbl checkerr.cbl -fstatic-call -Id:/DB2/SQLLIB/include/cobol_mf -Ld:/DB2/SQLLIB/lib/win32 -ldb2api
    -C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0x22d): undefined reference to SQLGSTRT@0' C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0x32a): undefined reference toSQLGALOC@0'
    -C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0x45f): undefined reference to SQLGSTLV@0' C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0x562): undefined reference toSQLGCALL@0'
    -C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0x5b5): undefined reference to SQLGSTOP@0' C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0x6e5): undefined reference toSQLGSTRT@0'
    -C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0x7bc): undefined reference to SQLGALOC@0' C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0x8f1): undefined reference toSQLGSTLV@0'
    -C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0xa10): undefined reference to SQLGSTLV@0' C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0xb2f): undefined reference toSQLGSTLV@0'
    -C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0xc32): undefined reference to SQLGCALL@0' C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0xc85): undefined reference toSQLGSTOP@0'
    -C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0xdd7): undefined reference to SQLGSTRT@0' C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0xe8f): undefined reference toSQLGSTLS@0'
    -C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0xfc0): undefined reference to SQLGCALL@0' C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0x1041): undefined reference toSQLGSTOP@0'
    -C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0x13d9): undefined reference to SQLGSTRT@0' C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0x1538): undefined reference toSQLGCALL@0'
    -C:\Users\spcwh2\AppData\Local\Temp\cob452_0.o:cob452_0.c:(.text+0x15e7): undefined reference to `SQLGSTOP@0'
    -collect2.exe: error: ld returned 1 exit status
    -
    -F:\DB2SAMPLE>deletc
    -Sample COBOL program: DELET
    -Enter your user id (default none):
    -BEFORE FIRST CALL TO SQLGSTRT
    -
    -attempt to reference unallocated memory (signal SIGSEGV)
    -abnormal termination - file contents may be incorrect
    -
    -The VS2019 version compiles successfully both ways, but only the STDCALL version executes successfully
    -
    -F:\DB2SAMPLE>cobc -x delet.cbl checkerr.cbl -fstatic-call -Id:/DB2/SQLLIB/include/cobol_mf -Ld:/DB2/SQLLIB/lib/win32 -ldb2api
    -
    -F:\DB2SAMPLE>cobc -x deletc.cbl checkerr.cbl -fstatic-call -Id:/DB2/SQLLIB/include/cobol_mf -Ld:/DB2/SQLLIB/lib/win32 -ldb2api
    -
    -Note ===> when I change to ==> CALL-CONVENTION 64 IS DB2API.
    -Then the VS2019 is successful as well.
    -
     ==========> conclusion
    
    -**A. The Programmer Guide is misleading "CALL-CONVENTION 64" is really the same as STDCALL "CALL-CONVENTION 8" is really the same as STATIC
    -
    -B. In the MinGW the STDCALL convention is generating link errors and the DB2API version is failing at execution time with "attempt to reference unallocated memory (signal SIGSEGV)"
    -
    -So there are issues with the MinGW STDCALL and "CALL-CONVENTION 64", the first generating Linker errors and the second generating execution errors. **
    +**The Programmer Guide is misleading "CALL-CONVENTION 64" is really the same as STDCALL "CALL-CONVENTION 8" is really the same as STATIC
    
    • assigned_to: Vincent (Bryan) Coen
    • Group: GC 4.0 --> Programmer's Guide
     
  • Simon Sobisch

    Simon Sobisch - 2021-01-05

    As for the C stdcall declaration bug is now in [bugs:#678] lets limit this bug to the PG.

     

    Related

    Bugs: #678

  • Vincent (Bryan) Coen

    • assigned_to: Vincent (Bryan) Coen --> James K. Lowden
     
  • Gabor Markon

    Gabor Markon - 2021-04-14

    I use OpenCobol IDE 4.7.6 to compile the Db2 sample program "cblsql2" under Windowx 10. Before compiling, I generate the proper COBOL source by using Db2 "prep", which I include then as input in the IDE.
    I get the same errors as James:
    "
    C:\Users\pc\AppData\Local\Temp\cob19424_0.o:cob19424_0.c:(.text+0x251): undefined reference to sqlgstrt' C:\Users\pc\AppData\Local\Temp\cob19424_0.o:cob19424_0.c:(.text+0x3b8): undefined reference tosqlgaloc'
    ...
    "

    I use following GCC:

    C:\progs\OpenCobolIDE\GnuCOBOL\bin>gcc --version
    gcc (GCC) 5.3.0

    I (supposed to) include also the proper library path as proposed by James:

    C:\Program Files\IBM\SQLLIB\lib\Win32

    Is there any solution to solve the problem in the meanwhile? I mean, to use another C compiler etc...?

    Regards
    Gabor

     
    • Simon Sobisch

      Simon Sobisch - 2021-04-14

      Not sure why you want to use a different C compiler: why not just add the appropriate library path and library via its configuration options?
      Ideally the complete db2prep step would be done by OCIDE, which actually is coded as seen in https://github.com/OpenCobolIDE/OpenCobolIDE/blob/master/doc/source/advanced.rst - but possibly this is disabled on Win32? Again: manually adding the library settings should help.

       
    • Chuck H.

      Chuck H. - 2021-04-14

      Gabor,

      this is an email that I sent to bug #678, it may be helpful for you. As you can see below I had the most success with the 64 bit version of theVS2019 version of the GNUCOBOL compiler.

      I've done some additional testing.

      The DB2 precompiler can generate COBOL code for a number of different dialects. I've tested with the following

      db2 prep deletx.sqb bindfile target ANSI_COBOL --> this generates the calls as "CALL "sqlg" where sqlg is the DB2 module

      db2 prep deletx.sqb bindfile target mfcob --> this generates the calls as "CALL DB2API"sqlg" where sqlg is the DB2 module and DB2API is set to CALL-CONVENTION 74.

      for testing purposes I changed the DB2API value to 64 so that I could control static vs dynamic via compile time parameters.

      So each version of the compiler has 4 variations mfcob or ANSI_COBOL and static or dynamic calls.

      VS2019-64 bit MF static successful
      MF dynamic successful
      ANSI static successful
      ANSI dynamic successful

      VS2019-32 bit MF static successful
      MF dynamic failed
      ANSI static failed
      ANSI dynamic failed

      MinGW-64 bit MF static failed
      MF dynamic successful
      ANSI static failed
      ANSI dynamic successful

      MinGW-32 bitt MF static link error (this is the prototype issue)
      MF dynamic failed
      ANSI static failed
      ANSI dynamic failed

      So there is a difference between the MinGW and Visual Studio versions of the GNUCOBOL compiler. The differences only are present when using static calls to the DB2 modules.

      That being said, perhaps it's not worth pursuing why these differences exist. So if someone wants to mark this ticket as closed that would be ok with me.

      Perhaps the issue with the prototype not including the parameters used in the CALL statement could potentially impact other applications which link to libraries created with MSVC, so that might we worth investigating.

      Also the DB2 precompiler has an option to use "TARGET ibmcob". It generates the same output as ANSI_COBOL so no need to test that.

       
      • Simon Sobisch

        Simon Sobisch - 2021-08-31

        What targets does db2 prep supports? How do they differ in code generation?

         
  • Vincent (Bryan) Coen

    Is this bug for the PG manual now finished ?

    If not what exactly is required to go into the manual replace what and where ?

     
    • Gabor Markon

      Gabor Markon - 2021-05-23

      Hello,

      sorry for the late answer. I try recently to use the OCIDE as Simon
      proposed. It seems to work fine with the preprocessor, but the generated
      code has a couple of errors which I must to check.

      Am Sa., 15. Mai 2021 um 17:04 Uhr schrieb Vincent (Bryan) Coen vcoen@users.sourceforge.net:

      Is this bug for the PG manual now finished ?

      If not what exactly is required to go into the manual replace what and
      where ?


      Status: pending
      Group: Programmer's Guide
      Created: Sat Aug 22, 2020 08:39 PM UTC by Chuck H.
      Last Updated: Wed Apr 14, 2021 07:37 PM UTC
      Owner: James K. Lowden
      Attachments:

      from what I understand in the programmers guide, CALL-CONVENTION 8 is
      supposed to be the same as STDCALL. This is WRONG according to the
      Programmer Guide bit 6 is supposed to be the same as STDCALL

      Using the "STDCALL" option on a "CALL" statement is equivalent to using
      "CALL-CONVENTION 8" (only bit 3 set).

      Using the "STATIC" option on a "CALL" statement is equivalent to using
      "CALL-CONVENTION 64" (only bit 6 set)

      ==========> conclusion

      **The Programmer Guide is misleading "CALL-CONVENTION 64" is really the
      same as STDCALL "CALL-CONVENTION 8" is really the same as STATIC


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/gnucobol/bugs/673/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       

      Related

      Bugs: #673

  • Vincent (Bryan) Coen

    • status: pending --> open
    • Group: Programmer's Guide --> GC 3.x
     
  • Vincent (Bryan) Coen

    My head hurts - So "exactly" what should the manual be saying?

    EXACTLY. ---- and make sure you read the manual for CALL.

     

Log in to post a comment.