diff options
author | wtc%netscape.com <devnull@localhost> | 2000-08-11 03:09:44 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 2000-08-11 03:09:44 +0000 |
commit | 4211128484ed5fa6c1fb7a9a7d76d147e829b06d (patch) | |
tree | ff1f59115d30b2da5129b9fa7422fb0a1e2557e0 | |
parent | 0093b5a6ea09936bb4b9730e37df9bb17d7adfa6 (diff) | |
download | nspr-hg-4211128484ed5fa6c1fb7a9a7d76d147e829b06d.tar.gz |
Bugzilla bug #15906: added GC_LEAK_DETECTOR support for Linux.
Modified files: config.mk, primpl.h, pr/src/Makefile, pr/src/Makefile.in,
pr/src/memory/Makefile, pr/src/memory/Makefile.in, prthinfo.c, ptthread.c
Added file: pr/src/memory/prgcleak.c
(NSPRPUB_CLIENT_BRANCH)
-rw-r--r-- | config/config.mk | 4 | ||||
-rw-r--r-- | pr/include/private/primpl.h | 8 | ||||
-rw-r--r-- | pr/src/Makefile | 8 | ||||
-rw-r--r-- | pr/src/Makefile.in | 8 | ||||
-rw-r--r-- | pr/src/memory/Makefile | 4 | ||||
-rw-r--r-- | pr/src/memory/Makefile.in | 4 | ||||
-rw-r--r-- | pr/src/memory/prgcleak.c | 46 | ||||
-rw-r--r-- | pr/src/misc/prthinfo.c | 3 | ||||
-rw-r--r-- | pr/src/pthreads/ptthread.c | 53 |
9 files changed, 102 insertions, 36 deletions
diff --git a/config/config.mk b/config/config.mk index 1985c50b..a3c1674d 100644 --- a/config/config.mk +++ b/config/config.mk @@ -188,6 +188,10 @@ ifeq ($(USE_IPV6),1) OS_CFLAGS += -D_PR_INET6 endif +ifdef GC_LEAK_DETECTOR +OS_CFLAGS += -DGC_LEAK_DETECTOR +endif + #################################################################### # # Configuration for the release process diff --git a/pr/include/private/primpl.h b/pr/include/private/primpl.h index 4b68a2b1..8c1d3e12 100644 --- a/pr/include/private/primpl.h +++ b/pr/include/private/primpl.h @@ -172,6 +172,14 @@ struct _PT_Notified (thr->interrupt_blocked = 1) #define _PT_THREAD_UNBLOCK_INTERRUPT(thr) \ (thr->interrupt_blocked = 0) + +#ifdef GC_LEAK_DETECTOR +/* All threads are GCable. */ +#define _PT_IS_GCABLE_THREAD(thr) 1 +#else +#define _PT_IS_GCABLE_THREAD(thr) ((thr)->state & PT_THREAD_GCABLE) +#endif /* GC_LEAK_DETECTOR */ + /* ** Possible values for thread's suspend field ** Note that the first two can be the same as they are really mutually exclusive, diff --git a/pr/src/Makefile b/pr/src/Makefile index d9cf5b4d..d608681d 100644 --- a/pr/src/Makefile +++ b/pr/src/Makefile @@ -145,6 +145,10 @@ OS_LIBS = advapi32.lib wsock32.lib winmm.lib endif endif +ifdef GC_LEAK_DETECTOR +OS_LIBS += -L$(DIST)/lib -lboehm +endif + # # Define platform-dependent OBJS # @@ -242,6 +246,10 @@ OBJS += \ cplus/$(OBJDIR)/rctime.$(OBJ_SUFFIX) endif +ifdef GC_LEAK_DETECTOR +OBJS += memory/$(OBJDIR)/prgcleak.$(OBJ_SUFFIX) +endif + ifeq ($(OS_ARCH), WINNT) ifneq ($(OS_TARGET),WIN16) DLLBASE=/BASE:0x30000000 diff --git a/pr/src/Makefile.in b/pr/src/Makefile.in index c82b1438..2458b896 100644 --- a/pr/src/Makefile.in +++ b/pr/src/Makefile.in @@ -151,6 +151,10 @@ endif endif endif +ifdef GC_LEAK_DETECTOR +OS_LIBS += -L$(DIST)/lib -lboehm +endif + endif # USE_AUTOCONF # # Define platform-dependent OBJS @@ -244,6 +248,10 @@ OBJS += \ cplus/$(OBJDIR)/rctime.$(OBJ_SUFFIX) endif +ifdef GC_LEAK_DETECTOR +OBJS += memory/$(OBJDIR)/prgcleak.$(OBJ_SUFFIX) +endif + ifdef USE_AUTOCONF include $(srcdir)/md/$(PR_MD_ARCH_DIR)/objs.mk diff --git a/pr/src/memory/Makefile b/pr/src/memory/Makefile index 25762308..28c15b13 100644 --- a/pr/src/memory/Makefile +++ b/pr/src/memory/Makefile @@ -30,6 +30,10 @@ endif CSRCS = prseg.c prshm.c prshma.c +ifdef GC_LEAK_DETECTOR +CSRCS += prgcleak.c +endif + TARGETS = $(OBJS) INCLUDES = -I$(DIST)/include -I$(MOD_DEPTH)/pr/include -I$(MOD_DEPTH)/pr/include/private diff --git a/pr/src/memory/Makefile.in b/pr/src/memory/Makefile.in index 7fa317e3..53c9dde1 100644 --- a/pr/src/memory/Makefile.in +++ b/pr/src/memory/Makefile.in @@ -37,6 +37,10 @@ endif #!USE_AUTOCONF CSRCS = prseg.c prshm.c prshma.c +ifdef GC_LEAK_DETECTOR +CSRCS += prgcleak.c +endif + TARGETS = $(OBJS) INCLUDES = -I$(DIST)/include -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private diff --git a/pr/src/memory/prgcleak.c b/pr/src/memory/prgcleak.c index ec223c79..4006ad71 100644 --- a/pr/src/memory/prgcleak.c +++ b/pr/src/memory/prgcleak.c @@ -1,36 +1,22 @@ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape Portable Runtime (NSPR). - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1999-2000 Netscape Communications Corporation. All - * Rights Reserved. - * +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + * * Contributor(s): * Patrick Beard <beard@netscape.com> - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. */ /* diff --git a/pr/src/misc/prthinfo.c b/pr/src/misc/prthinfo.c index 67415420..a278e0ad 100644 --- a/pr/src/misc/prthinfo.c +++ b/pr/src/misc/prthinfo.c @@ -134,12 +134,15 @@ PR_ThreadScanStackPointers(PRThread* t, if (status != PR_SUCCESS) return status; +#ifndef GC_LEAK_DETECTOR + /* if thread is not allocated on stack, this is redundant. */ ptd = t->privateData; for (index = 0; index < t->tpdLength; index++, ptd++) { status = scanFun(t, (void**)ptd, 1, scanClosure); if (status != PR_SUCCESS) return status; } +#endif return PR_SUCCESS; } diff --git a/pr/src/pthreads/ptthread.c b/pr/src/pthreads/ptthread.c index 23189c53..787d1e48 100644 --- a/pr/src/pthreads/ptthread.c +++ b/pr/src/pthreads/ptthread.c @@ -75,6 +75,42 @@ static PRIntn pt_PriorityMap(PRThreadPriority pri) } #endif +#if defined(GC_LEAK_DETECTOR) && (__GLIBC__ >= 2) && defined(__i386__) + +#include <setjmp.h> + +typedef struct stack_frame stack_frame; + +struct stack_frame { + stack_frame* next; + void* pc; +}; + +static stack_frame* GetStackFrame() +{ + jmp_buf jb; + stack_frame* currentFrame; + setjmp(jb); + currentFrame = (stack_frame*)(jb[0].__jmpbuf[JB_BP]); + currentFrame = currentFrame->next; + return currentFrame; +} + +static void* GetStackTop() +{ + stack_frame* frame; + frame = GetStackFrame(); + while (frame != NULL) + { + ptrdiff_t pc = (ptrdiff_t)frame->pc; + if ((pc < 0x08000000) || (pc > 0x7fffffff) || (frame->next < frame)) + return frame; + frame = frame->next; + } + return NULL; +} +#endif /* GC_LEAK_DETECTOR && (__GLIBC__ >= 2) && __i386__ */ + /* ** Initialize a stack for a native pthread thread */ @@ -91,9 +127,14 @@ static void _PR_InitializeStack(PRThreadStack *ts) ts->stackBottom = ts->allocBase + ts->stackSize; ts->stackTop = ts->allocBase; #else +#ifdef GC_LEAK_DETECTOR + ts->stackTop = GetStackTop(); + ts->stackBottom = ts->allocTop - ts->stackSize; +#else ts->stackTop = ts->allocBase; ts->stackBottom = ts->allocBase - ts->stackSize; #endif +#endif } } @@ -1031,7 +1072,7 @@ PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg) */ PRThread* next = thred->next; - if (thred->state & PT_THREAD_GCABLE) + if (_PT_IS_GCABLE_THREAD(thred)) { #if !defined(_PR_DCETHREADS) PR_ASSERT((thred == me) || (thred->suspend & PT_THREAD_SUSPENDED)); @@ -1095,7 +1136,7 @@ static void suspend_signal_handler(PRIntn sig) PRThread *me = PR_CurrentThread(); PR_ASSERT(me != NULL); - PR_ASSERT(me->state & PT_THREAD_GCABLE); + PR_ASSERT(_PT_IS_GCABLE_THREAD(me)); PR_ASSERT((me->suspend & PT_THREAD_SUSPENDED) == 0); PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, @@ -1286,7 +1327,7 @@ PR_IMPLEMENT(void) PR_SuspendAll() #endif while (thred != NULL) { - if ((thred != me) && (thred->state & PT_THREAD_GCABLE)) + if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) PR_SuspendSet(thred); thred = thred->next; } @@ -1295,7 +1336,7 @@ PR_IMPLEMENT(void) PR_SuspendAll() thred = pt_book.first; while (thred != NULL) { - if ((thred != me) && (thred->state & PT_THREAD_GCABLE)) + if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) PR_SuspendTest(thred); thred = thred->next; } @@ -1328,7 +1369,7 @@ PR_IMPLEMENT(void) PR_ResumeAll() while (thred != NULL) { - if ((thred != me) && (thred->state & PT_THREAD_GCABLE)) + if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) PR_ResumeSet(thred); thred = thred->next; } @@ -1336,7 +1377,7 @@ PR_IMPLEMENT(void) PR_ResumeAll() thred = pt_book.first; while (thred != NULL) { - if ((thred != me) && (thred->state & PT_THREAD_GCABLE)) + if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) PR_ResumeTest(thred); thred = thred->next; } |