unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Guile 1.8 Garbage Collection Question
@ 2011-10-25 20:34 Whitlock, Bradley D
  2011-10-26  5:15 ` Cedric Cellier
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Whitlock, Bradley D @ 2011-10-25 20:34 UTC (permalink / raw)
  To: guile-user@gnu.org

[-- Attachment #1: Type: text/plain, Size: 2080 bytes --]

I have built Guile 1.8.8.2 on MinGW.

I have wrapped some gtkwave code with Guile and have a memory issue. The following code apparently never frees 's', but I am not sure why.

SCM_DEFINE (libguile_fst_writer_emit_value, "libguile-fst-writer-emit-value",
                    3,0,0,
                    (SCM scm_ctx, SCM scm_fsthandle, SCM scm_val),
                    "Write a change on fstHandle")
{
  // Storage for temporary string
  char* s = NULL;
  scm_dynwind_begin (0);
  scm_dynwind_unwind_handler (free, s, SCM_F_WIND_EXPLICITLY);

  s = scm_to_locale_string (scm_val);

  fstWriterEmitValueChange(SCM_TO_CTX (scm_ctx),
                                                   SCM_TO_FSTHANDLE (scm_fsthandle),
                                                   s_buf);

  scm_dynwind_end();

  return SCM_UNSPECIFIED;
}

The code is called from Scheme land in the following loop:

(let loop ((n 0))
  (if (eq? n 10000000) #t
      (begin

                ;; Emit some changes on the signal
                (fst-emit-value ctx s (number->string (modulo n 2)))
                (fst-emit-value ctx s1 (number->string (modulo (1+ n) 2)))
                (fst-emit-time-change ctx n)

                (loop (1+ n))
                )))

It seems to me that the garbage collector never gets a chance to run, so how do I make sure that the gc gets a turn?

If I define my function like the following, the leak disappears, but it's a less desirable solution:

SCM_DEFINE (libguile_fst_writer_emit_value, "libguile-fst-writer-emit-value",
                    3,0,0,
                    (SCM scm_ctx, SCM scm_fsthandle, SCM scm_val),
                    "Write a change on fstHandle")
{
  // Storage for temporary string
  char s_buf [1024];
  scm_to_locale_stringbuf (scm_val, s_buf, 1024);
  s = scm_to_locale_string (scm_val);

  fstWriterEmitValueChange(SCM_TO_CTX (scm_ctx),
                                                   SCM_TO_FSTHANDLE (scm_fsthandle),
                                                   s_buf);

  return SCM_UNSPECIFIED;
}

Any suggestion?

Thanks,
Brad

[-- Attachment #2: Type: text/html, Size: 10915 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: Guile 1.8 Garbage Collection Question
@ 2011-10-25 20:36 Whitlock, Bradley D
  0 siblings, 0 replies; 7+ messages in thread
From: Whitlock, Bradley D @ 2011-10-25 20:36 UTC (permalink / raw)
  To: guile-user@gnu.org

[-- Attachment #1: Type: text/plain, Size: 2857 bytes --]

I had a copy-paste error in the second function listing, it should be this:

SCM_DEFINE (libguile_fst_writer_emit_value, "libguile-fst-writer-emit-value",
                    3,0,0,
                    (SCM scm_ctx, SCM scm_fsthandle, SCM scm_val),
                    "Write a change on fstHandle")
{
  // Storage for temporary string
  char s_buf [1024];
  scm_to_locale_stringbuf (scm_val, s_buf, 1024);

  fstWriterEmitValueChange(SCM_TO_CTX (scm_ctx),
                                                   SCM_TO_FSTHANDLE (scm_fsthandle),
                                                   s_buf);

  return SCM_UNSPECIFIED;
}

-Brad

From: Whitlock, Bradley D
Sent: Tuesday, October 25, 2011 2:34 PM
To: 'guile-user@gnu.org'
Subject: Guile 1.8 Garbage Collection Question

I have built Guile 1.8.8.2 on MinGW.

I have wrapped some gtkwave code with Guile and have a memory issue. The following code apparently never frees 's', but I am not sure why.

SCM_DEFINE (libguile_fst_writer_emit_value, "libguile-fst-writer-emit-value",
                    3,0,0,
                    (SCM scm_ctx, SCM scm_fsthandle, SCM scm_val),
                    "Write a change on fstHandle")
{
  // Storage for temporary string
  char* s = NULL;
  scm_dynwind_begin (0);
  scm_dynwind_unwind_handler (free, s, SCM_F_WIND_EXPLICITLY);

  s = scm_to_locale_string (scm_val);

  fstWriterEmitValueChange(SCM_TO_CTX (scm_ctx),
                                                   SCM_TO_FSTHANDLE (scm_fsthandle),
                                                   s_buf);

  scm_dynwind_end();

  return SCM_UNSPECIFIED;
}

The code is called from Scheme land in the following loop:

(let loop ((n 0))
  (if (eq? n 10000000) #t
      (begin

                ;; Emit some changes on the signal
                (fst-emit-value ctx s (number->string (modulo n 2)))
                (fst-emit-value ctx s1 (number->string (modulo (1+ n) 2)))
                (fst-emit-time-change ctx n)

                (loop (1+ n))
                )))

It seems to me that the garbage collector never gets a chance to run, so how do I make sure that the gc gets a turn?

If I define my function like the following, the leak disappears, but it's a less desirable solution:

SCM_DEFINE (libguile_fst_writer_emit_value, "libguile-fst-writer-emit-value",
                    3,0,0,
                    (SCM scm_ctx, SCM scm_fsthandle, SCM scm_val),
                    "Write a change on fstHandle")
{
  // Storage for temporary string
  char s_buf [1024];
  scm_to_locale_stringbuf (scm_val, s_buf, 1024);
  s = scm_to_locale_string (scm_val);

  fstWriterEmitValueChange(SCM_TO_CTX (scm_ctx),
                                                   SCM_TO_FSTHANDLE (scm_fsthandle),
                                                   s_buf);

  return SCM_UNSPECIFIED;
}

Any suggestion?

Thanks,
Brad

[-- Attachment #2: Type: text/html, Size: 14055 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Guile 1.8 Garbage Collection Question
  2011-10-25 20:34 Guile 1.8 Garbage Collection Question Whitlock, Bradley D
@ 2011-10-26  5:15 ` Cedric Cellier
  2011-10-26  8:39 ` Andy Wingo
  2011-10-26 16:30 ` rixed
  2 siblings, 0 replies; 7+ messages in thread
From: Cedric Cellier @ 2011-10-26  5:15 UTC (permalink / raw)
  To: Whitlock, Bradley D, guile-user

I cant see anything wrong with your function, so I suspect there is something wrong with the function you pass your string to. Maybe it's trying to write into s but does write out of bounds insead, damaging the heap ??

Note: it is my understanding that s is allocated on C's heap and so will not be garbage collected by guile's GC but freed immediately by your dynwind handler as soon as the function exits.



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Guile 1.8 Garbage Collection Question
  2011-10-25 20:34 Guile 1.8 Garbage Collection Question Whitlock, Bradley D
  2011-10-26  5:15 ` Cedric Cellier
@ 2011-10-26  8:39 ` Andy Wingo
  2011-10-26 16:07   ` EXTERNAL: " Whitlock, Bradley D
  2011-10-26 16:30 ` rixed
  2 siblings, 1 reply; 7+ messages in thread
From: Andy Wingo @ 2011-10-26  8:39 UTC (permalink / raw)
  To: Whitlock, Bradley D; +Cc: guile-user@gnu.org

On Tue 25 Oct 2011 22:34, "Whitlock, Bradley D" <bradley.d.whitlock@lmco.com> writes:

>   scm_dynwind_unwind_handler (free, s, SCM_F_WIND_EXPLICITLY);

You can write this as scm_dynwind_free (s), FWIW.

Otherwise I didn't see the problem.  `s' is not managed by the GC, so
the GC shouldn't have much to do with it.

Regards,

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: EXTERNAL: Re: Guile 1.8 Garbage Collection Question
  2011-10-26  8:39 ` Andy Wingo
@ 2011-10-26 16:07   ` Whitlock, Bradley D
  2011-10-26 16:28     ` rixed
  0 siblings, 1 reply; 7+ messages in thread
From: Whitlock, Bradley D @ 2011-10-26 16:07 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-user@gnu.org

Hm, thanks Andy. I settled on the following solution, no problems:

SCM_DEFINE (libguile_fst_writer_emit_value, "libguile-fst-writer-emit-value",
	    3,0,0,
	    (SCM scm_ctx, SCM scm_fsthandle, SCM scm_val), 
	    "Write a change on fstHandle")
{
  // Storage for temporary string
  char* s = NULL;

  scm_dynwind_begin (0);
  s = scm_to_locale_string (scm_val);

  fstWriterEmitValueChange(SCM_TO_CTX (scm_ctx),
			   SCM_TO_FSTHANDLE (scm_fsthandle),
			   s);
  scm_dynwind_free (s);
  scm_dynwind_end();

  return SCM_UNSPECIFIED;
}

Thanks,
Brad

-----Original Message-----
From: Andy Wingo [mailto:wingo@pobox.com] 
Sent: Wednesday, October 26, 2011 2:39 AM
To: Whitlock, Bradley D
Cc: guile-user@gnu.org
Subject: EXTERNAL: Re: Guile 1.8 Garbage Collection Question

On Tue 25 Oct 2011 22:34, "Whitlock, Bradley D" <bradley.d.whitlock@lmco.com> writes:

>   scm_dynwind_unwind_handler (free, s, SCM_F_WIND_EXPLICITLY);

You can write this as scm_dynwind_free (s), FWIW.

Otherwise I didn't see the problem.  `s' is not managed by the GC, so
the GC shouldn't have much to do with it.

Regards,

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: EXTERNAL: Re: Guile 1.8 Garbage Collection Question
  2011-10-26 16:07   ` EXTERNAL: " Whitlock, Bradley D
@ 2011-10-26 16:28     ` rixed
  0 siblings, 0 replies; 7+ messages in thread
From: rixed @ 2011-10-26 16:28 UTC (permalink / raw)
  To: guile-user@gnu.org

> {
>   // Storage for temporary string
>   char* s = NULL;
> 
>   scm_dynwind_begin (0);
>   s = scm_to_locale_string (scm_val);
> 
>   fstWriterEmitValueChange(SCM_TO_CTX (scm_ctx),
> 			   SCM_TO_FSTHANDLE (scm_fsthandle),
> 			   s);
>   scm_dynwind_free (s);
>   scm_dynwind_end();
> 
>   return SCM_UNSPECIFIED;
> }

You are supposed to call scm_dynwind_free(s) before anything that can
throw, ie right after the call to scm_to_locale_string(), IMHO.




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Guile 1.8 Garbage Collection Question
  2011-10-25 20:34 Guile 1.8 Garbage Collection Question Whitlock, Bradley D
  2011-10-26  5:15 ` Cedric Cellier
  2011-10-26  8:39 ` Andy Wingo
@ 2011-10-26 16:30 ` rixed
  2 siblings, 0 replies; 7+ messages in thread
From: rixed @ 2011-10-26 16:30 UTC (permalink / raw)
  To: guile-user@gnu.org

Now that I've replied to your last message, I think I've spotted the bug:

-[ Tue, Oct 25, 2011 at 08:34:23PM +0000, Whitlock, Bradley D ]----
> {
>   // Storage for temporary string
>   char* s = NULL;
>   scm_dynwind_begin (0);
>   scm_dynwind_unwind_handler (free, s, SCM_F_WIND_EXPLICITLY);
> 
>   s = scm_to_locale_string (scm_val);
> 
>   fstWriterEmitValueChange(SCM_TO_CTX (scm_ctx),
>                                                    SCM_TO_FSTHANDLE (scm_fsthandle),
>                                                    s_buf);
> 
>   scm_dynwind_end();
> 
>   return SCM_UNSPECIFIED;
> }

Here you are calling scm_dynwind_unwind_handler with NULL (the current
value of s), which is useless. It will call free(NULL) to free s, which
is not very usefull.
You must move this call after the initialization of s (and, as
suggested, you'd better use scm_dynwind_free, which is equivalent to
scm_dynwind_unwind_handler(free)).




^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-10-26 16:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-25 20:34 Guile 1.8 Garbage Collection Question Whitlock, Bradley D
2011-10-26  5:15 ` Cedric Cellier
2011-10-26  8:39 ` Andy Wingo
2011-10-26 16:07   ` EXTERNAL: " Whitlock, Bradley D
2011-10-26 16:28     ` rixed
2011-10-26 16:30 ` rixed
  -- strict thread matches above, loose matches on Subject: below --
2011-10-25 20:36 Whitlock, Bradley D

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).