[comp.sys.sgi] -lmalloc

scotts@isl1.ri.cmu.edu (Scott Safier) (01/29/89)

We have several personal Iris's running IRIX 3.1.  We have ported some
software from BSD systems, and found that there is a difference
between the C function malloc in /usr/lib/libbsd.a and
/usr/lib/libmalloc.a.  In particular the malloc in the latter library
is 8 times faster (by our estimates) than the malloc in the bsd
library (or the malloc provided with gnu emacs).

But there is also something strange with -lmalloc.  Sometimes,
programs which execute perfectly with the bsd malloc, core dump when
the other malloc is invoked.  For example, using X lib with bsd malloc
is ok, but with lmalloc core dumps occur.

Can somebody explain what the exact difference between these two
functions are?

Thanks,
  __
 /  \
 \__          -+--+-                 Scott Safier
    \  _  __   |  |                  Center for Integrated Manufacturing
 \__/ (__/\_)_/|_/|_/                           Decision Systems
                                     Carnegie Mellon
-- 

madd@adt.UUCP (jim frost) (01/30/89)

>We have several personal Iris's running IRIX 3.1.  We have ported some
>software from BSD systems, and found that there is a difference
>between the C function malloc in /usr/lib/libbsd.a and
>/usr/lib/libmalloc.a.  In particular the malloc in the latter library
>is 8 times faster (by our estimates) than the malloc in the bsd
>library (or the malloc provided with gnu emacs).
>
>But there is also something strange with -lmalloc.  Sometimes,
>programs which execute perfectly with the bsd malloc, core dump when
>the other malloc is invoked.  For example, using X lib with bsd malloc
>is ok, but with lmalloc core dumps occur.
>
>Can somebody explain what the exact difference between these two
>functions are?

I can't give you the exact difference but I can tell you a little
about it.

The libmalloc.a malloc() call uses a different internal format than
the default malloc(), and has much greater speed -- particularly with
lots of small allocations.  One of the changes between the two
malloc()'s is that the libmalloc.a version trashes the malloc()'ed
area after it was free()'ed.  My guess is it slams a pointer into the
area, which would be consistent with the man page.  If a program uses
the area after it's been free()'ed, it's likely to break.  This was
the case for our application, and it's probably the case with X.  If
you haven't noticed, much of X seems to be a hack.

Another difference between the libmalloc.a malloc() and the normal one
is the ability to adjust the tuning of its malloc (through mallopt())
and to turn on debugging.  This debugging feature is very useful in
finding which routine overran the bounds of a malloc()'ed region,
which is why we were using it.

At first I wondered "why don't they just make it the standard malloc
if it's so fast", but since so many programs incorrectly use space
which has been free()'ed (smashing both the program and malloc()'s
lists), it would be counterproductive -- especially considering the
number of annoyances which programmers have to put up with already on
the SGI.

Happy hacking,

jim frost
associative design technology
madd@bu-it.bu.edu

kipp@warp.SGI.COM (Kipp Hickman) (01/31/89)

In article <4143@pt.cs.cmu.edu>, scotts@isl1.ri.cmu.edu (Scott Safier) writes:
>  ...
> But there is also something strange with -lmalloc.  Sometimes,
> programs which execute perfectly with the bsd malloc, core dump when
> the other malloc is invoked.  For example, using X lib with bsd malloc
> is ok, but with lmalloc core dumps occur.

Most likely you have an Xlib which is compiled to allow malloc(0)'s.
-lmalloc does not support this ability.

					kipp hickman
					(kipp@sgi.com)
					silicon graphics inc.

dan@ingr.com (Dan Webb) (01/31/89)

in article <4143@pt.cs.cmu.edu>, scotts@isl1.ri.cmu.edu (Scott Safier) says:
> We have several personal Iris's running IRIX 3.1.  We have ported some
> software from BSD systems, and found that there is a difference
> between the C function malloc in /usr/lib/libbsd.a and
> /usr/lib/libmalloc.a.  In particular the malloc in the latter library
> is 8 times faster (by our estimates) than the malloc in the bsd
> library (or the malloc provided with gnu emacs).
> 
> But there is also something strange with -lmalloc.  Sometimes,
> programs which execute perfectly with the bsd malloc, core dump when
> the other malloc is invoked.  For example, using X lib with bsd malloc
> is ok, but with lmalloc core dumps occur.

I've had the same problem with -lmalloc (also known as malloc(3X)).
The crashes are probably caused by the fact that this implementation of
malloc, for some reason, treats a request for zero bytes as invalid.
It therefore returns a NULL pointer, which is probably passed to free()
or realloc() later, resulting in a core dump.

I probably don't have to convince too many people of this, but a request
for zero bytes is by no means an invalid request.  I think -lmalloc should
be fixed.

	 - Dan Webb

moraes@csri.toronto.edu (Mark Moraes) (02/01/89)

In article <3724@ingr.com> dan@ingr.com (Dan Webb) writes:
>> But there is also something strange with -lmalloc.  Sometimes,
>> programs which execute perfectly with the bsd malloc, core dump when
>> the other malloc is invoked.  For example, using X lib with bsd malloc
>> is ok, but with lmalloc core dumps occur.
>

Specifically for X lib, edit lib/X/Xlibos.h to define MALLOC_0_RETURNS_NULL
Grumble, grumble - see below.

>I probably don't have to convince too many people of this, but a request
>for zero bytes is by no means an invalid request.  I think -lmalloc should
>be fixed.

NOOOOO. PLEASE. malloc(0) SHOULD returns a NULL pointer and set EINVAL.
malloc(0) IS an invalid request if you stop and think about it for a
moment.

If you ask for 0 bytes (count 'em - zero), you presumably mean that
you don't want ANY storage. i.e. any pointer you get back is equally
valid because you aren't going to dereference it - EVER. If you
dereference it, then you should have used malloc(1), or
malloc(sizeof(whatever))

We have a debugging malloc here that botches an assertion and dumps
core if you call malloc(0) - finds lots of interesting bugs. Malloc(0)
is a bug, IMHO! Tell the people whose programs dump core with
malloc(0) to fix them. There are far too many backward compatible bugs
in the libraries already (can you say realloc(a freed block)?)

I'd be very interested in hearing your reasons why you feel malloc(0)
should return a pointer to valid storage. How many bytes of storage
you want for malloc(0)?

Reply by e-mail please - I'll summarize if there's enough response.

mike@iotek.UUCP (Mike Thompson) (02/01/89)

In article <3724@ingr.com> dan@ingr.com (Dan Webb) writes in reply to 
	article <4143@pt.cs.cmu.edu>, scotts@isl1.ri.cmu.edu (Scott Safier):
>I've had the same problem with -lmalloc (also known as malloc(3X)).
>The crashes are probably caused by the fact that this implementation of
>malloc, for some reason, treats a request for zero bytes as invalid.
>It therefore returns a NULL pointer, which is probably passed to free()
>or realloc() later, resulting in a core dump.
>
>I probably don't have to convince too many people of this, but a request
>for zero bytes is by no means an invalid request.  I think -lmalloc should
>be fixed.
>
>	 - Dan Webb

	Well I'm one of those few who need convincing, I think that
    treating a request for 0 memory from a memory managment system as
    an error is if not correct is at least not incorrect, to give you
    a valid pointer would in effect be allocating at least a byte,
    after all that address cannot be allocated to any other request
    can it?  On the other hand a program that does not check for
    errors on system calls, and does no checking for null pointers is
    definitely what I would call not written in the best of styles if
    not down right buggy!  (especially with the problems of null
    de-referencing effecting portability over the past few years)
-- 
<<<<<<******>>>>>>
Michael A. Thompson, Iotek Inc, |*| E-Mail: mike@iotek.uucp	|*| Have
1127 Barrington St., Suite 100, |*| Fax:    (902)420-0674	|*|   a Good
Halifax, N.S., B3H 2P8, Canada  |*| Phone:  (902)420-1890	|*|     Day :-)

dan@ingr.com (Dan Webb) (02/03/89)

in article <295@jupiter.iotek.UUCP>, mike@iotek.UUCP (Mike Thompson) says:
> 
> In article <3724@ingr.com> dan@ingr.com (Dan Webb) says:
>>I probably don't have to convince too many people of this, but a request
>>for zero bytes is by no means an invalid request.  I think -lmalloc should
>>be fixed.

> 	Well I'm one of those few who need convincing, I think that
>     treating a request for 0 memory from a memory managment system as
>     an error is if not correct is at least not incorrect, to give you

Ok, I guess there are a few people that need to be convinced.

Philisophically speaking:
When you're talking about an amount of things, zero is not a special case.
I can have two apples, or I can have zero apples.  If I have zero apples, I'd
better not try to eat one because I might core dump :-).

Asking for zero bytes is just as valid.  I have written lots of code that
deals with dynamically changing data, such as fonts (yes, these fonts are
quite dynamic) and Mac-like scrolling lists.  It is quite valid for a font
to initially have no characters or a list to have no entries.  I must
therefore deal with the case of allocating a zero-length amount.  Later, I
need to realloc or free the data.  If malloc(0) returns NULL, I'm forced to
special-case it everywhere I allocate/reallocate/free it.

My code looks like this in many places:
	ptr = (Thing *) malloc (count * sizeof (Thing));
	...
	ptr = (Thing *) realloc (ptr, count * sizeof (Thing));
	...
	free (ptr);
The value of count may very well be zero.

The bottom line is that if I want to special-case zero for speed,
I will.  But I don't want malloc to force me to do it.

>      ...to give you
>     a valid pointer would in effect be allocating at least a byte,
>     after all that address cannot be allocated to any other request
>     can it?

This depends on the implementation.  The normal SysV malloc uses a linked
list of blocks, so it isn't a problem.  The only thing that would exist for
the zero-length block is the block header.

>     On the other hand a program that does not check for
>     errors on system calls, and does no checking for null pointers is
>     definitely what I would call not written in the best of styles if
>     not down right buggy!  (especially with the problems of null
>     de-referencing effecting portability over the past few years)

I totally agree.  But if I checked for an error an error from -lmalloc, it
would tell me that allocating zero entries in my list is invalid -- when
it's really not!

To solve the problem with -lmalloc, I wrote wrappers around malloc and
realloc.  They turn any zero request into a request for one byte.

	- Dan Webb