From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/11082 Path: news.gmane.org!.POSTED!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: Reviving planned ldso changes Date: Sat, 25 Feb 2017 20:39:26 -0500 Message-ID: <20170226013926.GY1520@brightrain.aerifal.cx> References: <20170103054351.GA8459@brightrain.aerifal.cx> <20170104060640.GM1555@brightrain.aerifal.cx> <20170104062203.GN1555@brightrain.aerifal.cx> <20170104193627.GO1555@brightrain.aerifal.cx> <587A988A.50105@Wilcox-Tech.com> <20170115174438.GD1533@brightrain.aerifal.cx> <20170226010429.GQ12395@port70.net> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: blaine.gmane.org 1488073184 3724 195.159.176.226 (26 Feb 2017 01:39:44 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sun, 26 Feb 2017 01:39:44 +0000 (UTC) User-Agent: Mutt/1.5.21 (2010-09-15) To: musl@lists.openwall.com Original-X-From: musl-return-11097-gllmg-musl=m.gmane.org@lists.openwall.com Sun Feb 26 02:39:38 2017 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1chnoG-000087-HD for gllmg-musl@m.gmane.org; Sun, 26 Feb 2017 02:39:36 +0100 Original-Received: (qmail 24014 invoked by uid 550); 26 Feb 2017 01:39:40 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 23995 invoked from network); 26 Feb 2017 01:39:39 -0000 Content-Disposition: inline In-Reply-To: <20170226010429.GQ12395@port70.net> Original-Sender: Rich Felker Xref: news.gmane.org gmane.linux.lib.musl.general:11082 Archived-At: On Sun, Feb 26, 2017 at 02:04:30AM +0100, Szabolcs Nagy wrote: > * Rich Felker [2017-01-15 12:44:38 -0500]: > > static void do_init_fini(struct dso *p) > > { > > size_t dyn[DYN_CNT]; > > - int need_locking = libc.threads_minus_1; > > - /* Allow recursive calls that arise when a library calls > > - * dlopen from one of its constructors, but block any > > - * other threads until all ctors have finished. */ > > - if (need_locking) pthread_mutex_lock(&init_fini_lock); > > - for (; p; p=p->prev) { > > - if (p->constructed) continue; > > + pthread_mutex_lock(&init_fini_lock); > > + /* Construct in dependency order without any recursive state. */ > > + while (p && !p->constructed) { > > + /* The following loop descends into the first dependency > > + * that is neither alredy constructed nor pending > > + * construction due to circular deps, stopping only > > + * when it reaches a dso with no remaining dependencies > > + * to descend into. */ > > + while (p->deps && p->deps[p->next_dep]) { > > + if (!p->deps[p->next_dep]->constructed && > > + !p->deps[p->next_dep]->next_dep) > > + p = p->deps[p->next_dep++]; > > + else > > + p->next_dep++; > > + } > > p->constructed = 1; > > decode_vec(p->dynv, dyn, DYN_CNT); > > if (dyn[0] & ((1< > @@ -1233,17 +1246,19 @@ static void do_init_fini(struct dso *p) > > size_t *fn = laddr(p, dyn[DT_INIT_ARRAY]); > > while (n--) ((void (*)(void))*fn++)(); > > } > > - if (!need_locking && libc.threads_minus_1) { > > - need_locking = 1; > > - pthread_mutex_lock(&init_fini_lock); > > - } > > - } > > - if (need_locking) pthread_mutex_unlock(&init_fini_lock); > > + /* Revisit "parent" dso which caused the just-constructed > > + * dso to be pulled in as a dependency. On the next loop > > + * iteration we will either descend to construct a sibling > > + * of the just-constructed dso, or finish constructing the > > + * parent if no unfinished deps remain. */ > > + p = p->needed_by; > > + } > > i think with > > a.deps: b c > b.deps: c d > b.needed_by: a > c.needed_by: a > > the visiting order starting from a is > a > b > c > a > > and d never gets constructed. Are you sure? My understanding of what it does is: 1. Descend a->b->c, construct c, and back up to b. 2. Descend b->d, construct d, and back up to b. 3. Find all of b's deps constructed, construct b, and back up to a. 4. Find all of a's deps constructed, construct a, and end. I think you have a misunderstanding of "visit order". Nodes are not visited while descending, only when reaching a point where no further descent into a non-constructed dep is possible. Rich