<div><br></div><div>That was the first time in many years I was aware of a memory leak scenario in a Gambit env.</div><div><br></div><div>The leak consisted of 1) <a href="https://github.com/feeley/gambit/issues/33">https://github.com/feeley/gambit/issues/33</a> that regards wills not GC:ing if you ran will-execute! on it, for a programmer that one is easily worked around, and then 2) the following problem.</div>

<div><br></div><div>Apart from these two, Gambit works perfectly to my knowing.</div><div><br></div><div><br></div><div>Find dump_threads.scm and dump_threads_bug_demo.scm attached. Just launch them like this:</div><div>
<br>
</div><div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><font face="courier new, monospace">$ gsc</font></div><div><font face="courier new, monospace">Gambit v4.6.9</font></div><div><font face="courier new, monospace"><br>

</font></div><div><font face="courier new, monospace">> <b>(load "dump_threads.scm") (load "dump_threads_bug_demo.scm") (demo)</b></font></div><div><font face="courier new, monospace">"/home/user/dump_threads.scm"</font></div>

<div><font face="courier new, monospace">> "/home/user/dump_threads_bug_demo.scm"</font></div><div><font face="courier new, monospace">> Creating 10000 threads</font></div><div><font face="courier new, monospace">Waiting for threads to finish</font></div>

<div><font face="courier new, monospace">Numbered objects on the heap prior to GC: 10001 <span style="background-color:rgb(255,255,204)">- A (##gc) is made here.</span></font></div><div><font face="courier new, monospace">Numbered objects on the heap after GC: 1        <span style="background-color:rgb(255,255,204)">- All the 10000 threads GC:ed, this is what should happen.</span></font></div>

<div><font face="courier new, monospace">Creating 10000 threads, while doing a bunch of dump-threads calls too</font></div><div><font face="courier new, monospace">Waiting for threads to finish</font></div><div><font face="courier new, monospace">Numbered objects on the heap prior to GC: 10003 <span style="background-color:rgb(255,255,204)">- Now we do the same test again but while doing a bunch of dump-threads calls</span></font></div>

<div><font face="courier new, monospace">Numbered objects on the heap after GC: 9004     <span style="background-color:rgb(255,204,204)">- 9000 of the 1000 threads created became resistent to ##gc and never collect = Memory leak!</span></font></div>

</div><div><span style="font-family:'courier new',monospace">></span></div><div><br></div></blockquote></div><div><br></div><div>What happens here is that we see how (dump-threads) invocations *makes ~90% of threads running stuck on the heap and never GC*!</div>

<div><br></div><div><br></div><div>|dump-threads| is a really neat debug tool - so neat everybody should have a copy, that kind of level of neat - how can we make it not trash Gambit like this, but instead completely reliable?</div>

<div><br></div><div><br></div><div><br></div><div><br></div><div>Ordinary dump-threads use example, just so you know what it is about:</div><div><br></div><div><blockquote style="margin:0 0 0 40px;border:none;padding:0px">

<div><div><font face="courier new, monospace">$ gsc</font></div><div><font face="courier new, monospace">Gambit v4.6.9</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">> <b>(load "dump_threads.scm")</b></font></div>

<div><font face="courier new, monospace">"/home/user/dump_threads.scm"</font></div><div><font face="courier new, monospace">> <b>(thread-start! (make-thread (lambda () (define myvar 1234) (thread-sleep! 5) (void)) 'first-thread))</b></font></div>

<div><font face="courier new, monospace">#<thread #2 first-thread></font></div><div><font face="courier new, monospace">> <b>(thread-start! (make-thread (lambda () (define myvar 5678) (thread-sleep! 5) (void)) 'second-thread))</b></font></div>

<div><font face="courier new, monospace">#<thread #3 second-thread></font></div><div><font face="courier new, monospace">> <b>(thread-yield!)</b></font></div><div><font face="courier new, monospace">> <b>(dump-threads #t 100 100)</b></font></div>

<div><font face="courier new, monospace">#<thread #1 primordial></font></div><div><font face="courier new, monospace">0  loop                            "dump_threads.scm"@111:32       (with-exception-catcher (lambda (...</font></div>

<div><font face="courier new, monospace">        result = ##thread-void-action!</font></div><div><font face="courier new, monospace">        exception? = #f</font></div><div><font face="courier new, monospace">        end-condvar = '#<condition-variable #4 #f></font></div>

<div><font face="courier new, monospace">        quantum-pre = .02</font></div><div><font face="courier new, monospace">        loop = (lambda () (letrec ((quantum-pre (thread-quantum (current-thread)))) (thread-quantum-...</font></div>

<div><font face="courier new, monospace">        thread = '#<thread #1 primordial></font></div><div><font face="courier new, monospace">        display-environment = #t</font></div><div><font face="courier new, monospace">        max-head = 100</font></div>

<div><font face="courier new, monospace">        max-tail = 100</font></div><div><font face="courier new, monospace">1  dump-thread                     "dump_threads.scm"@124:5        (out)</font></div><div><font face="courier new, monospace">        out = (lambda () ((letrec ((loop (lambda () (letrec ((quantum-pre (thread-quantum (current-t...</font></div>

<div><font face="courier new, monospace">        thread = '#<thread #1 primordial></font></div><div><font face="courier new, monospace">        display-environment = #t</font></div><div><font face="courier new, monospace">        max-head = 100</font></div>

<div><font face="courier new, monospace">        max-tail = 100</font></div><div><font face="courier new, monospace">2  for-each</font></div><div><font face="courier new, monospace">3  (interaction)                   (console)@5:1                   (dump-threads #t 100 100)</font></div>

<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">#<thread #2 first-thread></font></div><div><font face="courier new, monospace">0  ##thread-sleep!</font></div><div>
<font face="courier new, monospace">1  #<procedure #5>                 (console)@2:60                  (thread-sleep! 5)</font></div>
<div><font face="courier new, monospace">        myvar = 1234</font></div><div><font face="courier new, monospace">2  ##thread-start-action!</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">#<thread #3 second-thread></font></div>

<div><font face="courier new, monospace">0  ##thread-sleep!</font></div><div><font face="courier new, monospace">1  #<procedure #6>                 (console)@3:60                  (thread-sleep! 5)</font></div><div>

<font face="courier new, monospace">        myvar = 5678</font></div><div><font face="courier new, monospace">2  ##thread-start-action!</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">></font></div>

</div><div><br></div></blockquote></div><div>What it does is to show all running threads including their environment.</div><div><br></div><div>So, at least in my frame of reference, a quite central debug tool.</div><div>
<br>
</div><div>Would be great if we could fix it.</div><div><br></div><div><br></div><div>Brgds,</div><div>Mikael</div><div><br></div>