From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: YAMAMOTO Mitsuharu Newsgroups: gmane.emacs.bugs Subject: Re: emacs-22.1 with GTK dumps core when Gnome wigets clicked Date: Thu, 14 Jun 2007 11:16:30 +0900 Organization: Faculty of Science, Chiba University Message-ID: References: <200706091549.l59FnfHJ005433@deneb.cc.umanitoba.ca> <20070610125120.GA27355@cc.umanitoba.ca> <20070610.224832.46203780.mituharu@math.s.chiba-u.ac.jp> <20070610141003.GA12085@cc.umanitoba.ca> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII X-Trace: sea.gmane.org 1181787403 2703 80.91.229.12 (14 Jun 2007 02:16:43 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Thu, 14 Jun 2007 02:16:43 +0000 (UTC) Cc: bug-gnu-emacs@gnu.org To: Gary Mills Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Jun 14 04:16:39 2007 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1Hyet4-0006V6-Ue for geb-bug-gnu-emacs@m.gmane.org; Thu, 14 Jun 2007 04:16:39 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Hyet4-00025O-Au for geb-bug-gnu-emacs@m.gmane.org; Wed, 13 Jun 2007 22:16:38 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Hyet1-00025J-Jz for bug-gnu-emacs@gnu.org; Wed, 13 Jun 2007 22:16:35 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Hyesz-000257-RD for bug-gnu-emacs@gnu.org; Wed, 13 Jun 2007 22:16:34 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Hyesz-000254-MM for bug-gnu-emacs@gnu.org; Wed, 13 Jun 2007 22:16:33 -0400 Original-Received: from ntp.math.s.chiba-u.ac.jp ([133.82.132.2] helo=mathmail.math.s.chiba-u.ac.jp) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Hyesy-0002t8-Nn for bug-gnu-emacs@gnu.org; Wed, 13 Jun 2007 22:16:33 -0400 Original-Received: from church.math.s.chiba-u.ac.jp (church [133.82.132.36]) by mathmail.math.s.chiba-u.ac.jp (Postfix) with ESMTP id 7FF952C40; Thu, 14 Jun 2007 11:16:30 +0900 (JST) In-Reply-To: <20070610141003.GA12085@cc.umanitoba.ca> User-Agent: Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.8 (=?ISO-8859-4?Q?Shij=F2?=) APEL/10.6 Emacs/22.1.50 (sparc-sun-solaris2.8) MULE/5.0 (SAKAKI) X-detected-kernel: NetBSD 3.0 (DF) X-BeenThere: bug-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:15874 Archived-At: I found a possible problem, which may or may not be relevant to this issue, in the initialization of the recursive mutex in src/gmalloc.c. Could you try this patch? YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp Index: src/gmalloc.c =================================================================== RCS file: /cvsroot/emacs/emacs/src/gmalloc.c,v retrieving revision 1.21 diff -c -p -r1.21 gmalloc.c *** src/gmalloc.c 28 Mar 2007 08:16:05 -0000 1.21 --- src/gmalloc.c 14 Jun 2007 02:03:33 -0000 *************** extern __malloc_size_t _bytes_free; *** 235,240 **** --- 235,243 ---- extern __ptr_t _malloc_internal PP ((__malloc_size_t __size)); extern __ptr_t _realloc_internal PP ((__ptr_t __ptr, __malloc_size_t __size)); extern void _free_internal PP ((__ptr_t __ptr)); + extern __ptr_t _malloc_internal_nolock PP ((__malloc_size_t __size)); + extern __ptr_t _realloc_internal_nolock PP ((__ptr_t __ptr, __malloc_size_t __size)); + extern void _free_internal_nolock PP ((__ptr_t __ptr)); #ifdef USE_PTHREAD extern pthread_mutex_t _malloc_mutex; *************** register_heapinfo () *** 554,560 **** #ifdef USE_PTHREAD static pthread_once_t malloc_init_once_control = PTHREAD_ONCE_INIT; ! pthread_mutex_t _malloc_mutex; #endif static void --- 557,563 ---- #ifdef USE_PTHREAD static pthread_once_t malloc_init_once_control = PTHREAD_ONCE_INIT; ! pthread_mutex_t _malloc_mutex = PTHREAD_MUTEX_INITIALIZER; #endif static void *************** malloc_initialize_1 () *** 567,573 **** if (__malloc_initialize_hook) (*__malloc_initialize_hook) (); ! #ifdef USE_PTHREAD { pthread_mutexattr_t attr; --- 570,578 ---- if (__malloc_initialize_hook) (*__malloc_initialize_hook) (); ! /* We don't use recursive mutex because pthread_mutexattr_init may ! call malloc internally. */ ! #if 0 /* defined (USE_PTHREAD) */ { pthread_mutexattr_t attr; *************** morecore (size) *** 661,667 **** `morecore_recursing' flag and return null. */ int save = errno; /* Don't want to clobber errno with ENOMEM. */ morecore_recursing = 1; ! newinfo = (malloc_info *) _realloc_internal (_heapinfo, newsize * sizeof (malloc_info)); morecore_recursing = 0; if (newinfo == NULL) --- 666,672 ---- `morecore_recursing' flag and return null. */ int save = errno; /* Don't want to clobber errno with ENOMEM. */ morecore_recursing = 1; ! newinfo = (malloc_info *) _realloc_internal_nolock (_heapinfo, newsize * sizeof (malloc_info)); morecore_recursing = 0; if (newinfo == NULL) *************** morecore (size) *** 717,723 **** /* Reset _heaplimit so _free_internal never decides it can relocate or resize the info table. */ _heaplimit = 0; ! _free_internal (oldinfo); PROTECT_MALLOC_STATE (0); /* The new heap limit includes the new table just allocated. */ --- 722,728 ---- /* Reset _heaplimit so _free_internal never decides it can relocate or resize the info table. */ _heaplimit = 0; ! _free_internal_nolock (oldinfo); PROTECT_MALLOC_STATE (0); /* The new heap limit includes the new table just allocated. */ *************** morecore (size) *** 732,738 **** /* Allocate memory from the heap. */ __ptr_t ! _malloc_internal (size) __malloc_size_t size; { __ptr_t result; --- 737,743 ---- /* Allocate memory from the heap. */ __ptr_t ! _malloc_internal_nolock (size) __malloc_size_t size; { __ptr_t result; *************** _malloc_internal (size) *** 752,758 **** return NULL; #endif - LOCK (); PROTECT_MALLOC_STATE (0); if (size < sizeof (struct list)) --- 757,762 ---- *************** _malloc_internal (size) *** 802,811 **** /* No free fragments of the desired size, so get a new block and break it into fragments, returning the first. */ #ifdef GC_MALLOC_CHECK ! result = _malloc_internal (BLOCKSIZE); PROTECT_MALLOC_STATE (0); #else ! result = malloc (BLOCKSIZE); #endif if (result == NULL) { --- 806,815 ---- /* No free fragments of the desired size, so get a new block and break it into fragments, returning the first. */ #ifdef GC_MALLOC_CHECK ! result = _malloc_internal_nolock (BLOCKSIZE); PROTECT_MALLOC_STATE (0); #else ! result = _malloc_internal_nolock (BLOCKSIZE); #endif if (result == NULL) { *************** _malloc_internal (size) *** 932,938 **** --- 936,954 ---- PROTECT_MALLOC_STATE (1); out: + return result; + } + + __ptr_t + _malloc_internal (size) + __malloc_size_t size; + { + __ptr_t result; + + LOCK (); + result = _malloc_internal_nolock (size); UNLOCK (); + return result; } *************** void (*__free_hook) PP ((__ptr_t __ptr)) *** 1024,1032 **** struct alignlist *_aligned_blocks = NULL; /* Return memory to the heap. ! Like `free' but don't call a __free_hook if there is one. */ void ! _free_internal (ptr) __ptr_t ptr; { int type; --- 1040,1048 ---- struct alignlist *_aligned_blocks = NULL; /* Return memory to the heap. ! Like `_free_internal' but don't lock mutex. */ void ! _free_internal_nolock (ptr) __ptr_t ptr; { int type; *************** _free_internal (ptr) *** 1043,1049 **** if (ptr == NULL) return; - LOCK (); PROTECT_MALLOC_STATE (0); for (l = _aligned_blocks; l != NULL; l = l->next) --- 1059,1064 ---- *************** _free_internal (ptr) *** 1158,1164 **** table's blocks to the system before we have copied them to the new location. */ _heaplimit = 0; ! _free_internal (_heapinfo); _heaplimit = oldlimit; /* Tell malloc to search from the beginning of the heap for --- 1173,1179 ---- table's blocks to the system before we have copied them to the new location. */ _heaplimit = 0; ! _free_internal_nolock (_heapinfo); _heaplimit = oldlimit; /* Tell malloc to search from the beginning of the heap for *************** _free_internal (ptr) *** 1166,1173 **** _heapindex = 0; /* Allocate new space for the info table and move its data. */ ! newinfo = (malloc_info *) _malloc_internal (info_blocks ! * BLOCKSIZE); PROTECT_MALLOC_STATE (0); memmove (newinfo, _heapinfo, info_blocks * BLOCKSIZE); _heapinfo = newinfo; --- 1181,1188 ---- _heapindex = 0; /* Allocate new space for the info table and move its data. */ ! newinfo = (malloc_info *) _malloc_internal_nolock (info_blocks ! * BLOCKSIZE); PROTECT_MALLOC_STATE (0); memmove (newinfo, _heapinfo, info_blocks * BLOCKSIZE); _heapinfo = newinfo; *************** _free_internal (ptr) *** 1231,1239 **** _bytes_free -= BLOCKSIZE; #ifdef GC_MALLOC_CHECK ! _free_internal (ADDRESS (block)); #else ! free (ADDRESS (block)); #endif } else if (_heapinfo[block].busy.info.frag.nfree != 0) --- 1246,1254 ---- _bytes_free -= BLOCKSIZE; #ifdef GC_MALLOC_CHECK ! _free_internal_nolock (ADDRESS (block)); #else ! _free_internal_nolock (ADDRESS (block)); #endif } else if (_heapinfo[block].busy.info.frag.nfree != 0) *************** _free_internal (ptr) *** 1269,1274 **** --- 1284,1299 ---- } PROTECT_MALLOC_STATE (1); + } + + /* Return memory to the heap. + Like `free' but don't call a __free_hook if there is one. */ + void + _free_internal (ptr) + __ptr_t ptr; + { + LOCK (); + _free_internal_nolock (ptr); UNLOCK (); } *************** __ptr_t (*__realloc_hook) PP ((__ptr_t _ *** 1415,1421 **** new region. This module has incestuous knowledge of the internals of both free and malloc. */ __ptr_t ! _realloc_internal (ptr, size) __ptr_t ptr; __malloc_size_t size; { --- 1440,1446 ---- new region. This module has incestuous knowledge of the internals of both free and malloc. */ __ptr_t ! _realloc_internal_nolock (ptr, size) __ptr_t ptr; __malloc_size_t size; { *************** _realloc_internal (ptr, size) *** 1425,1439 **** if (size == 0) { ! _free_internal (ptr); ! return _malloc_internal (0); } else if (ptr == NULL) ! return _malloc_internal (size); block = BLOCK (ptr); - LOCK (); PROTECT_MALLOC_STATE (0); type = _heapinfo[block].busy.type; --- 1450,1463 ---- if (size == 0) { ! _free_internal_nolock (ptr); ! return _malloc_internal_nolock (0); } else if (ptr == NULL) ! return _malloc_internal_nolock (size); block = BLOCK (ptr); PROTECT_MALLOC_STATE (0); type = _heapinfo[block].busy.type; *************** _realloc_internal (ptr, size) *** 1443,1453 **** /* Maybe reallocate a large block to a small fragment. */ if (size <= BLOCKSIZE / 2) { ! result = _malloc_internal (size); if (result != NULL) { memcpy (result, ptr, size); ! _free_internal (ptr); goto out; } } --- 1467,1477 ---- /* Maybe reallocate a large block to a small fragment. */ if (size <= BLOCKSIZE / 2) { ! result = _malloc_internal_nolock (size); if (result != NULL) { memcpy (result, ptr, size); ! _free_internal_nolock (ptr); goto out; } } *************** _realloc_internal (ptr, size) *** 1467,1473 **** Now we will free this chunk; increment the statistics counter so it doesn't become wrong when _free_internal decrements it. */ ++_chunks_used; ! _free_internal (ADDRESS (block + blocks)); result = ptr; } else if (blocks == _heapinfo[block].busy.info.size) --- 1491,1497 ---- Now we will free this chunk; increment the statistics counter so it doesn't become wrong when _free_internal decrements it. */ ++_chunks_used; ! _free_internal_nolock (ADDRESS (block + blocks)); result = ptr; } else if (blocks == _heapinfo[block].busy.info.size) *************** _realloc_internal (ptr, size) *** 1482,1489 **** /* Prevent free from actually returning memory to the system. */ oldlimit = _heaplimit; _heaplimit = 0; ! _free_internal (ptr); ! result = _malloc_internal (size); PROTECT_MALLOC_STATE (0); if (_heaplimit == 0) _heaplimit = oldlimit; --- 1506,1513 ---- /* Prevent free from actually returning memory to the system. */ oldlimit = _heaplimit; _heaplimit = 0; ! _free_internal_nolock (ptr); ! result = _malloc_internal_nolock (size); PROTECT_MALLOC_STATE (0); if (_heaplimit == 0) _heaplimit = oldlimit; *************** _realloc_internal (ptr, size) *** 1493,1505 **** the thing we just freed. Unfortunately it might have been coalesced with its neighbors. */ if (_heapindex == block) ! (void) _malloc_internal (blocks * BLOCKSIZE); else { __ptr_t previous ! = _malloc_internal ((block - _heapindex) * BLOCKSIZE); ! (void) _malloc_internal (blocks * BLOCKSIZE); ! _free_internal (previous); } goto out; } --- 1517,1529 ---- the thing we just freed. Unfortunately it might have been coalesced with its neighbors. */ if (_heapindex == block) ! (void) _malloc_internal_nolock (blocks * BLOCKSIZE); else { __ptr_t previous ! = _malloc_internal_nolock ((block - _heapindex) * BLOCKSIZE); ! (void) _malloc_internal_nolock (blocks * BLOCKSIZE); ! _free_internal_nolock (previous); } goto out; } *************** _realloc_internal (ptr, size) *** 1519,1536 **** { /* The new size is different; allocate a new space, and copy the lesser of the new size and the old. */ ! result = _malloc_internal (size); if (result == NULL) goto out; memcpy (result, ptr, min (size, (__malloc_size_t) 1 << type)); ! _free_internal (ptr); } break; } PROTECT_MALLOC_STATE (1); out: UNLOCK (); return result; } --- 1543,1573 ---- { /* The new size is different; allocate a new space, and copy the lesser of the new size and the old. */ ! result = _malloc_internal_nolock (size); if (result == NULL) goto out; memcpy (result, ptr, min (size, (__malloc_size_t) 1 << type)); ! _free_internal_nolock (ptr); } break; } PROTECT_MALLOC_STATE (1); out: + return result; + } + + __ptr_t + _realloc_internal (ptr, size) + __ptr_t ptr; + __malloc_size_t size; + { + __ptr_t result; + + LOCK(); + result = _realloc_internal_nolock (ptr, size); UNLOCK (); + return result; }