The dangers of replacing malloc()

Terry Lambert tlambert2 at
Sat Jun 28 01:29:25 PDT 2003

"D. J. Bernstein" wrote:
> Terry Lambert writes:
> > My argument in this case is that the valloc() interface is not
> > portable, and you should not use it.
> kqueue isn't portable, so you're saying nobody should use that, right?

Not in portable code.

> Or do you admit that it's actually a good idea for people to use kqueue,
> with a compile-time fallback to poll or select? Great.

Only the fallback code is actually portable.

> Now, what happens when some other system decides to emulate kqueue (not
> a huge surprise), using valloc (or some future xyzalloc), which in turn
> uses sbrk directly (as valloc already does on a huge number of systems,
> and as xyzalloc will probably do), rather than calling malloc?

Look.  You keep describing an implementation error on one system,
as if implementations errors aren't correctable, or you have to
support all systems with your software, even broken ones with
interfaces you should avoid anyway.

The "GNU answer" would be to carry around glibc2 with you wherever
you go, and don't rely on the vendor's libc programmers having got
it right.

I can tell you right now I could fix the implementation error on
the system in question through judicious used of "ar" and "ranlib"
and the C compiler, to write a replacement for valloc() and *MAKE*
that system work.

In the limit, the programmer is always more able than all vendor
supplied user space code and most kernel space code, even on
closed source systems.  On Open Source systems, the programmer is
God, and all problems, if they exist, belong to him to fix ("With
great power comes great responsibility").

> That's right: it obliterates the data that I obtained from sbrk in my
> malloc replacement. Kaboom. This is exactly the failure mode I explained
> before. This is why the weak linking of the system's malloc is useless
> for experienced programmers who care about portability.

	cc -C -o valloc.o <<EOF
	/* stupid replacement for broken valloc */
	#include <stdlib.h>
	#include <unistd.h>
	void *
	valloc(size_t size)
		void *mem;
		size_t sz = size;
		long pg_sz = sysconf(_SC_PAGESIZE);

		sz += pg_sz;
		mem = malloc(sz);
		mem += (pg_sz - 1);
		mem &= ~(pg_sz - 1);

	cp /usr/lib/libc.a .
	ar -r valloc.o
	# ready to use local libc.a in place of the system libc.a

Yes, you will have to add sizeof(void *) to your allocation an keep
the real allocation address there, and free it using a negative index
offset dereference as the real free address, if your malloc/free does
not do other internal housekeeping, but that's the problem of the
malloc implementor.

> (Since you asked: My valloc-uses-sbrk-directly demonstration was under
> Linux, exactly as I said; specifically, Debian. Are you really so naive
> as to think that all the Linux functions are listed in the manual?)

No... the manual only lists the functions you should consider OK
to use... now, given that it's not in the manual...

In any case, you have the source code and can fix yourself a local
copy, if it was Debian instead of Solaris.

-- Terry

More information about the freebsd-performance mailing list