For Programmers: Free Programming Magazines  


Home > Archive > Cobol > March 2006 > Problem Calling "kill" in threaded 64-bit MF Server Express 4.0 SP2









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Problem Calling "kill" in threaded 64-bit MF Server Express 4.0 SP2
Chris

2006-03-29, 3:55 am

Hi all.

Again - I come to the group hoping to find some expertise.

Platform: HP-UX 11i (11.11)
COBOL: MF Server Express 4.0 SP2 (Fixpack40.04_46)


I have the following snippet of code:


77 int pic s9(09) comp-5 is typedef.
77 u-int pic 9(9) comp-5 is typedef.

77 errno u-int external.


01 my-pid int.
01 rc int.


MOVE <some value> TO my-pid

CALL "kill" USING
BY VALUE my-pid
BY VALUE 0
RETURNING
rc
END-CALL



Now for the fun part. In a non-threaded runtime (rts64), when I move
the value of a PID that I am not the owner of to my-pid, I get the
following results:

rc=-1
errno=1

errno=1 indicates the UNIX EPERM error, which is what I expect. The
process exists and I do not have permissions on it.


In the threaded (rts64_t) runtime, when I execute the same snip of
code, I get the following results:

rc=-1
errno=25

What's even more peculiar, is that when I animate (anim64_t) the
threaded version, I get these results:

rc=-1
errno=2


What is it about threading vs. non-threading that would cause my call
to get all out of whack?

Am I missing something obvious here? I am new to the concept of using
"threaded" runtimes, but it is the recommended solution for working
with Oracle, but I wouldn't have expected this type of behavioral
change.

The MF Support folks suggested compiling with the -D_PSTAT64 flag, but
that did not correct the situation - so I am looking to the vast pool
of knowledge here for assistance.

Thanks in advance,
Chris

Chris

2006-03-29, 6:55 pm

OK - got the answer - wanted to post to the group.

Apparently, while this works in non-threaded mode - it won't work this
way in threaded mode.

You need to actually introduce a call to the appropriate system routine
to return the address of the last errno generated. On HP - this is
"__errno", on AIX, it's "_Errno" and on Sun it's "___errno".

So after you check rc = -1, you need to add this code:

CALL OS-ERRNO-ADDR
RETURNING OS-ERRNO-PTR
END-CALL

SET ADDRESS OF OS-ERRNO TO OS-ERRNO-PTR

DISPLAY OS-ERRNO


Now you will get the appropriate results.




Chris wrote:
> Hi all.
>
> Again - I come to the group hoping to find some expertise.
>
> Platform: HP-UX 11i (11.11)
> COBOL: MF Server Express 4.0 SP2 (Fixpack40.04_46)
>
>
> I have the following snippet of code:
>
>
> 77 int pic s9(09) comp-5 is typedef.
> 77 u-int pic 9(9) comp-5 is typedef.
>
> 77 errno u-int external.
>
>
> 01 my-pid int.
> 01 rc int.
>
>
> MOVE <some value> TO my-pid
>
> CALL "kill" USING
> BY VALUE my-pid
> BY VALUE 0
> RETURNING
> rc
> END-CALL
>
>
>
> Now for the fun part. In a non-threaded runtime (rts64), when I move
> the value of a PID that I am not the owner of to my-pid, I get the
> following results:
>
> rc=-1
> errno=1
>
> errno=1 indicates the UNIX EPERM error, which is what I expect. The
> process exists and I do not have permissions on it.
>
>
> In the threaded (rts64_t) runtime, when I execute the same snip of
> code, I get the following results:
>
> rc=-1
> errno=25
>
> What's even more peculiar, is that when I animate (anim64_t) the
> threaded version, I get these results:
>
> rc=-1
> errno=2
>
>
> What is it about threading vs. non-threading that would cause my call
> to get all out of whack?
>
> Am I missing something obvious here? I am new to the concept of using
> "threaded" runtimes, but it is the recommended solution for working
> with Oracle, but I wouldn't have expected this type of behavioral
> change.
>
> The MF Support folks suggested compiling with the -D_PSTAT64 flag, but
> that did not correct the situation - so I am looking to the vast pool
> of knowledge here for assistance.
>
> Thanks in advance,
> Chris


Michael Wojcik

2006-03-29, 6:55 pm


In article <1143604712.201547.254640@u72g2000cwu.googlegroups.com>, "Chris" <ctaliercio@yahoo.com> writes:
>
> I have the following snippet of code:
>
>
> 77 int pic s9(09) comp-5 is typedef.
> 77 u-int pic 9(9) comp-5 is typedef.
>
> 77 errno u-int external.
>
>
> 01 my-pid int.
> 01 rc int.
>
>
> MOVE <some value> TO my-pid
>
> CALL "kill" USING
> BY VALUE my-pid
> BY VALUE 0
> RETURNING
> rc
> END-CALL
>
>
>
> Now for the fun part. In a non-threaded runtime (rts64), when I move
> the value of a PID that I am not the owner of to my-pid, I get the
> following results:
>
> rc=-1
> errno=1
>
> errno=1 indicates the UNIX EPERM error, which is what I expect. The
> process exists and I do not have permissions on it.
>
>
> In the threaded (rts64_t) runtime, when I execute the same snip of
> code, I get the following results:
>
> rc=-1
> errno=25


That's because in a threaded environment, errno is not a single global
integer. Each thread needs its own errno to preserve the errno
semantics.

Since ISO C requires that errno be an expression that evaluates to an
int lvalue (that is, an object of int type that you can modify), the
usual (perhaps only) approach in Unix multithreaded C implementations
is to make errno a macro that expands to a dereferencing of a pointer
returned by a function call. If you track down the appropriate header
file, you'll probably see something like this:

extern int *_thread_errno(void);
#define errno (*_thread_errno());

So when you refer to errno in a multithreaded C program in this
implementation, what actually happens is a function call that returns
a pointer to the errno area for the current thread; then that pointer
is dereferenced so you can retrieve and set the value contained in
that area.

System calls which set errno, in turn, have to use the same
mechanism, since they're used by multithreaded C programs.

There may still be an external variable named "errno", but its value
doesn't mean anything. It may be garbage, or it may contain the most
recent errno value set for any thread; that depends on the implementa-
tion, and you can't rely on it.

I'm not sure there's a good, simple method to get the per-thread
errno in a multithreaded COBOL program. One approach would be to
write a small C routine to return it:

#include <errno.h>
int geterrno(void) {return errno;}

and compile that into a CSO:

$ cob -t -z -CC -D_REENTRANT geterrno.c

and call it to get errno in your COBOL program:

identification division.
program-id. testerrno.

data division.
working-storage section.
77 my-errno pic s9(9) comp-5.
77 rc pic s9(9) comp-5.

procedure division.

call "kill" using by value 1 0 returning rc.
call "geterrno" returning my-errno.
exhibit rc my-errno.
stop run.

To test:

$ cob -t -i testerrno.cbl
$ rts64_t testerrno
-0000000001 +0000000001

I just tried this on an HP-UX 11i system, and it seems to work fine.
Note that it's crucial that your geterrno.c program be compiled in
the same mode (single- or multithreaded) as your COBOL program for
this to work, so you might want single- and multithreaded versions
of it (with different names). Also, the way to get a C program
compiled for multithreading depends on the implementation - the
command line I have above works with the HP-UX ANSI C compiler.

(Also, errno is an int, not an unsigned int. If you happen to be on
a 64-bit platform where int is 64 bits, it'll be a 64-bit int. The
first parameter to the kill system call is a pid_t, which is an
implementation-dependent type; it too could be a 64-bit integer type.
On HP-UX 11i, though, they're both 32-bit integers, and signedness
won't matter.)

--
Michael Wojcik michael.wojcik@microfocus.com

Auden often writes like Disney. Like Disney, he knows the shape of beasts --
(& incidently he, too, might have a company of artists producing his lines) --
unlike Lawrence, he does not know what shapes or motivates these beasts.
-- Dylan Thomas
Chris

2006-03-30, 6:55 pm

Thanks Michael.

The reasoning behind the behvaior definitely makes sense. Being new to
the threaded environment, I expect there will be more issue like this
for me to deal with - but thankfully so far things have gone well.

The sample code I posted above works perfectly, and I believe it
reflects exactly what you were going for. What do you think of it?


BTW - for all of those folks who post here doubting the fact that
Michael does in fact work for Micro Focus :) - I can vouch for him. He
is most definitely a MF employee, and I had the pleasure of meeting him
at the Developer's Forum in Denver a couple of ws ago.


Chris



Michael Wojcik wrote:
> In article <1143604712.201547.254640@u72g2000cwu.googlegroups.com>, "Chris" <ctaliercio@yahoo.com> writes:
>
> That's because in a threaded environment, errno is not a single global
> integer. Each thread needs its own errno to preserve the errno
> semantics.
>
> Since ISO C requires that errno be an expression that evaluates to an
> int lvalue (that is, an object of int type that you can modify), the
> usual (perhaps only) approach in Unix multithreaded C implementations
> is to make errno a macro that expands to a dereferencing of a pointer
> returned by a function call. If you track down the appropriate header
> file, you'll probably see something like this:
>
> extern int *_thread_errno(void);
> #define errno (*_thread_errno());
>
> So when you refer to errno in a multithreaded C program in this
> implementation, what actually happens is a function call that returns
> a pointer to the errno area for the current thread; then that pointer
> is dereferenced so you can retrieve and set the value contained in
> that area.
>
> System calls which set errno, in turn, have to use the same
> mechanism, since they're used by multithreaded C programs.
>
> There may still be an external variable named "errno", but its value
> doesn't mean anything. It may be garbage, or it may contain the most
> recent errno value set for any thread; that depends on the implementa-
> tion, and you can't rely on it.
>
> I'm not sure there's a good, simple method to get the per-thread
> errno in a multithreaded COBOL program. One approach would be to
> write a small C routine to return it:
>
> #include <errno.h>
> int geterrno(void) {return errno;}
>
> and compile that into a CSO:
>
> $ cob -t -z -CC -D_REENTRANT geterrno.c
>
> and call it to get errno in your COBOL program:
>
> identification division.
> program-id. testerrno.
>
> data division.
> working-storage section.
> 77 my-errno pic s9(9) comp-5.
> 77 rc pic s9(9) comp-5.
>
> procedure division.
>
> call "kill" using by value 1 0 returning rc.
> call "geterrno" returning my-errno.
> exhibit rc my-errno.
> stop run.
>
> To test:
>
> $ cob -t -i testerrno.cbl
> $ rts64_t testerrno
> -0000000001 +0000000001
>
> I just tried this on an HP-UX 11i system, and it seems to work fine.
> Note that it's crucial that your geterrno.c program be compiled in
> the same mode (single- or multithreaded) as your COBOL program for
> this to work, so you might want single- and multithreaded versions
> of it (with different names). Also, the way to get a C program
> compiled for multithreading depends on the implementation - the
> command line I have above works with the HP-UX ANSI C compiler.
>
> (Also, errno is an int, not an unsigned int. If you happen to be on
> a 64-bit platform where int is 64 bits, it'll be a 64-bit int. The
> first parameter to the kill system call is a pid_t, which is an
> implementation-dependent type; it too could be a 64-bit integer type.
> On HP-UX 11i, though, they're both 32-bit integers, and signedness
> won't matter.)
>
> --
> Michael Wojcik michael.wojcik@microfocus.com
>
> Auden often writes like Disney. Like Disney, he knows the shape of beasts --
> (& incidently he, too, might have a company of artists producing his lines) --
> unlike Lawrence, he does not know what shapes or motivates these beasts.
> -- Dylan Thomas


Chris

2006-03-30, 6:55 pm

Thanks Michael.

The reasoning behind the behvaior definitely makes sense. Being new to
the threaded environment, I expect there will be more issue like this
for me to deal with - but thankfully so far things have gone well.

The sample code I posted above works perfectly, and I believe it
reflects exactly what you were going for. What do you think of it?


BTW - for all of those folks who post here doubting the fact that
Michael does in fact work for Micro Focus :) - I can vouch for him. He
is most definitely a MF employee, and I had the pleasure of meeting him
at the Developer's Forum in Denver a couple of ws ago.


Chris



Michael Wojcik wrote:
> In article <1143604712.201547.254640@u72g2000cwu.googlegroups.com>, "Chris" <ctaliercio@yahoo.com> writes:
>
> That's because in a threaded environment, errno is not a single global
> integer. Each thread needs its own errno to preserve the errno
> semantics.
>
> Since ISO C requires that errno be an expression that evaluates to an
> int lvalue (that is, an object of int type that you can modify), the
> usual (perhaps only) approach in Unix multithreaded C implementations
> is to make errno a macro that expands to a dereferencing of a pointer
> returned by a function call. If you track down the appropriate header
> file, you'll probably see something like this:
>
> extern int *_thread_errno(void);
> #define errno (*_thread_errno());
>
> So when you refer to errno in a multithreaded C program in this
> implementation, what actually happens is a function call that returns
> a pointer to the errno area for the current thread; then that pointer
> is dereferenced so you can retrieve and set the value contained in
> that area.
>
> System calls which set errno, in turn, have to use the same
> mechanism, since they're used by multithreaded C programs.
>
> There may still be an external variable named "errno", but its value
> doesn't mean anything. It may be garbage, or it may contain the most
> recent errno value set for any thread; that depends on the implementa-
> tion, and you can't rely on it.
>
> I'm not sure there's a good, simple method to get the per-thread
> errno in a multithreaded COBOL program. One approach would be to
> write a small C routine to return it:
>
> #include <errno.h>
> int geterrno(void) {return errno;}
>
> and compile that into a CSO:
>
> $ cob -t -z -CC -D_REENTRANT geterrno.c
>
> and call it to get errno in your COBOL program:
>
> identification division.
> program-id. testerrno.
>
> data division.
> working-storage section.
> 77 my-errno pic s9(9) comp-5.
> 77 rc pic s9(9) comp-5.
>
> procedure division.
>
> call "kill" using by value 1 0 returning rc.
> call "geterrno" returning my-errno.
> exhibit rc my-errno.
> stop run.
>
> To test:
>
> $ cob -t -i testerrno.cbl
> $ rts64_t testerrno
> -0000000001 +0000000001
>
> I just tried this on an HP-UX 11i system, and it seems to work fine.
> Note that it's crucial that your geterrno.c program be compiled in
> the same mode (single- or multithreaded) as your COBOL program for
> this to work, so you might want single- and multithreaded versions
> of it (with different names). Also, the way to get a C program
> compiled for multithreading depends on the implementation - the
> command line I have above works with the HP-UX ANSI C compiler.
>
> (Also, errno is an int, not an unsigned int. If you happen to be on
> a 64-bit platform where int is 64 bits, it'll be a 64-bit int. The
> first parameter to the kill system call is a pid_t, which is an
> implementation-dependent type; it too could be a 64-bit integer type.
> On HP-UX 11i, though, they're both 32-bit integers, and signedness
> won't matter.)
>
> --
> Michael Wojcik michael.wojcik@microfocus.com
>
> Auden often writes like Disney. Like Disney, he knows the shape of beasts --
> (& incidently he, too, might have a company of artists producing his lines) --
> unlike Lawrence, he does not know what shapes or motivates these beasts.
> -- Dylan Thomas


Michael Wojcik

2006-03-30, 6:55 pm


In article <1143729276.993446.155600@j33g2000cwa.googlegroups.com>, "Chris" <ctaliercio@yahoo.com> writes:
> Thanks Michael.
>
> The reasoning behind the behvaior definitely makes sense. Being new to
> the threaded environment, I expect there will be more issue like this
> for me to deal with - but thankfully so far things have gone well.
>
> The sample code I posted above works perfectly, and I believe it
> reflects exactly what you were going for. What do you think of it?


It looks fine to me. I used a CSO written in C just to avoid having
to know the name of the system function that returns the errno
pointer ("__errno" or whatever it may be). If you only have a few
platforms to worry about, you can just hard-code it; it's unlikely
to change.

> BTW - for all of those folks who post here doubting the fact that
> Michael does in fact work for Micro Focus :) - I can vouch for him. He
> is most definitely a MF employee, and I had the pleasure of meeting him
> at the Developer's Forum in Denver a couple of ws ago.


Thanks. Yes, I'm still with MF, despite the albatross-wrangling.

--
Michael Wojcik michael.wojcik@microfocus.com

[After the lynching of George "Big Nose" Parrot, Dr. John] Osborne
had the skin tanned and made into a pair of shoes and a medical bag.
Osborne, who became governor, frequently wore the shoes.
-- _Lincoln [Nebraska] Journal Star_
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com