From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.io/gmane.linux.lib.musl.general/22180 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: [PATCH] __libc_exit_fini forgets to do pthread_mutex_unlock Date: Wed, 2 Jul 2025 10:18:53 -0400 Message-ID: <20250702141853.GH1827@brightrain.aerifal.cx> References: <20250702022854.30301-1-rebecca.zhang.cn@windriver.com> Reply-To: musl@lists.openwall.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="14309"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mutt/1.9.5 (2018-04-13) Cc: Markus Wichmann , "musl@lists.openwall.com" , "Deng, Wenbin (CN)" To: "Zhang, Huilin (Rebecca) (CN)" Original-X-From: musl-return-22200-gllmg-musl=m.gmane-mx.org@lists.openwall.com Wed Jul 02 16:19:16 2025 Return-path: Envelope-to: gllmg-musl@m.gmane-mx.org Original-Received: from second.openwall.net ([193.110.157.125]) by ciao.gmane.io with smtp (Exim 4.92) (envelope-from ) id 1uWyIt-0003Zd-3n for gllmg-musl@m.gmane-mx.org; Wed, 02 Jul 2025 16:19:15 +0200 Original-Received: (qmail 16170 invoked by uid 550); 2 Jul 2025 14:19:03 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: x-ms-reactions: disallow Original-Received: (qmail 16140 invoked from network); 2 Jul 2025 14:19:03 -0000 Content-Disposition: inline In-Reply-To: Xref: news.gmane.io gmane.linux.lib.musl.general:22180 Archived-At: On Wed, Jul 02, 2025 at 06:06:11AM +0000, Zhang, Huilin (Rebecca) (CN) wrote: > Hello, Markus, > > Please see attached test code main.c. Assume we compile it with MUSL and generate the executable program named myApp. > This myApp needs an input parameter which is an another executable program. If this parameter pointed to a nonexistent > program, this myApp will get stuck. > > For example: (aaa is a nonexistent program) > ./myApp aaa > > > The attached .png file is the snapshot that I ran myApp on ubutntu 22.04.3. > > Thanks, > Rebecca > > > -----Original Message----- > From: Markus Wichmann > Sent: Wednesday, July 2, 2025 12:31 PM > To: musl@lists.openwall.com > Cc: Zhang, Huilin (Rebecca) (CN) ; Deng, Wenbin (CN) > Subject: Re: [musl] [PATCH] __libc_exit_fini forgets to do pthread_mutex_unlock > > CAUTION: This email comes from a non Wind River email account! > Do not click links or open attachments unless you recognize the sender and know the content is safe. > > Am Wed, Jul 02, 2025 at 10:28:54AM +0800 schrieb rebecca.zhang.cn@windriver.com: > > From: Rebecca Zhang > > > > This commit fixes the issue that __libc_exit_fini only do > > pthread_mutex_lock, but forget to do pthread_mutex_unlock. > > --- > > ldso/dynlink.c | 1 + > > 1 file changed, 1 insertion(+) > > > > diff --git a/ldso/dynlink.c b/ldso/dynlink.c index ceca3c9..7885675 > > 100644 > > --- a/ldso/dynlink.c > > +++ b/ldso/dynlink.c > > @@ -1492,6 +1492,7 @@ void __libc_exit_fini() > > fpaddr(p, dyn[DT_FINI])(); #endif > > } > > + pthread_mutex_unlock(&init_fini_lock); > > } > > > > void __ldso_atfork(int who) > > -- > > 2.34.1 > > > I think that is a deliberate omision. __libc_exit_fini() is called > on process exit. After it runs, it must not run again, and no new > initializer must run at all. The process will exit very soon anyway. > The only way to deadlock here is if a destructor calls exit(), which > they aren't allowed to do. > > Ciao, > Markus > #include > #include > #include > #include > #include > #include > > void main(int argc, char *argv[]) { > if (argc < 2) { > fprintf(stderr, "usage: %s [args...]\n", argv[0]); > exit(EXIT_FAILURE); > } > > printf("parent process PID=%d is starting\n", getpid()); > > pid_t pid = vfork(); // use vfork to create child process > > if (pid < 0) { > // vfork fail > perror("vfork fail"); > exit(EXIT_FAILURE); > } else if (pid == 0) { > // child process > printf("child process PID=%d will start: %s\n", getpid(), argv[1]); > > // execute program which is pass in via argv > execvp(argv[1], &argv[1]); > > perror("execvp fail"); > exit(EXIT_FAILURE); > } else { > // parent process > printf("parent process PID=%d wait for child process PID=%d\n", getpid(), pid); > > int status; > pid_t wait_pid = waitpid(pid, &status, 0); // wait for child process terminating > > if (wait_pid < 0) { > perror("waitpid fail"); > } else if (WIFEXITED(status)) { > printf("child process exit???exit code: %d\n", WEXITSTATUS(status)); > } else if (WIFSIGNALED(status)) { > printf("child process is terminated by signal???signal is: %d\n", WTERMSIG(status)); > } > > printf("parent process exit\n"); > } > > exit(0); > } This is completely expected. You cannot call exit in the child after vfork. The only permissible actions are execve (and variants) and _exit. Rich