Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: zsh 3.0.7 hogs memory



On Nov 23,  3:17pm, James Kirkpatrick wrote:
} Subject: zsh 3.0.7 hogs memory
}
} It usually seems to happen to people running Pine (4.10).  My guess at
} this point is that they dial in, start pine, and then either disconnect or
} become disconnected.
} 
} One other clue:  This only started happening when I added the following to
} /etc/zshenv:
} 
}   export HISTSIZE=200
}   export HISTFILE=~/.zsh_history
}   export SAVEHIST=200
} 
} Once I commented it out, the problem went away.  SO, I'm suspicious of
} problems in exception handling (disconnect) with history files turned on.

(I'm going to assume that by "exceptions" you mean "signals".)

The relevant bits of code would be:

	signals.c: 464: handler()
	builtin.c: 4761: zexit()
	hist.c: 1502-1584: savehistfile()
and maybe
	signals.c: 543: killrunjobs()

The only thing I could guess that might be happening is:

handler(), invoked on SIGHUP, calls zexit(), which calls killrunjobs();
killrunjobs() finds a job with group leader the current shell, and sends
it a SIGHUP; this invokes handler() again, and we loop.

Now, it *should* be the case that during the handling of a SIGHUP, any
additional SIGHUP is blocked.  The only possible connection I can come
up with between this and savehistfile() is if the stdio operations that
savehistfile() is using are somehow unblocking the signal, which seems
*very* unlikely.

You could attach dbx or gdb to one of the runaway processes (the smallest
one) and get a look at the stack.  Or (less helpful) you could try trapping
the HUP signal by adding this to /etc/zshenv as well:

	TRAPHUP() { exit 1 }

This will invoke zexit() in a slightly different way ("from_signal" will
be false) and should avoid the SIGHUP loop I described, if in fact that
is the problem.

Or you could assume that's the problem and try this patch:

Index: Src/signals.c
===================================================================
@@ -540,7 +540,8 @@
         if ((from_signal || i != thisjob) && (jobtab[i].stat & STAT_LOCKED) &&
             !(jobtab[i].stat & STAT_NOPRINT) &&
             !(jobtab[i].stat & STAT_STOPPED)) {
-            if (killpg(jobtab[i].gleader, SIGHUP) != -1)
+            if (jobtab[i].gleader != getpid() &&
+		killpg(jobtab[i].gleader, SIGHUP) != -1)
                 killed++;
         }
     if (killed)

I'll be a bit concerned about other signal-handling issues if that really
does fix it, though.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com



Messages sorted by: Reverse Date, Date, Thread, Author