Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 May 1998 18:43:57 +0000 (GMT)
From:      Terry Lambert <tlambert@primenet.com>
To:        syssgm@dtir.qld.gov.au (Stephen McKay)
Cc:        tlambert@primenet.com, freebsd-current@FreeBSD.ORG, syssgm@dtir.qld.gov.au
Subject:   Fix for undefined "__error" and discussion of shared object versioning
Message-ID:  <199805181843.LAA09263@usr01.primenet.com>
In-Reply-To: <199805180603.QAA16388@troll.dtir.qld.gov.au> from "Stephen McKay" at May 18, 98 04:03:01 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> >This would give each library a weak accessor that would be overridden
> >by the real accessor if the thing got linked to the right libc, right?
> 
> I tried a number of variants of this approach and could not make any of
> them work.  In all cases (well, all that compiled at all), the local
> hack ___error() was used in preference to the system supplied __error().
> Otherwise, this would be a good hack, costing only 12 bytes per .o file.

Use this one instead:

-----------------------------------------------------------------------
#ifndef __GNUC__
#ifndef _ERRNO_C_
static int *___error( void) { extern int errno; return &errno; }
#pragma weak __error = ___error
#endif	/* _ERRNO_C_*/
#endif	/* __GNUC__*/
extern int *	__error __P((void));
#define errno	(* __error())
-----------------------------------------------------------------------

This works *IF* libc and libc_r are compiled with -D_ERRNO_C_.

Also notice the lack of an __inline: use of __inline would expand
once per reference.

Amusingly enough, gdb is useless for debugging ld.so.


> Out of the possible solutions discussed, I very much prefer to delay
> this (inevitable) errno change until we change to ELF.  Next best would
> be a hack in ld.so to recognise __error specially and resolve it (if
> necessary) from a new lib__error.so.

An ld.so hack is precisely the wrong thing to do; it results in an
infinite recursion on the first error set which happens (which is
usually when Poul's malloc() code calls readlink() for /etc/malloc.conf
and gets an error when it's not a symlink when you link with libc_r).


> In my view, the least pleasant option is to bump all major library
> numbers.

It is, however, the correct one, I've decided, working on getting
this hack to actually work.


> This would have to include everything in ports as well as all the
> system libraries.

Yes, it would.

> I think this would be too error prone to be practical, and shows a
> weakness in the shared library versioning mechanism.

The versioning needs major, minor, and subminor.

The normal bugfix should increment the subminor; the interface addition
(like __error()) should increment the minor, and interface changes or
deletions (like the ISO networking address functions being ripped out,
which is what caused the version bump in libc and therefore this
problem) should bump the major.

Programs should prefer the same major and minor, but take the highest
subminor to get bug fixes.

Programs should try to take the same major and a different minor,
with warning that this may fail, in the absence of their preferred
major/minor.

Programs should fail on different major.



There is also a weakness in ld.so; specifically, ld.so, being a shared
object, should also be versioned (Sun does this).  This would have let
use "fix" the problem in ld.so by stepping it with libc.so and libc_r.so.



> Oh, and doing nothing is not what I call an option.

Use my tested fix, above.  It works.


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199805181843.LAA09263>