Skip site navigation (1)Skip section navigation (2)
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>