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.000000000 +0000 +++ bash-2.05a/lib/malloc/malloc.c 2005-06-14 17:19:00.000000000 +0000 @@ -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 <Address 0x10b out of > bounds>) > at parse.y:3667 > 3667 result = (char *)xmalloc (result_size = PROMPT_GROWTH); > (gdb) c > Continuing. > [EMAIL PROTECTED] bin]# ulimit -c 100000 > > Breakpoint 1, decode_prompt_string (string=0x10b <Address 0x10b out of > bounds>) > at parse.y:3667 > 3667 result = (char *)xmalloc (result_size = PROMPT_GROWTH); > (gdb) c > Continuing. > [EMAIL PROTECTED] bin]# ulimit -c 10000000000 > > Breakpoint 1, decode_prompt_string (string=0x10b <Address 0x10b out of > bounds>) > at parse.y:3667 > 3667 result = (char *)xmalloc (result_size = PROMPT_GROWTH); > (gdb) c > Continuing. > [EMAIL PROTECTED] bin]# ls > core.23751 bash > : > > Breakpoint 1, decode_prompt_string (string=0x10b <Address 0x10b out of > bounds>) > at parse.y:3667 > 3667 result = (char *)xmalloc (result_size = PROMPT_GROWTH); > (gdb) break malloc.c:662 > Breakpoint 2 at 0x80ad936: file malloc.c, line 662. > (gdb) c > Continuing. > > Breakpoint 2, internal_malloc (n=48, > file=0x80b01c0 "/usr/src/bash/src/parse.y", line=3667, flags=1) > at malloc.c:662 > 662 if ((p = nextf[nunits]) == NULL) > > > (gdb) signal SIGHUP > Continuing with signal SIGHUP. > > Breakpoint 2, internal_malloc (n=20, file=0x0, line=0, flags=0) at > malloc.c:662 > 662 if ((p = nextf[nunits]) == NULL) > (gdb) c > Continuing. > > Breakpoint 2, internal_malloc (n=42, file=0x0, line=0, flags=0) at > malloc.c:662 > 662 if ((p = nextf[nunits]) == NULL) > (gdb) c > Continuing. > > malloc: unknown:0: assertion botched > free: underflow detected; mh_nbytes out of range > last command: ls > Stopping myself... > Program received signal SIGABRT, Aborted. > 0xffffe002 in ?? () > (gdb) c > Continuing. > > Program received signal SIGABRT, Aborted. > 0xffffe002 in ?? () > (gdb) bt > #0 0xffffe002 in ?? () > #1 0x42028a73 in abort () from /lib/tls/libc.so.6 > #2 0x0806c733 in programming_error ( > format=0x80c2b40 "free: underflow detected; mh_nbytes out of range") at > error.c:258 > #3 0x080adac4 in internal_free (mem=0x80daa08, file=0x0, line=0, flags=0) > at > malloc.c:759 > #4 0x080adfd4 in free (mem=0x80daa08) at malloc.c:1073 > #5 0x080aae93 in history_do_write (filename=0x80d3968 > "/root/.bash_history", > nelements=3, > overwrite=0) at histfile.c:381 > #6 0x080aaeff in append_history (nelements=3, filename=0x80d3968 > "/root/.bash_history") > at histfile.c:398 > #7 0x0808068a in maybe_save_shell_history () at bashhist.c:344 > #8 0x0807c694 in termination_unwind_protect (sig=1) at sig.c:409 > #9 <signal handler called> > #10 internal_malloc (n=48, file=0x80b01c0 > "/usr/src/bash/src/parse.y", > line=3667, flags=134627174) at malloc.c:662 > #11 0x080adeee in sh_malloc (bytes=48, > file=0x80b01c0 "/usr/src/bash/src/parse.y", line=3667) at > malloc.c:987 > #12 0x080890e9 in sh_xmalloc (bytes=48, > file=0x80b01c0 "/usr/src/parse.y", line=3667) at > xmalloc.c:143 > #13 0x080600fe in decode_prompt_string (string=0x80d9b48 "[EMAIL PROTECTED] > \\W]\\$ > ") > at parse.y:3667 > #14 0x0806005a in prompt_again () at parse.y:3583 > #15 0x0805d791 in yylex () at parse.y:1964 > #16 0x0805c80e in yyparse () at bison.simple:432 > #17 0x0805b7cf in parse_command () at eval.c:213 > #18 0x0805b83e in read_command () at eval.c:257 > #19 0x0805b583 in reader_loop () at eval.c:124 > #20 0x08059beb in main (argc=1, argv=0xbfffeb74, env=0xbfffeb7c) at > shell.c:668 > #21 0x42015574 in __libc_start_main () from /lib/tls/libc.so.6 > > > > _______________________________________________ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash