bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: core dump on SIGHUP


From: Tom Robinson
Subject: Re: core dump on SIGHUP
Date: Tue, 14 Jun 2005 15:58:04 -0700

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" <trobinson@mvista.com> wrote in message 
news:mailman.54.1118728847.2837.bug-bash@gnu.org...
...
> 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.
> [root@walstib 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.
> [root@walstib 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.
> [root@walstib 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 "[\\u@\\h \\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
>
>
>
> 






reply via email to

[Prev in Thread] Current Thread [Next in Thread]