This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

gcc-3.4.0: mt_allocator crashes due to alignment problems on SPARC targets when sizeof(type) <= 2


It appears that when sizeof(type) is less than or equal to 2, the
mt_allocator does not ensure proper alignment of the block_record
structures when building the freelists.   This causes the allocator
code itself to crash during initialization.

On sparc-sun-solaris2.8 with gcc-3.4.0, the following small program
crashes with a bus error when TEST_SIZE <= 2.

  #include <memory>
  
  struct a { char a[TEST_SIZE]; };
  
  int
  main()
  {
    std::allocator<a> x;
    x.allocate(1);
    return 0;
  }

I'm using a single-threaded build, so the offending code starts at
around line 391 of mt_allocator.h, but it appears in similar form in
two places.  An excerpt from line 391:

  block_count--;
  block = __bin.first[0];
  while (block_count > 0)
    {
      char* __c = reinterpret_cast<char*>(block) + bin_size;
      block->next = reinterpret_cast<block_record*>(__c);
      block = block->next;
      block_count--;
    }
  block->next = NULL;

Note that __bin.first[0] comes from memory allocated with ::operator
new(), so it is properly aligned.  The initialization of the first
block works as a result, but bin_size is 5 (sizeof(void *) +
sizeof(bool)), so after the first iteration, "block->next" becomes an
illegal address for multibyte access, and crashes.

I think all that has to happen is for bin_size to be rounded up to the
minimum (not necessarily the most time efficient) alignment for the
architecture.  This might mean that bins with a size less than that
minimum alignment are simply not usable (i.e. not useful) on such
architectures?  That is, perhaps we may as well not have a bin size
less than the minimum alignment size we'd have to pad it anyway?

I'm not familiar with the details of the new mt_allocator
implementation, but I can work up a patch attempt if necessary.  Just
let me know if I should.  (BTW, I found this when boost::regex crashed
in a constructor on this target.)  I started out by just changing
the _S_initialize() __bin_size and __bin_max to 2 as an experiment,
but that didn't appear to be enough. :(

Also, I wasn't aware that the default allocator had become "new", at
least for Solaris targets.  Was this intentional?

One more detail: Is it intentional that _S_init is never set to true
when _S_options._M_force_new is true?  It's not causing problems, but
it does mean _S_initialize() is called (and then immediately
short-circuited) on every allocation, which confused me while
debugging. 

-- 
------------------------------------------------------------------
Brad Spencer - spencer@infointeractive.com - "It's quite nice..."
Systems Architect | InfoInterActive Corp. | A Canadian AOL Company


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]