Date: Thu, 13 Oct 2005 21:30:23 GMT From: Nate Eldredge <nge@cs.hmc.edu> To: freebsd-bugs@FreeBSD.org Subject: Re: bin/45478: /bin/sh coredump Message-ID: <200510132130.j9DLUNga071234@freefall.freebsd.org>
index | next in thread | raw e-mail
The following reply was made to PR bin/45478; it has been noted by GNATS.
From: Nate Eldredge <nge@cs.hmc.edu>
To: bug-followup@FreeBSD.org, olli@secnetix.de
Cc: keramida@freebsd.org
Subject: Re: bin/45478: /bin/sh coredump
Date: Thu, 13 Oct 2005 14:24:07 -0700 (PDT)
I have reproduced this and have a fix. It does seem to have been
INTON/INTOFF. To find where the signal was being handled inside malloc,
in gdb you can do
handle SIGINT nostop pass
(answer yes)
break exraise
command
where
continue
end
run
which will print a stack trace every time it handles the signal. Then you
look for malloc inside the trace.
I found the following offenders:
#11 0x0805bba7 in redirect (redir=0x0, flags=1) at redir.c:111
#11 0x0805e1a3 in setvar (name=0x80dd76e "_", val=0x810d0ac "true",
flags=0) at var.c:246
However, a casual glance revealed several other un-wrapped calls. 90% of
these are made via ckmalloc/ckrealloc/ckfree. Thus I think the easiest
and safest thing to do is to call INTON/INTOFF inside these functions.
They are safe to use recursively and have trivial overhead (incrementing a
counter). Here is a patch which does this. It is against CURRENT but I
imagine it will apply to other versions as well. After this patch I
cannot make it crash anymore.
I found only one unsafe use of malloc/free directly: in the umask builtin.
umaskcmd() calls setmode() which calls malloc, and then calls free. My
patch puts INTON/INTOFF around this as well.
By the way, I think the CPU usage thing is a red herring. I assume the
numbers are from top, and its CPU field is an average. It definitely
decays slowly to 0 after a process has been running, so it can report
nonzero even for a totally idle process. sh gets commands from the user
with a blocking read, so it must be idle while waiting for input.
diff -ur /usr/src/bin/sh/memalloc.c ./src/bin/sh/memalloc.c
--- /usr/src/bin/sh/memalloc.c Tue Apr 6 13:06:51 2004
+++ ./src/bin/sh/memalloc.c Thu Oct 13 14:02:30 2005
@@ -57,8 +57,10 @@
{
pointer p;
+ INTOFF;
if ((p = malloc(nbytes)) == NULL)
error("Out of space");
+ INTON;
return p;
}
@@ -70,11 +72,20 @@
pointer
ckrealloc(pointer p, int nbytes)
{
+ INTOFF;
if ((p = realloc(p, nbytes)) == NULL)
error("Out of space");
+ INTON;
return p;
}
+void
+ckfree(pointer p)
+{
+ INTOFF;
+ free(p);
+ INTON;
+}
/*
* Make a copy of a string in safe storage.
diff -ur /usr/src/bin/sh/memalloc.h ./src/bin/sh/memalloc.h
--- /usr/src/bin/sh/memalloc.h Tue Apr 6 13:06:51 2004
+++ ./src/bin/sh/memalloc.h Thu Oct 13 14:01:27 2005
@@ -48,6 +48,7 @@
pointer ckmalloc(int);
pointer ckrealloc(pointer, int);
+void ckfree(pointer);
char *savestr(char *);
pointer stalloc(int);
void stunalloc(pointer);
@@ -72,5 +73,3 @@
#define STTOPC(p) p[-1]
#define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount))
#define grabstackstr(p) stalloc(stackblocksize() - sstrnleft)
-
-#define ckfree(p) free((pointer)(p))
diff -ur /usr/src/bin/sh/miscbltin.c ./src/bin/sh/miscbltin.c
--- /usr/src/bin/sh/miscbltin.c Fri Sep 9 12:59:41 2005
+++ ./src/bin/sh/miscbltin.c Thu Oct 13 14:00:13 2005
@@ -274,12 +274,14 @@
umask(mask);
} else {
void *set;
+ INTOFF;
if ((set = setmode (ap)) == 0)
error("Illegal number: %s", ap);
mask = getmode (set, ~mask & 0777);
umask(~mask & 0777);
free(set);
+ INTON;
}
}
return 0;
--
Nate Eldredge
nge@cs.hmc.edu
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200510132130.j9DLUNga071234>
