unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
To: Gary Mills <mills@cc.umanitoba.ca>
Cc: bug-gnu-emacs@gnu.org
Subject: Re: emacs-22.1 with GTK dumps core when Gnome wigets clicked
Date: Sat, 16 Jun 2007 14:22:54 +0900	[thread overview]
Message-ID: <wlsl8swk0h.wl%mituharu@math.s.chiba-u.ac.jp> (raw)
In-Reply-To: <20070614184924.GA25414@cc.umanitoba.ca>

>>>>> On Thu, 14 Jun 2007 13:49:25 -0500, Gary Mills <mills@cc.umanitoba.ca> said:

>> 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?

> I'm sorry to report that it still dumps core when I click on one of
> those icons.

I've set up Solaris 10 11/06 SPARC with Sun Studio 11 and tried
making/running the GTK+ build, but couldn't reproduce the crash even
with unmodified Emacs 22.1.  That may be because mine is a
uniprocessor machine.  What about yours?

Could you try yet another patch below and identify the line in the
source code where the crash occurs?

				     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	16 Jun 2007 05:15:04 -0000
*************** extern __malloc_size_t _bytes_free;
*** 235,248 ****
  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));
  
  #ifdef USE_PTHREAD
! extern pthread_mutex_t _malloc_mutex;
  #define LOCK()     pthread_mutex_lock (&_malloc_mutex)
  #define UNLOCK()   pthread_mutex_unlock (&_malloc_mutex)
  #else
  #define LOCK()
  #define UNLOCK()
  #endif
  
  #endif /* _MALLOC_INTERNAL.  */
--- 235,255 ----
  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, _aligned_blocks_mutex;
  #define LOCK()     pthread_mutex_lock (&_malloc_mutex)
  #define UNLOCK()   pthread_mutex_unlock (&_malloc_mutex)
+ #define LOCK_ALIGNED_BLOCKS()     pthread_mutex_lock (&_aligned_blocks_mutex)
+ #define UNLOCK_ALIGNED_BLOCKS()   pthread_mutex_unlock (&_aligned_blocks_mutex)
  #else
  #define LOCK()
  #define UNLOCK()
+ #define LOCK_ALIGNED_BLOCKS()
+ #define UNLOCK_ALIGNED_BLOCKS()
  #endif
  
  #endif /* _MALLOC_INTERNAL.  */
*************** 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
--- 561,568 ----
  
  #ifdef USE_PTHREAD
  static pthread_once_t malloc_init_once_control = PTHREAD_ONCE_INIT;
! pthread_mutex_t _malloc_mutex = PTHREAD_MUTEX_INITIALIZER;
! pthread_mutex_t _aligned_blocks_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;
  
--- 575,583 ----
    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;
  
*************** static int morecore_recursing;
*** 616,624 ****
  
  /* Get neatly aligned memory, initializing or
     growing the heap info table as necessary. */
! static __ptr_t morecore PP ((__malloc_size_t));
  static __ptr_t
! morecore (size)
       __malloc_size_t size;
  {
    __ptr_t result;
--- 626,634 ----
  
  /* Get neatly aligned memory, initializing or
     growing the heap info table as necessary. */
! static __ptr_t morecore_nolock PP ((__malloc_size_t));
  static __ptr_t
! morecore_nolock (size)
       __malloc_size_t size;
  {
    __ptr_t result;
*************** 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)
--- 671,677 ----
  	     `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.  */
--- 727,733 ----
        /* 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;
--- 742,748 ----
  
  /* 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))
--- 762,767 ----
*************** _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)
  	    {
--- 811,820 ----
  	  /* 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)
*** 874,880 ****
   		  _heaplimit += wantblocks - lastblocks;
  		  continue;
  		}
! 	      result = morecore (wantblocks * BLOCKSIZE);
  	      if (result == NULL)
  		goto out;
  	      block = BLOCK (result);
--- 883,889 ----
   		  _heaplimit += wantblocks - lastblocks;
  		  continue;
  		}
! 	      result = morecore_nolock (wantblocks * BLOCKSIZE);
  	      if (result == NULL)
  		goto out;
  	      block = BLOCK (result);
*************** _malloc_internal (size)
*** 932,938 ****
--- 941,959 ----
  
    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;
--- 1045,1053 ----
  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,1051 ****
    if (ptr == NULL)
      return;
  
-   LOCK ();
    PROTECT_MALLOC_STATE (0);
  
    for (l = _aligned_blocks; l != NULL; l = l->next)
      if (l->aligned == ptr)
        {
--- 1064,1072 ----
    if (ptr == NULL)
      return;
  
    PROTECT_MALLOC_STATE (0);
  
+   LOCK_ALIGNED_BLOCKS ();
    for (l = _aligned_blocks; l != NULL; l = l->next)
      if (l->aligned == ptr)
        {
*************** _free_internal (ptr)
*** 1053,1058 ****
--- 1074,1080 ----
  	ptr = l->exact;
  	break;
        }
+   UNLOCK_ALIGNED_BLOCKS ();
  
    block = BLOCK (ptr);
  
*************** _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
--- 1180,1186 ----
  		 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;
--- 1188,1195 ----
  	      _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)
--- 1253,1261 ----
  	  _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 ****
--- 1291,1306 ----
      }
  
    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;
  {
--- 1447,1453 ----
     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;
--- 1457,1470 ----
  
    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;
  	    }
  	}
--- 1474,1484 ----
        /* 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)
--- 1498,1504 ----
  	     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;
--- 1513,1520 ----
  	  /* 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;
  	    }
--- 1524,1536 ----
  		 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;
  }
  
--- 1550,1580 ----
  	{
  	  /* 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;
  }
  
*************** memalign (alignment, size)
*** 1718,1723 ****
--- 1762,1768 ----
  	 of an allocated block.  */
  
        struct alignlist *l;
+       LOCK_ALIGNED_BLOCKS ();
        for (l = _aligned_blocks; l != NULL; l = l->next)
  	if (l->aligned == NULL)
  	  /* This slot is free.  Use it.  */
*************** memalign (alignment, size)
*** 1728,1740 ****
  	  if (l == NULL)
  	    {
  	      free (result);
! 	      return NULL;
  	    }
  	  l->next = _aligned_blocks;
  	  _aligned_blocks = l;
  	}
        l->exact = result;
        result = l->aligned = (char *) result + alignment - adj;
      }
  
    return result;
--- 1773,1788 ----
  	  if (l == NULL)
  	    {
  	      free (result);
! 	      result = NULL;
! 	      goto out;
  	    }
  	  l->next = _aligned_blocks;
  	  _aligned_blocks = l;
  	}
        l->exact = result;
        result = l->aligned = (char *) result + alignment - adj;
+     out:
+       UNLOCK_ALIGNED_BLOCKS ();
      }
  
    return result;

  parent reply	other threads:[~2007-06-16  5:22 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-09 15:49 emacs-22.1 with GTK dumps core when Gnome wigets clicked Gary Mills
2007-06-10  8:43 ` YAMAMOTO Mitsuharu
2007-06-10 12:51   ` Gary Mills
2007-06-10 13:48     ` YAMAMOTO Mitsuharu
2007-06-10 14:10       ` Gary Mills
2007-06-14  2:16         ` YAMAMOTO Mitsuharu
     [not found]           ` <20070614184924.GA25414@cc.umanitoba.ca>
2007-06-16  5:22             ` YAMAMOTO Mitsuharu [this message]
2007-06-16 13:32               ` Gary Mills
2007-06-16 14:30               ` Gary Mills
2007-06-16 15:40                 ` Gary Mills
2007-06-17  6:41                   ` YAMAMOTO Mitsuharu
2007-06-17 16:01                     ` Gary Mills
2007-06-18  1:08                       ` YAMAMOTO Mitsuharu
2007-06-18  3:03                         ` Gary Mills
2007-06-18  9:58                           ` YAMAMOTO Mitsuharu
2007-06-16 18:51           ` Richard Stallman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=wlsl8swk0h.wl%mituharu@math.s.chiba-u.ac.jp \
    --to=mituharu@math.s.chiba-u.ac.jp \
    --cc=bug-gnu-emacs@gnu.org \
    --cc=mills@cc.umanitoba.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).