From: Richard on
On Feb 1, 4:23 pm, Robert <n...(a)e.mail> wrote:
> On Thu, 31 Jan 2008 11:47:51 -0800 (PST), Richard <rip...(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]

As usual you think that pointing out where you are wrong and
correcting you is an 'insult'.

> >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.

I have no idea what "mainframers and others from the Old School" may
understand, but if the library is loaded when the application starts
then it is not 'dynamic' as was required by Charles.


> 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.

The CALL can check whether it has failed to find the program with an
ON EXCEPTION, or it can be checked for in other ways, there is no need
for the program to abort.

If there is a requirement to ensure that the libraries do exist at
start of run, then yes, you can statically link them, or do an initial
CALL, but that was _NOT_ the stated requirement, you were, as usual,
answering the wrong question.

The requirement is to have dynamic loading.

> It also allows useful diagnostics to be run before
> starting a long batch job.

Unfortuanatly, as you completely failed to notice, it also makes the
program not work correctly and thus _REQUIRING_ disgnostics.

As Charles discovered, when you link in a shared library it prevents
the CANCEL working. I tested this by taking the working set of
Charles's programs and adding a -l to the ld. The test then showed
the CANCEL did not work. Removing the -l and retesting showed the CALL
and CANCEL to work correctly.

Your advice was BAD, the results of following your advice was WRONG.

When will you accept that you completely fail to understand dynamic
loading ?


> 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.

There are some _VERY_GOOD_ reasons why dynamic loading is used. The
fact that you don't understand them does not mean they are not
entirely valid.


> In addition to the advantages given above,

Which are irrelevant.

> one
> specific to Cobol is non-proliferation of program files, which I'll explain below.

Which is also completely irrelevant.


> 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).

Yeah, yeah, _WE_ know all that.


> 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 am not sure why you think that is a 'problem'.

It is not a problem to me at all, nor to any of my clients.

> I find that ugly and, from a deployment point of view, clunky and amateurish.

You finding something as 'ugly' is probably a good reason to use it.


> It would be cleaner to
> package his hundreds of programs into one or a few libraries that are linked to the main
> executable.

Only if you fail to understand why dynamic loading is used and the
advantages it bestows on the system.


> How many third-party apps have you seen that came with hundreds of libraries or dlls?

Several, many even.

> >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.

Charles results and my testing show that you are WONG once again.

Instead of simply assumnming that what you 'know' is everything that
is possible to know you should actually try testing stuff out.


> 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.

A CANCEL is not just for regaining initial values, it also frees the
memory. But not only that it caters for a fresh copy to be loaded.
Actual dynamic is dynamic. I can put a new version of a program into
the directory, get the main program to CANCEL and CALL and the new
code will be running.


> 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.

Geez, Robert, don't you _EVER_ test anything before spouting out what
will or will not happen ?

I just ran a test here to confirm what _I_ expected to happen based on
a few decades of using actual dynamic loading in Cobol.

What you completely failed to notice is that the _data_area_ is not
part of the library, but is created in the main program run-unit. When
the CANCEL is done the data areas created in the run-unit are dumped,
a subsequent CALL will recreate a new set of data areas regardless of
whether the code area still exists in a loaded library or a new
library has to be loaded.

In fact I just ran another test. I started one program until it
CALLed the subroutine. I then on another console changed the source to
add a display, recompiled and ran a 2nd copy. It loaded a new version
even though the first was still in the middle of the subroutine.
Running through the CANCEL and CALL on that loaded the new routine
exactly as _I_ expected.

Your grasp of this is tenuous at best. Probably this is because you've
never done it the right way.

Instead of prattling on with more and more misinformation based on
guesswork just try doing this and see what _actually_ happens.


> If you want to be hackerish, issue the CANCEL 100 times. Each
> call to dlopen() subtracts 1 from the user count.

Geez, Robert, when you are WRONG you do it in spades. The main program
can only reduce the user count if it is _still_connected_ to the
library. The first CANCEL causes a disconnect and the rest do nothing
at all.

> 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.

With Windows (which is a completely different issue and unrelated to
this topic) there are _two_ problems. The first is that a file cannot
be deleted or overwritten when it is open (Unix with its inode
structure can unlink a file that is open and it will disappear when it
is closed). Thus if a dll is in use, and it remains open, the
replacement must be deferred until it can be guaranteed that it is not
open, such as during a boot.

The second problem is that a dll in memory will be used in preference
to loading from disk. The FreeLibrary may make it disappear from
memory, but that is irrelevant to this topic.

This discussion is going along exactly as every one with you has:

Robert gives WRONG and/or BAD advise.
I point out it is wrong and show results of testing.
Robert reiterates his BAD and WRONG advice and claims he is right.
I point out where it is wrong and why.
Robert claims I am insulting him and (obviously having researched)
write screeds of irrelevant and obvious material that is mostly
unrelated.
I point out where it is irrelevant and wrong and show results of
testing.

From: Richard on
On Feb 1, 4:33 pm, Robert <n...(a)e.mail> wrote:
> On Thu, 31 Jan 2008 09:48:48 -0800 (PST), 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.
>
> -L is used to override the user's LD_LIBRARY_PATH. It shouldn't be necessary on your own
> machine.

Geez, Robert, yet more misinformation. You are _WRONG_ yet again. ld
does _NOT_ follow the LD_LIBRARY_PATH. It follows the LIBPATH. You can
add the current directory to LIBPATH or use the -L _IF_ you want to
link the dynamic libraries statically.

I actually ran a _test_ (you may want to look up what this word might
refer to) by adding the -l MYSUB1 without the -L while having the
LD_LIBRARY_PATH. As I expected it failed, just as Charles reported.



> >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.

The INITIAL clause is _also_ BAD and WRONG advice. The INITIAL clause
means that the subprogram is reset on _EVERY_ CALL. It is not a
substitute for CANCEL.

If you want CANCEL to work then don't do stupid stuff like statically
linking a dynamic library. If you want to statically link then do so
with -c on the compile and -o NAME.o then link that.

> See my comments to Richard about the disadvantage of hundreds of little libraries.

The only 'disadvantage' that you could dream up was an entirely
subjective 'it is ugly' and similar. There are no _actual_
disadvantages and many significant advantages.

From: Robert on
On Thu, 31 Jan 2008 20:41:29 -0800 (PST), Richard <riplin(a)azonic.co.nz> wrote:

>On Feb 1, 4:23 pm, Robert <n...(a)e.mail> wrote:
>> On Thu, 31 Jan 2008 11:47:51 -0800 (PST), Richard <rip...(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]
>
>As usual you think that pointing out where you are wrong and
>correcting you is an 'insult'.

No, I think name calling is insulting.

>> >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.
>
>I have no idea what "mainframers and others from the Old School" may
>understand, but if the library is loaded when the application starts
>then it is not 'dynamic' as was required by Charles.

You are confusing people with the term 'static linking'. Fujitsu's terminology is pretty
good:

static linking Old School, everything in one executable
dynamic program structure Unix style libraries linked with -l
dynamic link structure Cobol style Load On Demand

>> 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.
>
>The CALL can check whether it has failed to find the program with an
>ON EXCEPTION, or it can be checked for in other ways, there is no need
>for the program to abort.

True. How many programs have a graceful fallback? Ok, if called from a menu, they say
'Function not available'. Makes you wonder why they didn't grey it out.

>If there is a requirement to ensure that the libraries do exist at
>start of run, then yes, you can statically link them, or do an initial
>CALL, but that was _NOT_ the stated requirement, you were, as usual,
>answering the wrong question.
>
>The requirement is to have dynamic loading.

Why is Cobol the only language with a pressing need for dynamic linking? Huge bodies of
code written in C and other languages get by without it.

>As Charles discovered, when you link in a shared library it prevents
>the CANCEL working. I tested this by taking the working set of
>Charles's programs and adding a -l to the ld. The test then showed
>the CANCEL did not work. Removing the -l and retesting showed the CALL
>and CANCEL to work correctly.

The NETCobol for Linux User's Guide says the same in Chapter 7.

>> Cobol can, and I believe should, use the normal Unix binding mechanism. There are several
>> advantages and no good reason not to.
>
>There are some _VERY_GOOD_ reasons why dynamic loading is used. The
>fact that you don't understand them does not mean they are not
>entirely valid.

CANCEL was created in the days of limited memory, same as overlays. Cobol dropped overlays
when they were no longer needed. It should have dropped CANCEL at the same time.

>> 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 am not sure why you think that is a 'problem'.
>
>It is not a problem to me at all, nor to any of my clients.

It complicates deployment, makes the system less reliable and slows execution.

>> It would be cleaner to
>> package his hundreds of programs into one or a few libraries that are linked to the main
>> executable.
>
>Only if you fail to understand why dynamic loading is used and the
>advantages it bestows on the system.

The advantage disappeared when we broke the 640K barrier.

>> >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.
>
>Charles results and my testing show that you are WONG once again.

I said IF Cobol issues a dlclose(). Fujitsu does not. It could.

>Instead of simply assumnming that what you 'know' is everything that
>is possible to know you should actually try testing stuff out.

Fair enough. If this gets any deeper, I'll install Fujitsu for Linux.

>> 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.
>
>A CANCEL is not just for regaining initial values, it also frees the
>memory. But not only that it caters for a fresh copy to be loaded.
>Actual dynamic is dynamic. I can put a new version of a program into
>the directory, get the main program to CANCEL and CALL and the new
>code will be running.

I reload with four keystrokes: esc, ctrl-P, Enter.

>> 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.
>
>Geez, Robert, don't you _EVER_ test anything before spouting out what
>will or will not happen ?
>
>I just ran a test here to confirm what _I_ expected to happen based on
>a few decades of using actual dynamic loading in Cobol.
>
>What you completely failed to notice is that the _data_area_ is not
>part of the library, but is created in the main program run-unit. When
>the CANCEL is done the data areas created in the run-unit are dumped,
>a subsequent CALL will recreate a new set of data areas regardless of
>whether the code area still exists in a loaded library or a new
>library has to be loaded.

That's not under the control of Unix. If Fujitsu does that, why doesn't it free the data
area of a dynamic program structure the same way?

>In fact I just ran another test. I started one program until it
>CALLed the subroutine. I then on another console changed the source to
>add a display, recompiled and ran a 2nd copy. It loaded a new version
>even though the first was still in the middle of the subroutine.
>Running through the CANCEL and CALL on that loaded the new routine
>exactly as _I_ expected.

That's not normal Unix behavior. I'd need hands-on to figure out why it loaded a second
copy.

>Your grasp of this is tenuous at best. Probably this is because you've
>never done it the right way.

My grasp is based on writing large make files and knowledge of Unix internals.

>> If you want to be hackerish, issue the CANCEL 100 times. Each
>> call to dlopen() subtracts 1 from the user count.
>
>Geez, Robert, when you are WRONG you do it in spades. The main program
>can only reduce the user count if it is _still_connected_ to the
>library. The first CANCEL causes a disconnect and the rest do nothing
>at all.

Unix doesn't know who is connected to a shared library. All it knows is the user count.
Perhaps Fujitsu ignores CANCEL on a program that doesn't have a data segment.

>The second problem is that a dll in memory will be used in preference
>to loading from disk. The FreeLibrary may make it disappear from
>memory, but that is irrelevant to this topic.

Not if the dll is 'bound'.

From: Robert on
On Thu, 31 Jan 2008 21:02:58 -0800 (PST), Richard <riplin(a)azonic.co.nz> wrote:

>On Feb 1, 4:33 pm, Robert <n...(a)e.mail> wrote:
>> On Thu, 31 Jan 2008 09:48:48 -0800 (PST), 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.
>>
>> -L is used to override the user's LD_LIBRARY_PATH. It shouldn't be necessary on your own
>> machine.
>
>Geez, Robert, yet more misinformation. You are _WRONG_ yet again. ld
>does _NOT_ follow the LD_LIBRARY_PATH. It follows the LIBPATH. You can
>add the current directory to LIBPATH or use the -L _IF_ you want to
>link the dynamic libraries statically.
>
>I actually ran a _test_ (you may want to look up what this word might
>refer to) by adding the -l MYSUB1 without the -L while having the
>LD_LIBRARY_PATH. As I expected it failed, just as Charles reported.

In the bad old days, each flavor of Unix had its own name for the library path searched by
ld and dlopen. AIX used LIBPATH (same as z/OS), HPUX used SHLIB_PATH, OS X used
DYLD_LIBRARY_PATH.

In the late '90s POSIX became the Unix standard. The POSIX name, LD_LIBRARY_PATH, works
on all versions of Unix.

For badkward compatibility, the various Unixen merge their old name with LD_LIBRARY_PATH,
eliminating duplicates, and use the result.

If your test failed, you ran it on an obsolete AIX. Charles reported that LD_LIBRARY_PATH
worked for him.

>> >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.
>
>The INITIAL clause is _also_ BAD and WRONG advice. The INITIAL clause
>means that the subprogram is reset on _EVERY_ CALL. It is not a
>substitute for CANCEL.
>
>If you want CANCEL to work then don't do stupid stuff like statically
>linking a dynamic library.

It's not a static link; it's a dynamic program structure.

>If you want to statically link then do so
>with -c on the compile and -o NAME.o then link that.

That would be turning the clock back 20 years. Some vendors, such as Micro Focus, have
dropped support for static linking.

>> See my comments to Richard about the disadvantage of hundreds of little libraries.
>
>The only 'disadvantage' that you could dream up was an entirely
>subjective 'it is ugly' and similar. There are no _actual_
>disadvantages and many significant advantages.

User memory management makes it easy to return to MS-DOS. Is that the advantage?
From: Richard on
On Feb 1, 7:49 pm, Robert <n...(a)e.mail> wrote:
> On Thu, 31 Jan 2008 20:41:29 -0800 (PST), Richard <rip...(a)azonic.co.nz> wrote:
> >On Feb 1, 4:23 pm, Robert <n...(a)e.mail> wrote:
> >> On Thu, 31 Jan 2008 11:47:51 -0800 (PST), Richard <rip...(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]
>
> >As usual you think that pointing out where you are wrong and
> >correcting you is an 'insult'.
>
> No, I think name calling is insulting.
>
> >> >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.
>
> >I have no idea what "mainframers and others from the Old School" may
> >understand, but if the library is loaded when the application starts
> >then it is not 'dynamic' as was required by Charles.
>
> You are confusing people with the term 'static linking'.

You may be confused, even though you used the term yourself, but what
evidence do you have that anuone else is ?

> Fujitsu's terminology is pretty
> good:

> static linking Old School, everything in one executable

Not 'Old School' at all. Old School would be trying to fit everything
in 640Kb, or even 64Kb of CP/M.

> dynamic program structure Unix style libraries linked with -l

And the objects are loaded (statically) at start up time, though the
CALLs are not necessarily linked to the routines.

> dynamic link structure Cobol style Load On Demand

Exactly, they are _loaded_ dynamically. The requirement was stated as
being the last: "dynamic linkage" which does dynamic loading. You
should have noticed that the DLOAD directive was used and thus the -l
was inappropriate (see table in manual).


> >> 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.
>
> >The CALL can check whether it has failed to find the program with an
> >ON EXCEPTION, or it can be checked for in other ways, there is no need
> >for the program to abort.
>
> True. How many programs have a graceful fallback? Ok, if called from a menu, they say
> 'Function not available'.

It would seem to me that Charles' programs may well form an
interactive menu driven application. Gracefull fallback is what these
systems should do.

> Makes you wonder why they didn't grey it out.

Perhaps because that would require searching the disk every time the
menu is displayed.

> >If there is a requirement to ensure that the libraries do exist at
> >start of run, then yes, you can statically link them, or do an initial
> >CALL, but that was _NOT_ the stated requirement, you were, as usual,
> >answering the wrong question.
>
> >The requirement is to have dynamic loading.
>
> Why is Cobol the only language with a pressing need for dynamic linking? Huge bodies of
> code written in C and other languages get by without it.

Why do you think that "Cobol is the only language" ? I use several
that also do dynamic loading. I have even done dynamic loading in C.
You seem rather limited.


> >As Charles discovered, when you link in a shared library it prevents
> >the CANCEL working. I tested this by taking the working set of
> >Charles's programs and adding a -l to the ld. The test then showed
> >the CANCEL did not work. Removing the -l and retesting showed the CALL
> >and CANCEL to work correctly.
>
> The NETCobol for Linux User's Guide says the same in Chapter 7.

I am pleased to see that you are doing some research even if it is
rather belated.


> >> Cobol can, and I believe should, use the normal Unix binding mechanism. There are several
> >> advantages and no good reason not to.
>
> >There are some _VERY_GOOD_ reasons why dynamic loading is used. The
> >fact that you don't understand them does not mean they are not
> >entirely valid.
>
> CANCEL was created in the days of limited memory, same as overlays. Cobol dropped overlays
> when they were no longer needed. It should have dropped CANCEL at the same time.

Many would disagree with you.

> >> 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 am not sure why you think that is a 'problem'.
>
> >It is not a problem to me at all, nor to any of my clients.
>
> It complicates deployment, makes the system less reliable and slows execution.

What _evidence_, other than 'researching your keyboard', can you
provide for these unsupported assertions. Certainly a dynamic load
takes a few milliseconds when a menu item is selected, but in what way
would it be 'less reliable' ?

Actually, to those that use this, it _simplifies_ deployment,
especially in bespoke systems where I operate. If a single program
requires changes then only that file is tested and redistributed. In
any rational development all deployments would be fully tested. If you
link several programs into one library the all those in the library
need to be retested. If they are all linked to one executable then
everything needs to be retested.

And the CALL dataname feature is invaluable as it means that the menu
program can use a data file to define what is available in a
particular application, or even to the particular user, and this can
be extended by changing the data file (and issuing the programs)
without changing the menu program at all.

'One off' or special programs can be deployed individually and
executed with the application framework by typing their name into the
menu program (given that the user has adequate permissions), there is
no need to redeploy the whole system.

> >> It would be cleaner to
> >> package his hundreds of programs into one or a few libraries that are linked to the main
> >> executable.
>
> >Only if you fail to understand why dynamic loading is used and the
> >advantages it bestows on the system.
>
> The advantage disappeared when we broke the 640K barrier.

Showing once again that you fail to understand why dynamic loading is
used and the
advantages it bestows on the system.


> >> >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.
>
> >Charles results and my testing show that you are WONG once again.
>
> I said IF Cobol issues a dlclose(). Fujitsu does not. It could.

So, you would agree that your 'Wrong' was Wrong then. Charles and I
both described the results of testing. You said this was 'wrong' on
the basis that it _could_ have been different if Fujitsu did it
differently, but they don't.

You would have to agree that are testing results are 'RIGHT' then.


> >Instead of simply assumnming that what you 'know' is everything that
> >is possible to know you should actually try testing stuff out.
>
> Fair enough. If this gets any deeper, I'll install Fujitsu for Linux.

Wow, forcing you into a situation where you actually test something.
You must have gone past repeating the misinformation more than 3 times
then.


> >> 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.
>
> >A CANCEL is not just for regaining initial values, it also frees the
> >memory. But not only that it caters for a fresh copy to be loaded.
> >Actual dynamic is dynamic. I can put a new version of a program into
> >the directory, get the main program to CANCEL and CALL and the new
> >code will be running.
>
> I reload with four keystrokes: esc, ctrl-P, Enter.

But that (presumably) reloads the whole application. How inefficient.


> >> 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.
>
> >Geez, Robert, don't you _EVER_ test anything before spouting out what
> >will or will not happen ?
>
> >I just ran a test here to confirm what _I_ expected to happen based on
> >a few decades of using actual dynamic loading in Cobol.
>
> >What you completely failed to notice is that the _data_area_ is not
> >part of the library, but is created in the main program run-unit. When
> >the CANCEL is done the data areas created in the run-unit are dumped,
> >a subsequent CALL will recreate a new set of data areas regardless of
> >whether the code area still exists in a loaded library or a new
> >library has to be loaded.
>
> That's not under the control of Unix. If Fujitsu does that, why doesn't it free the data
> area of a dynamic program structure the same way?

Ask them.

> >In fact I just ran another test. I started one program until it
> >CALLed the subroutine. I then on another console changed the source to
> >add a display, recompiled and ran a 2nd copy. It loaded a new version
> >even though the first was still in the middle of the subroutine.
> >Running through the CANCEL and CALL on that loaded the new routine
> >exactly as _I_ expected.
>
> That's not normal Unix behavior. I'd need hands-on to figure out why it loaded a second
> copy.

Exactly. Your guesses were just misinformation.

> >Your grasp of this is tenuous at best. Probably this is because you've
> >never done it the right way.
>
> My grasp is based on writing large make files and knowledge of Unix internals.

Which didn't address the area under discussion at all it seems.


> >> If you want to be hackerish, issue the CANCEL 100 times. Each
> >> call to dlopen() subtracts 1 from the user count.
>
> >Geez, Robert, when you are WRONG you do it in spades. The main program
> >can only reduce the user count if it is _still_connected_ to the
> >library. The first CANCEL causes a disconnect and the rest do nothing
> >at all.
>
> Unix doesn't know who is connected to a shared library. All it knows is the user count.

What you also failed to notice that you got WRONG with your assertion
is that it isn't "dlopen(name)" that "subtracts 1", that would add 1.
It is dlclose(handle) that would subtract and the handle would be
destroyed by the dlclose() (ie it would be disconnected) and a
subsequent dlclose() would be with an invalid handle.

As I say, you get some things wrong in spades.


> Perhaps Fujitsu ignores CANCEL on a program that doesn't have a data segment.
>
> >The second problem is that a dll in memory will be used in preference
> >to loading from disk. The FreeLibrary may make it disappear from
> >memory, but that is irrelevant to this topic.
>
> Not if the dll is 'bound'.