This is the mail archive of the libc-alpha@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[pelliott@nowdocs.com] libc/1708:



Hi libc developers,

I can confirm the reported bug with static linking.  Can somebody
check the suggested fix and send a clean patch, please?

Thanks,
Andreas



Topics:
   libc/1708: [pthreads stop working on call to "system" if linked -static]


----------------------------------------------------------------------

Date: Tue, 25 Apr 2000 16:29:52 -0500
From: pelliott@nowdocs.com
To: bugs@gnu.org
Subject: libc/1708: [pthreads stop working on call to "system" if linked -static]
Message-Id: <200004252129.QAA01232@vortex.nowdocs.com>


>Number:         1708
>Category:       libc
>Synopsis:       pthreads stop working children defunct on call to "system" if linked -static
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    libc-gnats
>State:          open
>Class:          doc-bug
>Submitter-Id:   unknown
>Arrival-Date:   Tue Apr 25 17:40:06 EDT 2000
>Last-Modified:
>Originator:     
>Organization:
NowDocs.com
 
>Release:        libc-2.1.2
>Environment:
pc, linux, linux, glibc

Host type: i386-redhat-linux-gnu
System: Linux vortex.nowdocs.com 2.2.14 #5 SMP Wed Mar 8 14:28:07 CST 2000 i686 unknown
Architecture: i686

Addons: crypt glibc-compat linuxthreads
Build CFLAGS: -O3 -Wall -Winline -Wstrict-prototypes -Wwrite-strings -g
Build CC: egcs
Compiler version: egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
Kernel headers: 2.2.14
Symbol versioning: yes
Build static: yes
Build shared: yes
Build pic-default: no
Build profile: yes
Build omitfp: no
Build bounded: no
Build static-nss: no
Stdio: libio

>Description:
/* if linked -static program calls "system" manager thread exits, parent thread stops
*  all children programs become defunct. 
*/
>How-To-Repeat:
/* link the following code -static, then run. */

#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>

void putmsg(const char* fmt, ...) {
    char buf[256], *end;
    va_list ap;
    va_start(ap, fmt);
    vsprintf(buf, fmt, ap);
    va_end(ap);
    write(1, buf, strlen(buf));
}

void* threadfun(void* arg) {
    const char* msg = (const char*) arg;
    for(;;) {
	putmsg("pid=%d, tid=%d, name=%s, ppid=%d\n", 
	       getpid(), pthread_self(), msg, getppid() );
	sleep(1);
    }
}

void spawn(const char* name) {
    pthread_t tid;
    int e = pthread_create(&tid, NULL, threadfun, (void*)name);
    if (e != 0) {
	putmsg("pthread_create(%s) = %d\n", name, e);
    }
}

int main() {

  printf("main pid=%d\n",getpid() );

    spawn("one");
    spawn("two");
    spawn("three");
    sleep(5);
    putmsg("calling system\n");
    system("echo \"Your momma!\"");
    pause();

    sleep(60);

    return 0;
}

>Fix:
	workaround:
	/* grab the following code from glibc-2.1/sysdeps/posix
	 * rename __libc_system to my_libc_system
	 * change  __set_errno to errno = 
	 * so that it will compile
	 * call my_libc_system instead of "system"
         */

/* Copyright (C) 1991, 92, 94, 95, 96, 97 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/types.h>
#include <errno.h>


#ifndef	HAVE_GNU_LD
#define	__environ	environ
#endif

#define	SHELL_PATH	"/bin/sh"	/* Path of the shell.  */
#define	SHELL_NAME	"sh"		/* Name to give it.  */

/* Execute LINE as a shell command, returning its status.  */
int
my_libc_system (const char *line)
{
  int status, save;
  pid_t pid;
  struct sigaction sa, intr, quit;
#ifndef WAITPID_CANNOT_BLOCK_SIGCHLD
  sigset_t block, omask;
#endif

  if (line == NULL)
    /* This signals that we have a command processor available.  */
    return 1;

  sa.sa_handler = SIG_IGN;
  sa.sa_flags = 0;
  __sigemptyset (&sa.sa_mask);

  if (__sigaction (SIGINT, &sa, &intr) < 0)
    return -1;
  if (__sigaction (SIGQUIT, &sa, &quit) < 0)
    {
      save = errno;
      (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
      errno = save;
      return -1;
    }

#ifndef WAITPID_CANNOT_BLOCK_SIGCHLD

/* SCO 3.2v4 has a bug where `waitpid' will never return if SIGCHLD is
   blocked.  This makes it impossible for `system' to be implemented in
   compliance with POSIX.2-1992.  They have acknowledged that this is a bug
   but I have not seen nor heard of any forthcoming fix.  */

  __sigemptyset (&block);
  __sigaddset (&block, SIGCHLD);
  save = errno;
  if (__sigprocmask (SIG_BLOCK, &block, &omask) < 0)
    {
      if (errno == ENOSYS)
	errno = save;
      else
	{
	  save = errno;
	  (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
	  (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
	  errno = save;
	  return -1;
	}
    }
#define UNBLOCK	__sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL)
#else
#define UNBLOCK 0
#endif

  pid = __vfork ();
  if (pid == (pid_t) 0)
    {
      /* Child side.  */
      const char *new_argv[4];
      new_argv[0] = SHELL_NAME;
      new_argv[1] = "-c";
      new_argv[2] = line;
      new_argv[3] = NULL;

      /* Restore the signals.  */
      (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
      (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
      (void) UNBLOCK;

      /* Exec the shell.  */
      (void) __execve (SHELL_PATH, (char *const *) new_argv, __environ);
      _exit (127);
    }
  else if (pid < (pid_t) 0)
    /* The fork failed.  */
    status = -1;
  else
    /* Parent side.  */
#ifdef	NO_WAITPID
    {
      pid_t child;
      do
	{
	  child = __wait (&status);
	  if (child <= -1)
	    {
	      status = -1;
	      break;
	    }
	} while (child != pid);
    }
#else
    if (__waitpid (pid, &status, 0) != pid)
      status = -1;
#endif

  save = errno;
  if ((__sigaction (SIGINT, &intr, (struct sigaction *) NULL) |
       __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL) |
       UNBLOCK) != 0)
    {
      if (errno == ENOSYS)
	errno = save;
      else
	return -1;
    }

  return status;
}
>Audit-Trail:
>Unformatted:


------------------------------

End of forwardHdDFqT Digest
***************************



-- 
 Andreas Jaeger
  SuSE Labs aj@suse.de
   private aj@arthur.rhein-neckar.de

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]