Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Microport Unix -- Large Model Problems

177 views
Skip to first unread message

Ron Flax

unread,
Oct 29, 1986, 11:14:11 AM10/29/86
to
Has anyone else out there been experiencing problems with porting
programs to Microport Unix V/AT that fall into the large model category?
It seems that most everything I port (try to port?) has pointer
alignment problems, as indicated by lint, or just core dumps with a
segmentation violation at strange places in the code, like on a strlen()
call?

Sdb seems to indicate a memory fault as the culprit and I think that
most of the problems are pointer related since an 'int' ain't
necessarily an 'int' (ie. 16 bits in small model, 32 bits in large
model). Does anyone have any words of wisdom as to how one might go
about fixing pointer alignment problems without too much pain?

One other unrelated problem I have with Microport Unix is that for one
reason or another the system seems to run for a while then when it
decides its had enough it just plain goes south. It appears to be a
deadlock situation since terminals that had active sessions going
continue to echo keystroke even though it doesn't respond to them and
non-active sessions (ie. getty's running) do NOT echo keystrokes. This
obviously quite annoying as you might imagine... One other thing that
is interesting is that I know of two other sites with the exact same
problem on different hardware, but Microport claims they have never
heard of it? Has anyone else seen this behavior? Incidentally I was
running SCO Xenix V successfully for about 6 months prior to getting
Microport Unix. Microport are you listening 8-)

--
r...@vsedev.VSE.COM (Ron Flax)
UUCP: ..!seismo!vsedev!ron
ARPA: vsedev.VSE.COM!r...@seismo.CSS.GOV

Larry Campbell

unread,
Oct 30, 1986, 7:16:00 PM10/30/86
to
In article <1...@vsedev.VSE.COM> r...@vsedev.VSE.COM (Ron Flax) writes:
>Has anyone else out there been experiencing problems with porting
>programs to Microport Unix V/AT that fall into the large model category?
>It seems that most everything I port (try to port?) has pointer
>alignment problems, as indicated by lint, or just core dumps with a
>segmentation violation at strange places in the code, like on a strlen()
>call?
>
>Sdb seems to indicate a memory fault as the culprit and I think that
>most of the problems are pointer related since an 'int' ain't
>necessarily an 'int' (ie. 16 bits in small model, 32 bits in large
>model). Does anyone have any words of wisdom as to how one might go
>about fixing pointer alignment problems without too much pain?

The simplest solution is to get your code to pass through lint without
complaints. The most common problem I've found (especially from code
written on 68Ks and VAXen) is for people to not bother declaring pointer
valued objects:

char *p;

p = malloc(128);

oops, malloc is implicitly declared (int), not (char *), so you get
a bogus pointer because ints are 16 bits while pointers are 32 bits.
There should have been an "extern char *malloc();" in there. Lint will
find these for you.
--
Larry Campbell MCI: LCAMPBELL The Boston Software Works, Inc.
UUCP: {alliant,wjh12}!maynard!campbell 120 Fulton Street, Boston MA 02109
ARPA: campbell%maynar...@harvisr.harvard.edu (617) 367-6846

Daniel M. Frank

unread,
Oct 30, 1986, 11:47:28 PM10/30/86
to
In article <1...@vsedev.VSE.COM> r...@vsedev.VSE.COM (Ron Flax) writes:
>Has anyone else out there been experiencing problems with porting
>programs to Microport Unix V/AT that fall into the large model category?
>It seems that most everything I port (try to port?) has pointer
>alignment problems, as indicated by lint, or just core dumps with a
>segmentation violation at strange places in the code, like on a strlen()
>call?

The problems aren't generally with Microport, they are with brain-
damaged, unlinted programs that presume that sizeof int = sizeof *,
or even (in one case), that ALL scalar data types are always the same
size when passed into a function. Let me make a few observations and
suggestions of how to find these problems and what to watch for.

First, the lint you have is probably broken, unless you have the
very latest release (in the last two days). You will find the new,
repaired version of lint (and sdb, actually), very useful.

Suggestion: compile everything with -g. sdb is very useful
for finding obscure portability bugs that lint will not find (usually
because of a VARARGS directive).

Nasties to watch for:

1) Failure to declare functions returning long or *. The compiler
will happily truncate return values to one word, which will
usually cause segmentation violations very quickly, or in
the case of long returns, cause odd program behaviour. malloc()
and time() are favorites, as are string functions returning
pointers.

2) Constructs of the form 1 << n, where n is greater than 15.
Guess what happens? The compiler optimizes this to zeroing
out a register. You want 1L << n. This bug is from compress.c

3) Silly function arguments, usually constants. time(0) is a
popular one. This should be time((long *)0).

4) Very silly constant function arguments in varargs functions,
where lint can't find them. execl and execle are very
popular in this category. Watch for varargs functions
that use null pointers to terminate lists; folks usually
use 0 rather than the proper (char *)0.

5) Varargs functions that use a bunch of integer arguments
to copy the stack. These are all over the place, in
such classics as patch and inews. The method is not
bad, per se, but usually there aren't enough of these
arguments if ints are shorter than pointers. Redeclare
them to be long instead.


(I am posting this generally, rather than mailing back to the poster,
because I would beg, implore, plead, and otherwise abase myself before
authors of C programs posted to the net to try and be sensitive to
some of these problems. Yes, I know the 286 is brain-damaged and all
that, but a bunch of us got `em cheap from this guy in a plaid sport
coat who told us that they were the wave of the future, and now we
can't afford Suns. Watch for assumptions about pointer sizes. Use
the varargs functions and macros provided in System V and BSD instead
of bogus argument lists.)

On the crash problem, try again with Microport support. Stress
that there are not many multi-terminal sites, and that this is occurring
on different hardware. Ask for Henry and use my name.

Good luck!
Dan

--
Dan Frank
uucp: ... uwvax!prairie!dan
arpa: dan%cas...@spool.wisc.edu

Larry Campbell

unread,
Oct 31, 1986, 10:12:49 PM10/31/86
to
In article <2...@prairie.UUCP> d...@prairie.UUCP (Daniel M. Frank) writes:
>...On the crash problem, try again with Microport support. Stress

>that there are not many multi-terminal sites, and that this is occurring
>on different hardware. Ask for Henry and use my name.

Poor Henry... he seems to be awfully busy these days.

- A more-or-less satisifed Microport customer (well, so far the hassles
I've encountered haven't negated the $800 I saved by going Microport
instead of Xenix) who has had the opportunity to chat with Henry on
several occasions...

Daniel M. Frank

unread,
Nov 1, 1986, 1:05:59 PM11/1/86
to
In article <4...@maynard.UUCP> camp...@maynard.UUCP (Larry Campbell) writes:
>Poor Henry... he seems to be awfully busy these days.

Actually, they just hired a roomfull of customer support people to help
him out. He's still busy, though ...

Steve Barber

unread,
Nov 1, 1986, 3:33:11 PM11/1/86
to
In article <4...@maynard.UUCP>, camp...@maynard.UUCP (Larry Campbell) writes:
> In article <1...@vsedev.VSE.COM> r...@vsedev.VSE.COM (Ron Flax) writes:
> >Has anyone else out there been experiencing problems with porting
> >programs to Microport Unix V/AT that fall into the large model category?

> .... The most common problem I've found (especially from code


> written on 68Ks and VAXen) is for people to not bother declaring pointer
> valued objects:

Another common problem is passing NULL as pointer argument. NULL is
#defined as 0, which is 2 bytes. Large model pointers are 4 bytes, so
the stack frame is now basically garbage. The solution is to cast the
NULLs to the appropriate types. Ahhh..Intel..you can never be forgiven
for making us have to worry about memory models (flames by mail only,
please).

--
Steve Barber Rabbit Software Corp.
...!ihnp4!{cbmvax,cuuxb}!hutch!barber ...!psuvax1!burdvax!hutch!barber
(215) 647-0440 7 Great Valley Parkway East Malvern PA 19355

Guy Harris

unread,
Nov 3, 1986, 5:52:16 AM11/3/86
to
> Another common problem is passing NULL as pointer argument. NULL is
> #defined as 0, which is 2 bytes. Large model pointers are 4 bytes, so
> the stack frame is now basically garbage. The solution is to cast the
> NULLs to the appropriate types. Ahhh..Intel..you can never be forgiven
> for making us have to worry about memory models...

Yes, having to worry about memory models may be a pain; however, even if you
didn't have multiple memory models, you'd *still* have to worry about
properly declaring pointer-valued functions and casting null pointers. A
68K implementation might have 16-bit "int"s and 32-bit pointers, or might
return the value of an integral-type-valued function in D0 and the value of
a pointer-valued function in A0. Other implementations might not use an
all-zero bit pattern to represent a null pointer.

I really hope that when the ANSI C standard comes out, compilers start
issuing warnings if you use a function that you haven't already declared, or
if you don't declare the types of the arguments to a function. Yes, this
may inconvenience programmers, but the ones it most inconveniences are the
ones who just don't *care* about data types, and they're the ones who need
the biggest attitude adjustment.
--
Guy Harris
{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
g...@sun.com (or g...@sun.arpa)

Daniel M. Frank

unread,
Nov 3, 1986, 9:32:33 AM11/3/86
to
In article <2...@rabbit1.UUCP> bar...@rabbit1.UUCP (Steve Barber) writes:
>Another common problem is passing NULL as pointer argument. NULL is
>#defined as 0, which is 2 bytes. Large model pointers are 4 bytes, so
>the stack frame is now basically garbage.

This isn't really true. Code in stdio.h for the SV/286 release
checks your memory model, and if it is large, defines NULL to be 0L,
which is the same size as a pointer. It doesn't please lint, so the
best solution is still to cast it as appropriate (like (char *)0),
but you ARE generally safe, as long as you include stdio.h.

Larry Campbell

unread,
Nov 3, 1986, 5:27:00 PM11/3/86
to
In article <3...@prairie.UUCP> d...@prairie.UUCP (Daniel M. Frank) writes:
>In article <2...@rabbit1.UUCP> bar...@rabbit1.UUCP (Steve Barber) writes:
>>Another common problem is passing NULL as pointer argument. NULL is
>>#defined as 0, which is 2 bytes. Large model pointers are 4 bytes, so
>>the stack frame is now basically garbage.
>
> This isn't really true. Code in stdio.h for the SV/286 release
>checks your memory model, and if it is large, defines NULL to be 0L,
>which is the same size as a pointer. It doesn't please lint, so the
>best solution is still to cast it as appropriate (like (char *)0),
>but you ARE generally safe, as long as you include stdio.h.

I wonder why stdio.h doesn't just declare NULL as "(char *) 0", or,
in the brave new world of ANSI X-whatever, "(void *) 0"? This should
do all the right things.

Garry Wiegand

unread,
Nov 4, 1986, 12:53:14 AM11/4/86
to
In a recent article camp...@maynard.UUCP (Larry Campbell) wrote:
>I wonder why stdio.h doesn't just declare NULL as "(char *) 0", or,
>in the brave new world of ANSI X-whatever, "(void *) 0"? This should
>do all the right things.

To get *all* the right things, we use:

#ifdef lint
# define null 0
#else
# define null (char *)0
#endif

since lint doesn't understand that comparing an (int *) variable with a
(char *)0 is legitimate.

garry wiegand (garry%cadi...@cu-arpa.cs.cornell.edu)

Doug Gwyn

unread,
Nov 4, 1986, 12:24:58 PM11/4/86
to
In article <4...@maynard.UUCP> camp...@maynard.UUCP (Larry Campbell) writes:
>I wonder why stdio.h doesn't just declare NULL as "(char *) 0", or,
>in the brave new world of ANSI X-whatever, "(void *) 0"? This should
>do all the right things.

How quickly people forget.

In pre-X3J11 C, no single data type is correct for null pointers in all
contexts, particularly in actual parameters to functions. These should
ALWAYS be written as NULL (or 0) cast to pointers of the correct type.
The best definition of NULL in <stdio.h> for these implementations is the
integer constant 0. Some of us would even argue that that is the only
completely correct choice.

In X3J11 C, if a function prototype is in scope, casting of function
parameters is automatically done, and either (void *)0 or 0 is a
correct definition for NULL.

I recommend that you assume that NULL is defined to be the int constant
0 (even if it isn't on your current system), and always cast it to the
correct pointer type when used as an actual parameter. This practice
will continue to work under X3J11.

Dave Carlson

unread,
Nov 5, 1986, 10:06:56 AM11/5/86
to

A potential problem I smacked into yesterday when porting BSD to SV/AT
is ioctl(2) expects as the third argument:
union { int iarg;
char *cparg;}
Problem is that the union will pull 4 bytes off the stack (in large model)
but the program calling with an integer will only push 2 bytes. Oh S*$&!
I cast my integer args long and everything seems ok but what a pain...

I'm always a bit wary when I have to watch even system calls.
Raver dave

Guy Harris

unread,
Nov 5, 1986, 2:41:45 PM11/5/86
to
> I wonder why stdio.h doesn't just declare NULL as "(char *) 0", or,
> in the brave new world of ANSI X-whatever, "(void *) 0"? This should
> do all the right things.

No, it shouldn't. Passing a "(char *)0" to a routine that expects an "int
*" of some sort is NOT guaranteed to work. If, in fact, you have a machine
on which "char *" is longer than "int *", it is very unlikely to work.

In the brave new world of ANSI X3J11, the right thing to do is to use
function prototypes; if you do this, almost all the 0's will be
automatically converted into null pointers of the appropriate type by the
compiler. (It still won't work for "execl"; if you hack NULL to be
"(char *)0", it fixes *this* case, but it may not work for some routine that
expects an "(int *)0" at the end of its argument list.)

Guy Harris

unread,
Nov 5, 1986, 3:35:44 PM11/5/86
to
> To get *all* the right things, we use:
>
> #ifdef lint
> # define null 0
> #else
> # define null (char *)0
> #endif
>
> since lint doesn't understand that comparing an (int *) variable with a
> (char *)0 is legitimate.

If you use that particular construct, you will get a lot of perfectly
legitimate "lint" complaints about argument mismatches when you pass a
"null" to a routine that expects a pointer of some sort. Since, given the
rationale for this construct, you presumably want to keep "lint" as quiet as
possible, you presumably then cast "null" to the appropriate type. Given
that, what does the non-"lint" arm of the conditional buy you, other than
fixing up a few calls to things like "execl", which are easy enough to fix
manually with casts?

tony mason

unread,
Nov 5, 1986, 9:30:32 PM11/5/86
to
In article <1...@vsedev.VSE.COM> r...@vsedev.VSE.COM (Ron Flax) writes:
>One other unrelated problem I have with Microport Unix is that for one
>reason or another the system seems to run for a while then when it
>decides its had enough it just plain goes south. It appears to be a
>deadlock situation since terminals that had active sessions going
>continue to echo keystroke even though it doesn't respond to them and
>non-active sessions (ie. getty's running) do NOT echo keystrokes. This
>obviously quite annoying as you might imagine... One other thing that
>is interesting is that I know of two other sites with the exact same
>problem on different hardware, but Microport claims they have never
>heard of it? Has anyone else seen this behavior? Incidentally I was
>running SCO Xenix V successfully for about 6 months prior to getting
>Microport Unix. Microport are you listening 8-)
>

While running with SCO Xenix V all spring, we found that it would
periodically do EXACTLY what you are describing. It made no difference what
machine we used (IBM AT, SPERRY IT, even ALTOS 2086) it would die. After
much in-depth research, and discussion with SCO's technical support
(overworked, harried people it often took a week just to get to talk to) it
turns out that it isn't too hard to get this problem to occur - just write a
large model program on the 80286 that uses sbrk() (and is returning large
pointers) and doesn't de-allocate at the end of the program (after all, why
do that? The system takes care of it right?) this will lead to death.
Symptoms are:

1. Terminals still echo characters
2. Disk activity periodically (sync?)
3. NOTHING can be done (except a reset) to get it back.

This is the infamous LARGE MODEL DEATH. I was told by SCO that they had no
fix for it, and that their technical engineers were stumped (something like,
five of the last five "fixes" in house had failed to work.)

Naturally, we tested this out on other machines, and yes, it occurs on them
all. (This was disasterous because the product was using INFORMIX - which
did have some large model pieces).

Perhaps this is what you are experiencing (if not, it is an AMAZING
coincidence).

tony mason

unread,
Nov 5, 1986, 9:49:53 PM11/5/86
to
In article <4...@maynard.UUCP> camp...@maynard.UUCP (Larry Campbell) writes:
>In article <3...@prairie.UUCP> d...@prairie.UUCP (Daniel M. Frank) writes:
>>In article <2...@rabbit1.UUCP> bar...@rabbit1.UUCP (Steve Barber) writes:
>>>Another common problem is passing NULL as pointer argument. NULL is
>>>#defined as 0, which is 2 bytes. Large model pointers are 4 bytes, so
>>>the stack frame is now basically garbage.
>>
>> This isn't really true. Code in stdio.h for the SV/286 release
>>checks your memory model, and if it is large, defines NULL to be 0L,
>>which is the same size as a pointer. It doesn't please lint, so the
>>best solution is still to cast it as appropriate (like (char *)0),
>>but you ARE generally safe, as long as you include stdio.h.
>
>I wonder why stdio.h doesn't just declare NULL as "(char *) 0", or,
>in the brave new world of ANSI X-whatever, "(void *) 0"? This should
>do all the right things.

Note that in SCO XENIX (a/k/a MICROSOFT XENIX) they have declared NULL to be
of type (char *)0. Of course, you always have someone who will abuse this by
doing something stupid such as:

char buf[10];

buf[0] = NULL;

but they will learn!

The best practice is to cast it correctly (it sure makes lint happy!).


Tony Mason > No opinions expressed here. Only cold hard
University of Chicago > facts.

uucp: ...ihnp4!gargoyle!sphinx!wmam, ...ihnp4!gargoyle!euler!tony
bitnet: wmam%sph...@UChicago.Bitnet
US. Lotto System (bet your 22 cents that it will get there!!!)
3854 S. Archer (312) 254-2114 home
Chicago, IL 60632

David Herron, NPR Lover

unread,
Nov 7, 1986, 12:40:51 PM11/7/86
to
In article <8...@ur-valhalla.UUCP> da...@valhalla.UUCP (Dave Carlson) writes:
>A potential problem I smacked into yesterday when porting BSD to SV/AT
>is ioctl(2) expects as the third argument:
>union { int iarg;
> char *cparg;}
>Problem is that the union will pull 4 bytes off the stack (in large model)
>but the program calling with an integer will only push 2 bytes. Oh S*$&!
>I cast my integer args long and everything seems ok but what a pain...

Argh! And you're doing a port of an operating system???

UNIONS are the SAME size regardless of WHICH part of them you use!

A user which passes an int to a routine expecting a union is ASKING
for trouble!

Argh!
--
David Herron, cbosgd!ukma!david, da...@UKMA.BITNET, da...@ms.uky.csnet
(I'm also "postmaster", "news", "netnews", "uucp", "mmdf", and ...)
(And also the ACM chapter chairperson.)
(And even an all-around nice guy. Aren't you lucky to get something from me?)

Doug Gwyn

unread,
Nov 8, 1986, 3:16:50 AM11/8/86
to
In article <50...@ukme.ukma.uky.csnet> da...@ukme.UUCP (David Herron, NPR Lover) writes:
-In article <8...@ur-valhalla.UUCP> da...@valhalla.UUCP (Dave Carlson) writes:
->A potential problem I smacked into yesterday when porting BSD to SV/AT
->is ioctl(2) expects as the third argument:
->union { int iarg;
-> char *cparg;}
->Problem is that the union will pull 4 bytes off the stack (in large model)
->but the program calling with an integer will only push 2 bytes. Oh S*$&!
->I cast my integer args long and everything seems ok but what a pain...
-
-Argh! And you're doing a port of an operating system???
-
-UNIONS are the SAME size regardless of WHICH part of them you use!
-
-A user which passes an int to a routine expecting a union is ASKING
-for trouble!

Oh, good grief! Mr. Carlson is talking about ioctl(), which is a
well-known function whose third argument has a type that depends on
its second argument's value; usually it's an (int) or a (struct termio *).
The problem is not his; rather it is due to the SV/AT implementor
changing ioctl()'s third argument to be a union. This is in violation
of the SVID and of common sense, since (as Mr. Carlson reports) this
breaks correctly-written code.

0 new messages