Date: Thu, 4 Jan 2001 16:26:30 -0800 (PST) From: John Polstra <jdp@polstra.com> To: hackers@freebsd.org Cc: rcarter@pinyon.org Subject: Re: ld-elf.so.1: assert failed: /usr/src/libexec/rtld-elf/rtld.c:2033 Message-ID: <200101050026.f050QU703172@vashon.polstra.com> In-Reply-To: <20001230164716.6366F9B@pinyon.org> References: <20001230164716.6366F9B@pinyon.org>
next in thread | previous in thread | raw e-mail | index | archive | help
In article <20001230164716.6366F9B@pinyon.org>, Russell L. Carter <rcarter@pinyon.org> wrote: > > Bingo! > > Thanks guys! Not so fast there, fella. You're not getting off that easily. ;-) Could you please try the patch below? It is like the patch that Paul sent, except it should handle error conditions better. This patch is against -current, but I think it will apply cleanly to -stable too. Thanks, John Index: rtld.c =================================================================== RCS file: /home/ncvs/src/libexec/rtld-elf/rtld.c,v retrieving revision 1.50 diff -u -r1.50 rtld.c --- rtld.c 2000/11/07 22:41:53 1.50 +++ rtld.c 2001/01/05 00:13:18 @@ -77,6 +77,8 @@ static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *); static Obj_Entry *dlcheck(void *); static bool donelist_check(DoneList *, const Obj_Entry *); +static void errmsg_restore(char *); +static char *errmsg_save(void); static char *find_library(const char *, const Obj_Entry *); static const char *gethints(void); static void init_dag(Obj_Entry *); @@ -457,6 +459,30 @@ va_end(ap); } +/* + * Return a dynamically-allocated copy of the current error message, if any. + */ +static char * +errmsg_save(void) +{ + return error_message == NULL ? NULL : xstrdup(error_message); +} + +/* + * Restore the current error message from a copy which was previously saved + * by errmsg_save(). The copy is freed. + */ +static void +errmsg_restore(char *saved_msg) +{ + if (saved_msg == NULL) + error_message = NULL; + else { + _rtld_error("%s", saved_msg); + free(saved_msg); + } +} + static const char * basename(const char *name) { @@ -696,7 +722,7 @@ if (obj == (Obj_Entry *) handle) break; - if (obj == NULL || obj->dl_refcount == 0) { + if (obj == NULL || obj->refcount == 0 || obj->dl_refcount == 0) { _rtld_error("Invalid shared object handle %p", handle); return NULL; } @@ -1184,13 +1210,20 @@ objlist_call_fini(Objlist *list) { Objlist_Entry *elm; + char *saved_msg; + /* + * Preserve the current error message since a fini function might + * call into the dynamic linker and overwrite it. + */ + saved_msg = errmsg_save(); STAILQ_FOREACH(elm, list, link) { if (elm->obj->refcount == 0) { dbg("calling fini function for %s", elm->obj->path); (*elm->obj->fini)(); } } + errmsg_restore(saved_msg); } /* @@ -1202,11 +1235,18 @@ objlist_call_init(Objlist *list) { Objlist_Entry *elm; + char *saved_msg; + /* + * Preserve the current error message since an init function might + * call into the dynamic linker and overwrite it. + */ + saved_msg = errmsg_save(); STAILQ_FOREACH(elm, list, link) { dbg("calling init function for %s", elm->obj->path); (*elm->obj->init)(); } + errmsg_restore(saved_msg); } static void @@ -2030,7 +2070,8 @@ { const Needed_Entry *needed; - assert(root->refcount != 0); + if (root->refcount == 0) + return; root->refcount--; if (root->refcount == 0) for (needed = root->needed; needed != NULL; needed = needed->next) To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200101050026.f050QU703172>