[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: puppet problem on the kFreeBSD ports



(the short version - the parent forks and waitpids, and never gets a
SIGCHLD or a return from waitpid.  This appears to be because the child
never exec's after the fork).

Please could test patches from my previous mails:

Date: Fri, 6 Aug 2010 13:31:14 +0200 (CEST)
Date: Fri, 6 Aug 2010 18:45:06 +0200 (CEST)


* 1.8.7.299-2 + rb18.diff
* 1.8.7.299-2 + rb18.diff + disabled 100730_disable_getsetcontext_on_nptl in series
* 1.8.7.299-2 + rb18.diff + rb18-extra.diff
* 1.8.7.299-2 + rb18.diff + rb18-extra.diff + disabled
       100730_disable_getsetcontext_on_nptl in debian/patches/series


rb18-extra.diff slightly alteres timer thread starting/ending,
it uses less pthread primitives (no pthread_cond),
the drawback is that ending of timer thread is not immediate,
but it might last at most 10ms.


Please send me detailed recipe, i.e. whole .rb file
and script which have to be run. While I looked into ruby implementation,
I do not speak ruby itself :-(

In the provided kdump, the child calls rfork,
in linux it is named clone. The rest of child dump
looks like thread manager, it is needed to also know
trace of 77777.

77775 ruby1.8  CALL  sigprocmask(SIG_SETMASK,0xbfbe3af0,0xbfbe3af0)
77775 ruby1.8  RET   sigprocmask 0
77775 ruby1.8  CALL  rfork(RFPROC|RFMEM|RFTHREAD|RFSIGSHARE|RFLINUXTHPN)
77775 ruby1.8  RET   rfork 77777/0x12fd1
77775 ruby1.8  CALL  sigprocmask(SIG_SETMASK,0xbfbe3af0,0)
77775 ruby1.8  RET   sigprocmask 0


I believe that following part of rb18.diff might help:


--- ruby1.8-1.8.7.299.orig/process.c
+++ ruby1.8-1.8.7.299/process.c
@@ -1332,13 +1332,11 @@

     before_exec();
     pid = fork();
-    after_exec();
+    if (pid != 0)
+      after_exec();

     switch (pid) {
       case 0:
-#ifdef linux
-       after_exec();
-#endif
        rb_thread_atfork();
        if (rb_block_given_p()) {
            int status;



Petr
--- ruby1.8-1.8.7.299.orig/process.c
+++ ruby1.8-1.8.7.299/process.c
@@ -1332,13 +1332,11 @@
 
     before_exec();
     pid = fork();
-    after_exec();
+    if (pid != 0) 
+      after_exec();
 
     switch (pid) {
       case 0:
-#ifdef linux
-	after_exec();
-#endif
 	rb_thread_atfork();
 	if (rb_block_given_p()) {
 	    int status;
--- ruby1.8-1.8.7.299.orig/signal.c
+++ ruby1.8-1.8.7.299/signal.c
@@ -21,6 +21,7 @@
 #undef SIGBUS
 #endif
 
+#define sigprocmask pthread_sigmask
 #if defined HAVE_SIGPROCMASK || defined HAVE_SIGSETMASK
 #define USE_TRAP_MASK 1
 #else
--- eval.STD	2010-06-10 06:38:43.000000000 +0200
+++ eval.c	2010-08-06 14:47:58.000000000 +0200
@@ -12317,6 +12317,7 @@
     sigfillset(&all_signals);
     pthread_sigmask(SIG_BLOCK, &all_signals, 0);
 
+#if 0
     safe_mutex_lock(&running->lock);
     pthread_cond_signal(start);
 
@@ -12325,6 +12326,13 @@
     while ((err = WAIT_FOR_10MS()) == EINTR || err == ETIMEDOUT) {
 	if (timer_stopping)
 	    break;
+#else
+   while (!timer_stopping)
+   {
+       to.tv_sec = 0;
+       to.tv_nsec = PER_NANO/100;
+       nanosleep(&to, NULL); 
+#endif
 
 	if (!rb_thread_critical) {
 	    rb_thread_pending = 1;
@@ -12334,7 +12342,9 @@
 	}
     }
 
+#if 0
     pthread_cleanup_pop(1);
+#endif   
 
     return NULL;
 }
@@ -12342,6 +12352,7 @@
 void
 rb_thread_start_timer()
 {
+#if 0
     void *args[2];
     static pthread_cond_t start = PTHREAD_COND_INITIALIZER;
 
@@ -12356,17 +12367,31 @@
 	pthread_cond_wait(&start, &time_thread.lock);
     }
     pthread_cleanup_pop(1);
+#else
+    if (rb_thread_alone()) return;
+    if (!__sync_bool_compare_and_swap (&thread_init, 0, 1))
+        return;
+    CATCH_VTALRM();
+        
+    if (pthread_create(&time_thread.thread, 0, thread_timer, 0) != 0)
+        thread_init = 0;
+#endif
 }
 
 void
 rb_thread_stop_timer()
 {
     if (!thread_init) return;
+#if 0    
     safe_mutex_lock(&time_thread.lock);
     timer_stopping = 1;
     pthread_cond_signal(&time_thread.cond);
     thread_init = 0;
     pthread_cleanup_pop(1);
+#else
+    timer_stopping = 1;
+    thread_init = 0;
+#endif    
     pthread_join(time_thread.thread, NULL);
     timer_stopping = 0;
 }

Reply to: