From: charles.goodman on 1 Feb 2008 12:48 Thanks for the tips. Yes I needed to add my curent directory to LD_LIBRARY_PATH I also nneded to add "-L./" to the cobol command to compile the main program. My compile commands, that work are: cobol -dy -shared -WC,"BINARY(BYTE)" -o libMYSUB1.so MYSUB1.cbl cobol -dy -shared -WC,"BINARY(BYTE)" -o libMYSUB2.so MYSUB2.cbl cobol -M -dy -WC,"BINARY(BYTE),DLOAD" -o MYMAIN -L./ -lMYSUB1 -lMYSUB2 MYMAIN.cbl I am able to compile and execute. My simple programs are designed to allow me to see the functioning of CALL and CANCEL..... However the results is NOT exactly what I want. Using -l does not allow for proper functioning of the CANCEL verb (see pg 77 of user's guide). Once a subprogram is loaded with a CALL statement, it remains in memory regardless of CANCEL statements. The working-storage of the sub-program is not reinitialized upon a second CALL. ---Charlie
From: Richard on 1 Feb 2008 14:14 On Feb 1, 6:48 am, charles.good...(a)bell.ca wrote: > Thanks for the tips. > Yes I needed to add my curent directory to LD_LIBRARY_PATH > I also nneded to add "-L./" to the cobol command to compile the main > program. > My compile commands, that work are: > cobol -dy -shared -WC,"BINARY(BYTE)" -o libMYSUB1.so MYSUB1.cbl > cobol -dy -shared -WC,"BINARY(BYTE)" -o libMYSUB2.so MYSUB2.cbl > cobol -M -dy -WC,"BINARY(BYTE),DLOAD" -o MYMAIN -L./ -lMYSUB1 -lMYSUB2 > MYMAIN.cbl > > I am able to compile and execute. My simple programs are designed to > allow me to see the functioning of CALL and CANCEL..... > > However the results is NOT exactly what I want. Using -l does not > allow for proper functioning of the CANCEL verb (see pg 77 of user's > guide). Once a subprogram is loaded with a CALL statement, it remains > in memory regardless of CANCEL statements. The working-storage of the > sub-program is not reinitialized upon a second CALL. Robert is completely wrong. You do not need a -l or a -L. These will turn the CALLs into a static load and, as you say, the CANCEL will not work as expected. Go back to using your original compiles and links _without_ the -l or - L. It was only the LD_LIBRARY_PATH change that was required. I am not sure how you determined that the CANCEL did not work but I modified your programs to add a 2nd CALL and a CANCEL followed by a 3nd CALL in MYMAIN and then added a check for 'first time in' into MYSUB1 and it worked as _I_ expected. IDENTIFICATION DIVISION. PROGRAM-ID. MYMAIN. DATA DIVISION. WORKING-STORAGE SECTION. 01 ACPT PIC X. PROCEDURE DIVISION. OPEN-PARA. DISPLAY "BEGIN MYMAIN". CALL 'MYSUB1'. CALL 'MYSUB1'. CANCEL 'MYSUB1'. CALL 'MYSUB1'. DISPLAY "THE END - ACCEPTING ONE BYTE". ACCEPT ACPT. STOP RUN. IDENTIFICATION DIVISION. PROGRAM-ID. MYSUB1. DATA DIVISION. WORKING-STORAGE SECTION. 01 ACPT PIC X. 01 FIRST-IN PIC X VALUE "Y". PROCEDURE DIVISION. OPEN-PARA. IF FIRST-IN = "Y" DISPLAY "First Time In" ELSE DISPLAY "Been here before" END-IF MOVE "N" TO FIRST-IN DISPLAY "BEGIN MYSUB1 - ACCEPTING ONE BYTE". ACCEPT ACPT. EXIT PROGRAM. As expected I got (ignoring your displays and accepts): First Time In Been here before First Time In So the CANCEL worked exactly as it should.
From: Richard on 1 Feb 2008 14:47 On Jan 31, 7:23 pm, Robert <n...(a)e.mail> wrote: > On Wed, 30 Jan 2008 20:46:28 -0800 (PST), Richard <rip...(a)azonic.co.nz> wrote: > >On Jan 31, 4:38 pm, Robert <n...(a)e.mail> wrote: > >> >when I try to execute I see my first DISPLAY and then it crashes: > >> >BEGIN MYMAIN > >> >cobol-rts:: HALT: JMP0015I-U [PID:0000763D TID:002516C0] CANNOT CALL > >> >PROGRAM 'MY > >> >SUB1'. ./MYMAIN: undefined symbol: MYSUB1 PGM=MYMAIN > >> >Aborted > > >> >I am running on Red Hat Enterprise, and Fujitsu support say they will > >> >only support: > >> > * Red Hat Linux 7.2, Locale C > >> > * Red Hat Linux 7.3, Locale C > >> > * Red Hat Linux Advanced Server 2.1, Locale C > > >> >I am hoping that someone here has figured out how to compile and line > >> >on less ancient versions of Linux. > > >> Try '-l MYSUB1' (lower case el) on the compilation of MYMAIN. As written, MYMAIN has no > >> way of knowing the library name. > > >I think that you fail to understand what 'Dynamic Load' means. > > There is no Cobol syntax to specify a library name. You can only specify an entry point > name. When you do a CALL, Unix doesn't search every library in the library path. That > would be hopelessly slow. It searches only the libraries named in the executable's ELF > header. > > Libraries normally contain many programs and entry points. They are not one-for-one like > the example here. Robert, you really should try to understand the problem and its solution _before_ you show your complete lack of understanding of what is happening. I had already said that the code and compiles as given in the first message _worked_ on my machine and that the only change required was to the LD_LIBRARY_PATH which is the environment variable used for _dynamic_ loads. I had actually compiled and ran these programs to ensure that what I said was correct and that I was not giving bad or wrong advice. I had indicated, gently, to you that you were not on the right track. I have used dynamic loading of Cobol with mainframes, with Micro Focus since CIS Cobol, on RM, Fujitsu and others since the days of CP/M and with Unix, DOS, Windows and Linux. I have even done dynamic loading with C. You have made several claims above which are FACTUALLY WRONG and show that you, as I said before, completely fail to understand dynamic loading, or even that it is possible. With Fujitsu Cobol the DLOAD directive tells the system that CALLs might be dynamic. In these cases there is no need for the library containing the called routine to be known to the ELF binary, there is no need for a -l, nor for the library to even exist at link (ld) time. At run time a dynamic call will look for a file called libNAME.so along the LD_LIBRARY_PATH, where NAME is that in the CALL, and it will load that and find the required entry point. As you should be able to tell from the results in charles' 2nd message your BAD and WRONG advice has meant that his program does not work as he expected. He statically linked the dynamic library which will cause the CANCEL to fail to unload it and thus a reload does not find a new copy but reuses the old.
From: Robert on 1 Feb 2008 22:23 On Thu, 31 Jan 2008 11:47:51 -0800 (PST), Richard <riplin(a)azonic.co.nz> wrote: >On Jan 31, 7:23 pm, Robert <n...(a)e.mail> wrote: >> On Wed, 30 Jan 2008 20:46:28 -0800 (PST), Richard <rip...(a)azonic.co.nz> wrote: >> >On Jan 31, 4:38 pm, Robert <n...(a)e.mail> wrote: >> >> >when I try to execute I see my first DISPLAY and then it crashes: >> >> >BEGIN MYMAIN >> >> >cobol-rts:: HALT: JMP0015I-U [PID:0000763D TID:002516C0] CANNOT CALL >> >> >PROGRAM 'MY >> >> >SUB1'. ./MYMAIN: undefined symbol: MYSUB1 PGM=MYMAIN >> >> >Aborted >> >> >> >I am running on Red Hat Enterprise, and Fujitsu support say they will >> >> >only support: >> >> > * Red Hat Linux 7.2, Locale C >> >> > * Red Hat Linux 7.3, Locale C >> >> > * Red Hat Linux Advanced Server 2.1, Locale C >> >> >> >I am hoping that someone here has figured out how to compile and line >> >> >on less ancient versions of Linux. >> >> >> Try '-l MYSUB1' (lower case el) on the compilation of MYMAIN. As written, MYMAIN has no >> >> way of knowing the library name. >> >> >I think that you fail to understand what 'Dynamic Load' means. >> >> There is no Cobol syntax to specify a library name. You can only specify an entry point >> name. When you do a CALL, Unix doesn't search every library in the library path. That >> would be hopelessly slow. It searches only the libraries named in the executable's ELF >> header. >> >> Libraries normally contain many programs and entry points. They are not one-for-one like >> the example here. [the usual insults snipped] >With Fujitsu Cobol the DLOAD directive tells the system that CALLs >might be dynamic. In these cases there is no need for the library >containing the called routine to be known to the ELF binary, there is >no need for a -l, nor for the library to even exist at link (ld) time. Normal Unix binding, outside Cobol, is to enter the names of called libraries in the executable's header, using -l . Doing so does NOT mean they are statically linked as the term is understood by mainframers and others from the Old School. It means the library files will be loaded (if not already in memory) when the executable starts. If any cannot be found, the program will not start, which guarantees the program will not abort mid-run because a called program is missing. It also allows useful diagnostics to be run before starting a long batch job. A Windows dll works almost exactly the same as a Unix library (.so). Cobol can, and I believe should, use the normal Unix binding mechanism. There are several advantages and no good reason not to. In addition to the advantages given above, one specific to Cobol is non-proliferation of program files, which I'll explain below. Dynamic binding is the alternative. A running program can ask the OS to load an additional library by specifying its FILE NAME. Technically, this is done with a call to dlopen() (or LoadLibrary() on Windows). The OS first checks to see whether the library is already loaded in memory, either because it was in the program's own header or because some other running process is using it. If not, it searches the library path looking for the file name and loads it. In either case it returns a handle to THE FILE that the program can use to search for a specific entry point or the file's default entry point (with the dlsym() function). The problem with dynamic binding in Cobol is that Cobol has no concept of library FILE NAME, it only knows about entry point names, which are essentially the same as program names. Thus, Charles' application with "hundreds of COBOL programs", if packaged for dynamic call, will have HUNDREDS OF LIBRARY FILES, each named libPROGRAM.so. I find that ugly and, from a deployment point of view, clunky and amateurish. It would be cleaner to package his hundreds of programs into one or a few libraries that are linked to the main executable. How many third-party apps have you seen that came with hundreds of libraries or dlls? >At run time a dynamic call will look for a file called libNAME.so >along the LD_LIBRARY_PATH, where NAME is that in the CALL, and it will >load that and find the required entry point. It will first look for the symbol NAME already loaded. If not found THEN it will load libNAME.so. >As you should be able to tell from the results in charles' 2nd message >your BAD and WRONG advice has meant that his program does not work as >he expected. He statically linked the dynamic library which will cause >the CANCEL to fail to unload it and thus a reload does not find a new >copy but reuses the old. Wrong. If Cobol issues a dlclose() on libMYSUB1.so, even though it was 'statically' linked with -l, it will be unloaded .. and reloaded the next time he calls it. If it is packaged in a library with a hundred other programs, the whole library might be unloaded, because the handle for NAME is the handle for libMYSUBS.so. Or Fujitsu might be smart enough to know it wasn't dynamically loaded. If he really needs initial values, he should use the Cobol INITIAL clause. Incidentally, CANCEL is not guaranteed to unload the program your way, either. A dynamically loaded library can only be unloaded when its user count is zero. If another developer happens to be using the same called program, CANCEL will fail, and Cobol has no way of checking for that. If you want to be hackerish, issue the CANCEL 100 times. Each call to dlopen() subtracts 1 from the user count. Then listen for cursing from the next cubicle. :) The reason Windows installers want you to reboot is because they don't have a reliable way of deleting old dlls they just replaced. The solution is to call FreeLibrary until it disappears from memory.
From: Robert on 1 Feb 2008 22:33 On Thu, 31 Jan 2008 09:48:48 -0800 (PST), charles.goodman(a)bell.ca wrote: >Thanks for the tips. >Yes I needed to add my curent directory to LD_LIBRARY_PATH >I also nneded to add "-L./" to the cobol command to compile the main >program. -L is used to override the user's LD_LIBRARY_PATH. It shouldn't be necessary on your own machine. >My compile commands, that work are: >cobol -dy -shared -WC,"BINARY(BYTE)" -o libMYSUB1.so MYSUB1.cbl >cobol -dy -shared -WC,"BINARY(BYTE)" -o libMYSUB2.so MYSUB2.cbl >cobol -M -dy -WC,"BINARY(BYTE),DLOAD" -o MYMAIN -L./ -lMYSUB1 -lMYSUB2 >MYMAIN.cbl > >I am able to compile and execute. My simple programs are designed to >allow me to see the functioning of CALL and CANCEL..... > >However the results is NOT exactly what I want. Using -l does not >allow for proper functioning of the CANCEL verb (see pg 77 of user's >guide). Once a subprogram is loaded with a CALL statement, it remains >in memory regardless of CANCEL statements. The working-storage of the >sub-program is not reinitialized upon a second CALL. I answered Richard before reading this reply. Failure of the CANCEL means Fujitsu figured out the library (.so) had not been dynamically loaded, so did not issue a dlclose(). If you want the program initialized every time, use the INITIAL clause on PROGRAM-ID. See my comments to Richard about the disadvantage of hundreds of little libraries.
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: help with tables Next: S0C4 x'4' abend while reading VSAM KSDS file |