This problem can be fixed by applying part of the update from 2.05a to 2.05b
in
lib/malloc/malloc.c. The relevent sections are as follows:
--- bash-2.05a.orig/lib/malloc/malloc.c 2001-10-04 12:13:16.0 +
+++ bash-2.05a/lib/malloc/malloc.c 2005-06-14 17:19:00.0 +
@@ -202,9 +202,16 @@
#define ERR_ASSERT_FAILED 0x08
/* Evaluates to true if NB is appropriate for bucket NU. NB is adjusted
- appropriately by the caller to account for malloc overhead. */
-#define IN_BUCKET(nb, nu) \
- ((nb) > (4 << (nu)) && ((nb) <= (8 << (nu
+ appropriately by the caller to account for malloc overhead. This only
+ checks that the recorded size is not too big for the bucket. We
+ can't check whether or not it's in between NU and NU-1 because we
+ might have encountered a busy bucket when allocating and moved up to
+ the next size.*/
+#define IN_BUCKET(nb, nu) ((nb) <= binsizes[(nu)])
+
+/* Use this when we want to be sure that NB is in bucket NU. */
+#define RIGHT_BUCKET(nb, nu) \
+(((nb) > binsizes[(nu)-1]) && ((nb) <= binsizes[(nu)]))
/* nextf[i] is free list of blocks of size 2**(i + 3) */
@@ -218,6 +225,17 @@
static int pagebucket; /* bucket for requests a page in size */
static int maxbuck;/* highest bucket receiving allocation request. */
+static unsigned long binsizes[NBUCKETS] = {
+ 8UL, 16UL, 32UL, 64UL, 128UL, 256UL, 512UL, 1024UL, 2048UL, 4096UL,
+ 8192UL, 16384UL, 32768UL, 65536UL, 131072UL, 262144UL, 524288UL,
+ 1048576UL, 2097152UL, 4194304UL, 8388608UL, 16777216UL, 33554432UL,
+ 67108864UL, 134217728UL, 268435456UL, 536870912UL, 1073741824UL,
+ 2147483648UL, 4294967295UL
+};
+
+/* binsizes[x] == (1 << ((x) + 3)) */
+#define binsize(x) binsizes[(x)]
+
/* Declarations for internal functions */
static PTR_T internal_malloc __P((size_t, const char *, int, int));
static PTR_T internal_realloc __P((PTR_T, size_t, const char *, int, int));
@@ -753,8 +771,10 @@
We sanity-check the value of mh_nbytes against the size of the blocks
in the appropriate bucket before we use it. This can still cause
problems
and obscure errors if mh_nbytes is wrong but still within range; the
- checks against MAGIC1 will probably fail then. Using MALLOC_REGISTER
- will help here, since it saves the original number of bytes requested.
*/
+ checks against the size recorded at the end of the chunk will probably
+ fail then. Using MALLOC_REGISTER will help here, since it saves the
+ original number of bytes requested. */
+
if (IN_BUCKET(nbytes, nunits) == 0)
xbotch (mem, ERR_UNDERFLOW,
"free: underflow detected; mh_nbytes out of range", file, line);
@@ -837,8 +857,9 @@
We sanity-check the value of mh_nbytes against the size of the blocks
in the appropriate bucket before we use it. This can still cause
problems
and obscure errors if mh_nbytes is wrong but still within range; the
- checks against MAGIC1 will probably fail then. Using MALLOC_REGISTER
- will help here, since it saves the original number of bytes requested.
*/
+ checks against the size recorded at the end of the chunk will probably
+ fail then. Using MALLOC_REGISTER will help here, since it saves the
+ original number of bytes requested. */
if (IN_BUCKET(nbytes, nunits) == 0)
xbotch (mem, ERR_UNDERFLOW,
"realloc: underflow detected; mh_nbytes out of range", file, line);
@@ -851,7 +872,7 @@
nbytes = ALLOCATED_BYTES(n);
/* If ok, use the same block, just marking its size as changed. */
- if (IN_BUCKET(nbytes, nunits))
+ if (RIGHT_BUCKET(nbytes, nunits))
{
m = (char *)mem + tocopy;
*m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0;
---
"Tom Robinson" <[EMAIL PROTECTED]> wrote in message
news:[EMAIL PROTECTED]
...
> I have seen bash dump core a few times. It is extremely difficult to
> reproduce naturally.
> The problem occurs when a SIGHUP is received during a malloc by bash.
> After examining
> the backtrace of the core, I am able to reproduce the problem using gbd.
> I have been able to
> reproduce this on a number of different platforms. After the SIGHUP, bash
> calls a handler
> to clean up, write the history, etc. But it calls free() from
> history_do_write() which in turn
> calls internal_free() where the problem occurs. There is a comment right
> before the xbotch()
> but I can't tell if that is relevant here.
>
> Any help on this would be appreciated.
>
> Repeat-By:
>
> # gdb bash
>:
> (gdb) break decode_prompt_string
> Breakpoint 1 at 0x80600e0: file parse.y, line 3667.
> (gdb) r
> Starting program: bash
>
> Breakpoint 1, decode_prompt_string (string=0x10b bounds>)
>at parse.y:3667
> 3667 result = (char *)xm