I have now fixed this bug locally. The leak is in jobtab array (jobs.c). I concluded that the most logical approach would be eliminating inconsistency between makejob() and dowait() functions. My fix in a forked repo: https://salsa.debian.org/psvz-guest/dash/-/commit/5e3ea90cb3355d1308c482661a471883d36af5e7 I suspect that imbalance between allocating and freeing jobtab slots was introduced at evolving SIGCHLD handling, because I can see two waitforjob() calls, wherein the first call could wait for both done jobs and gotsigchld is set. At the second call, gotsigchld is cleared and waitforjob() does nothing. So 1 of 2 jobtab slots goes astray. Simplified bug repro steps: Script ------- while true do true & sleep .1 done Execution ------------- # dash Script & You can now observe resident set size (RSS) is bumped every several seconds: # ps aux |grep 'RSS\|dash' What do I do to have it peer-reviewed and, potentially, merged into mainline? Cheers, Vitaly ----------fixDetails: Function makejob() calls freejob() when appropriate. Specifically, it detects a free slot in jobtab array by this condition: (jp->state != JOBDONE || !jp->waited) The problem is that dowait() never sets waited flag together with JOBDONE state. Consequently, jobtab may leak: repro steps are provided in a bug report #953421. One solution could be not relying on waited flag at all, i.e. converting the makejob()'s condition into (jp->state != JOBDONE). As an alternative, I am setting waited flag in dowait().