From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Mark H Weaver Newsgroups: gmane.lisp.guile.bugs Subject: bug#19235: make-fresh-user-module procedure leaks memory Date: Sun, 07 Dec 2014 03:07:43 -0500 Message-ID: <87iohn51dc.fsf@yeeloong.lan> References: <20141130232834.32cbf5b2@bother.homenet> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1417939830 4938 80.91.229.3 (7 Dec 2014 08:10:30 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 7 Dec 2014 08:10:30 +0000 (UTC) Cc: 19235@debbugs.gnu.org To: Chris Vine Original-X-From: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Sun Dec 07 09:10:22 2014 Return-path: Envelope-to: guile-bugs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1XxWv6-0005pM-7s for guile-bugs@m.gmane.org; Sun, 07 Dec 2014 09:10:20 +0100 Original-Received: from localhost ([::1]:57284 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XxWv5-0006jx-Hp for guile-bugs@m.gmane.org; Sun, 07 Dec 2014 03:10:19 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:34337) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XxWuw-0006jf-Fg for bug-guile@gnu.org; Sun, 07 Dec 2014 03:10:16 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XxWuo-0007jc-UJ for bug-guile@gnu.org; Sun, 07 Dec 2014 03:10:10 -0500 Original-Received: from debbugs.gnu.org ([140.186.70.43]:58774) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XxWuo-0007jM-Qo for bug-guile@gnu.org; Sun, 07 Dec 2014 03:10:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1XxWuo-0003sY-Cb for bug-guile@gnu.org; Sun, 07 Dec 2014 03:10:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Mark H Weaver Original-Sender: "Debbugs-submit" Resent-CC: bug-guile@gnu.org Resent-Date: Sun, 07 Dec 2014 08:10:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 19235 X-GNU-PR-Package: guile X-GNU-PR-Keywords: Original-Received: via spool by 19235-submit@debbugs.gnu.org id=B19235.141793977414867 (code B ref 19235); Sun, 07 Dec 2014 08:10:02 +0000 Original-Received: (at 19235) by debbugs.gnu.org; 7 Dec 2014 08:09:34 +0000 Original-Received: from localhost ([127.0.0.1]:55987 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1XxWuM-0003ri-DI for submit@debbugs.gnu.org; Sun, 07 Dec 2014 03:09:34 -0500 Original-Received: from world.peace.net ([50.252.239.5]:59930) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1XxWuK-0003ra-K8 for 19235@debbugs.gnu.org; Sun, 07 Dec 2014 03:09:33 -0500 Original-Received: from c-24-62-95-23.hsd1.ma.comcast.net ([24.62.95.23] helo=yeeloong.lan) by world.peace.net with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.72) (envelope-from ) id 1XxWuD-00087n-CR; Sun, 07 Dec 2014 03:09:25 -0500 In-Reply-To: <20141130232834.32cbf5b2@bother.homenet> (Chris Vine's message of "Sun, 30 Nov 2014 23:28:34 +0000") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-guile@gnu.org List-Id: "Bug reports for GUILE, GNU's Ubiquitous Extension Language" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Original-Sender: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.bugs:7667 Archived-At: Chris Vine writes: > The make-fresh-user-module procedure leaks memory in guile-2.0.11 as > demonstrated by the attached test case. [...] > > The question which might be asked is "Would any sane person ever want > to invoke the make-fresh-user-module procedure more than a few times > in a practical program?". The answer to this question is "Yes", if > guile is being used as an extension framework for a C or C++ program, > and it executes guile extensions as individual tasks, and it is > necessary that top levels should not to be shared. The execution of > tasks concurrently is one such case, but there can be many cases where > isolated top levels are desirable for tasks executed serially also. Unfortunately, Guile modules cannot be garbage collected. The problem is that modules are usually referenced by name, not by direct pointers. Every module must have a name, due to the way our macro expander works. Modules created by 'make-module' or 'make-fresh-user-module' are named using gensyms. We maintain a global map from module names to module objects, and we can never safely delete from this map, because we cannot prove that the module name won't be looked up in the future. I agree that your use case is reasonable. I'll think about how we might allow unnamed modules to be collected, but I'm afraid it might be quite difficult. In the meantime, I wrote a procedure that uses undocumented interfaces to forcefully delete a module from the name->module map. However, I must emphasize that this procedure is likely to break in a future version of Guile. However, it should work in the 2.0.x series. --8<---------------cut here---------------start------------->8--- ;; WARNING: Uses undocumented interfaces; NOT FUTURE PROOF!! ;; This needs (srfi srfi-1) (define (delete-module! module) (let* ((name (module-name module)) (last-name (last name)) (parent-name (drop-right name 1)) (parent (resolve-module parent-name #f)) (var (module-variable parent last-name))) (when (and var (variable-bound? var) (eqv? (variable-ref var) module)) (hashq-remove! (module-obarray parent) last-name)) (hashq-remove! (module-submodules parent) last-name) #f)) --8<---------------cut here---------------end--------------->8--- I should mention that creating new modules with 'make-fresh-user-module' is not thread safe, nor is the procedure above. Both of them mutate the same name->module map. For now, I recommend protecting calls to both of them with a mutex. Mark