Mail Archives: cygwin/2000/09/27/13:04:26
------_=_NextPart_000_01C028A3.2B0BBD06
Content-Type: text/plain;
charset="iso-8859-1"
Hi all,
(I'm not sure who to send this to, because I can't quite work
out where ash comes from! Hopefully this is a reasonable
first try ...)
I think I've found and fixed a segfault in ash 20000823 (from
Cygwin). I have a feeling that this has been around since b20
or before -- I definitely saw a similar one there, which I fixed
by changing to bash for this particular script -- but I don't
have that installed any more to confirm that it's the same one.
The problem occurs infrequently, when a large string value
(>504 chars, I think!) is assigned to a variable. In ash-
source-speak, what happens is that the current stack
position is saved via a call to setstackmark, but then before
it is freed again in popstackmark, a call to growstackblock
moves the stack block which has been saved. Then when
the time comes to free it, the free is passed an invalid
pointer, and basically, it all goes horribly wrong. (All these
routines are in memalloc.c)
The attached patch adds a new member to the stack_block
structure which is initially set to zero, but is incremented if
setstackmark is called on a particular stack_block. If this
member is non-zero in growstackblock, even if no data is
actually allocated in that block, it will still go ahead and
create another one and leave the previous one in place.
This is all at the cost of an extra 4 bytes in a stack_block,
but looking at the average length of the block chain for the
sorts of runs I've been doing (about 4 or 5 for most of the
time, I think), I don't expect that this is a problem. Wiser
minds than mine may prevail, however.
I've checked that this fixes the problem I was having;
however, I haven't done much more testing than that single
(admittedly many thousand line) script.
Have fun!
Andy
--
Andy Mortimer, CFX-5 Architecture and Infrastructure Team
andy DOT mortimer AT aeat DOT com
------_=_NextPart_000_01C028A3.2B0BBD06
Content-Type: application/octet-stream;
name="memalloc.diff"
Content-Disposition: attachment;
filename="memalloc.diff"
*** memalloc.c.orig Wed Sep 27 17:43:39 2000
--- memalloc.c Wed Sep 27 17:21:57 2000
***************
*** 106,118 ****
*
* The size 504 was chosen because the Ultrix malloc handles that size
* well.
*/
! #define MINSIZE 504 /* minimum size of a block */
struct stack_block {
struct stack_block *prev;
char space[MINSIZE];
};
--- 106,121 ----
*
* The size 504 was chosen because the Ultrix malloc handles that size
* well.
+ *
+ * Reduced to 500 now I've added an extra int -- andy DOT mortimer AT zetnet DOT co DOT uk
*/
! #define MINSIZE 500 /* minimum size of a block */
struct stack_block {
struct stack_block *prev;
+ int refcnt;
char space[MINSIZE];
};
***************
*** 143,148 ****
--- 146,152 ----
sp = ckmalloc(sizeof(struct stack_block) - MINSIZE +
blocksize);
sp->prev = stackp;
+ sp->refcnt = 0;
stacknxt = sp->space;
stacknleft = blocksize;
stackp = sp;
***************
*** 176,183 ****
mark->stackp = stackp;
mark->stacknxt = stacknxt;
mark->stacknleft = stacknleft;
- }
void
popstackmark(mark)
--- 180,188 ----
mark->stackp = stackp;
mark->stacknxt = stacknxt;
mark->stacknleft = stacknleft;
+ stackp->refcnt++;
+ }
void
popstackmark(mark)
***************
*** 186,191 ****
--- 191,197 ----
struct stack_block *sp;
INTOFF;
+ mark->stackp->refcnt--;
while (stackp != mark->stackp) {
sp = stackp;
stackp = sp->prev;
***************
*** 220,226 ****
oldspace = stacknxt;
oldlen = stacknleft;
! if (stacknxt == stackp->space && stackp != &stackbase) {
INTOFF;
sp = stackp;
stackp = sp->prev;
--- 226,233 ----
oldspace = stacknxt;
oldlen = stacknleft;
! if (stacknxt == stackp->space && stackp != &stackbase
! && !stackp->refcnt) {
INTOFF;
sp = stackp;
stackp = sp->prev;
------_=_NextPart_000_01C028A3.2B0BBD06
Content-Type: text/plain; charset=us-ascii
--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe AT sourceware DOT cygnus DOT com
------_=_NextPart_000_01C028A3.2B0BBD06--
- Raw text -