Debugging patch for Bug 1399746 draft
authorTom Prince <mozilla@hocat.ca>
Tue, 21 Nov 2017 14:12:34 -0700
changeset 703815 f3e0ba02a0ab77bd7a273104f4c066e6f97f808d
parent 703814 e7105e5e439ae2e3edecb2d07ffaaf9705f8bc03
child 703816 63524d706f5eed5c79a4aee7af6cb2c2b8828e6c
push id90981
push userbmo:mozilla@hocat.ca
push dateMon, 27 Nov 2017 20:23:23 +0000
bugs1399746
milestone59.0a1
Debugging patch for Bug 1399746
nsprpub/pr/src/pthreads/ptthread.c
--- a/nsprpub/pr/src/pthreads/ptthread.c
+++ b/nsprpub/pr/src/pthreads/ptthread.c
@@ -15,16 +15,18 @@
 #include "primpl.h"
 #include "prpdce.h"
 
 #include <pthread.h>
 #include <unistd.h>
 #include <string.h>
 #include <signal.h>
 #include <dlfcn.h>
+#include <execinfo.h>
+#include <stdio.h>
 
 #if defined(OPENBSD) || defined(FREEBSD) || defined(DRAGONFLY)
 #include <pthread_np.h>
 #endif
 
 #ifdef SYMBIAN
 /* In Open C sched_get_priority_min/max do not work properly, so we undefine
  * _POSIX_THREAD_PRIORITY_SCHEDULING here.
@@ -284,17 +286,34 @@ static PRThread* pt_AttachThread(void)
 
         thred->priority = PR_PRIORITY_NORMAL;
         thred->id = pthread_self();
         thred->idSet = PR_TRUE;
 #ifdef _PR_NICE_PRIORITY_SCHEDULING
         thred->tid = gettid();
 #endif
         rv = pthread_setspecific(pt_book.key, thred);
-        PR_ASSERT(0 == rv);
+        /* Expand PR_ASSERT(0 == rv) to debug Bug 1399746. */
+#if defined(DEBUG) || defined(FORCE_PR_ASSERT)
+        if (0 != rv) {
+            void* callstack[128];
+            int i, frames = backtrace(callstack, 128);
+            char** strs = backtrace_symbols(callstack, frames);
+            char msg[128];
+            snprintf(msg, sizeof(msg), "0 == rv (%d), pt_book.keyCreated=%d",
+                     rv, (int)pt_book.keyCreated);
+            /* PR_Assert(msg, __FILE__, __LINE__); */
+            fprintf(stderr, "Assertion failure: %s, at %s:%d\n", msg, __FILE__, __LINE__);
+            for (i = 0; i < frames; ++i) {
+               fprintf(stderr, "%s\n", strs[i]);
+            }
+            fflush(stderr);
+            free(strs);            
+          }
+#endif /* defined(DEBUG) || defined(FORCE_PR_ASSERT) */
 
         thred->state = PT_THREAD_GLOBAL | PT_THREAD_FOREIGN;
         PR_Lock(pt_book.ml);
 
         /* then put it into the list */
         thred->prev = pt_book.last;
         if (pt_book.last)
             pt_book.last->next = thred;
@@ -1061,16 +1080,23 @@ void PR_HPUX10xInit(shl_t handle, int lo
 #elif defined(AIX)
 /* Need to use the -binitfini::_PR_Fini linker option. */
 #endif
 
 void _PR_Fini(void)
 {
     void *thred;
     int rv;
+    void* callstack[128]; int i, frames = backtrace(callstack, 128);
+    char** strs = backtrace_symbols(callstack, frames);
+    fprintf(stderr, "_PR_Fini called\n");
+    for (i = 0; i < frames; ++i) {
+       fprintf(stderr, "%s\n", strs[i]);
+    }
+    fflush(stderr);
 
     if (!_pr_initialized) {
         /* Either NSPR was never successfully initialized or 
          * PR_Cleanup has been called already. */
         if (pt_book.keyCreated)
         {
             rv = pthread_key_delete(pt_book.key);
             PR_ASSERT(0 == rv);
@@ -1096,16 +1122,18 @@ void _PR_Fini(void)
     /* TODO: free other resources used by NSPR */
     /* _pr_initialized = PR_FALSE; */
 }  /* _PR_Fini */
 
 PR_IMPLEMENT(PRStatus) PR_Cleanup(void)
 {
     PRThread *me = PR_GetCurrentThread();
     int rv;
+    fprintf(stderr, "PR_Cleanup called\n");
+    fflush(stderr);
     PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR"));
     PR_ASSERT(me->state & PT_THREAD_PRIMORD);
     if (me->state & PT_THREAD_PRIMORD)
     {
         PR_Lock(pt_book.ml);
         while (pt_book.user > pt_book.this_many)
             PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT);
         if (me->state & PT_THREAD_SYSTEM)