<div dir="ltr">Thanks Bill, that seems to be all working so far. Thanks for the explanation. I am having a weird occasional issue though, which has me worried that I could have a nasty bug in how I&#39;ve set things up. In max, I&#39;ve got it so that multiple s7 interpreters can be running, one in each s4m.scm object. So far no issues on this approach. I&#39;ve pasted my eval helper below, adapted from the grepl.c example.<div><br></div><div>So yesterday, I had this weird thing happen where one instance of the interpreter started logging a bizarre error message from this function, that didn&#39;t seem to have any relevance to what it was doing, and it was also still managing to execute code at the same time. It looked from the outside like s7_eval_string was getting called twice, once with something totally unexpected, and once with what I expect. I just wondered if there are ever cases you&#39;ve seen where s7_get_output_string  and s7_current_error_port could be returning the wrong errors, or stale data of some kind. I know this is all rather vague, but the behaviour has me completely flumoxed. No worries if it&#39;s too vague to even comment on.</div><div><br></div><div>thanks</div><div>iain<br><div><br></div><div>// eval string  with error logging<br>void scm4max_s7_eval_string(t_scm4max *x, char *string_to_eval){<br>    //post(&quot;scm4max_s7_eval_string() %s&quot;, string_to_eval);<br>    int gc_loc;<br>    s7_pointer old_port, result;<br>    const char *errmsg = NULL;<br>    char *msg = NULL;<br>    old_port = s7_set_current_error_port(x-&gt;s7, s7_open_output_string(x-&gt;s7));<br>    gc_loc = s7_gc_protect(x-&gt;s7, old_port);<br>    s7_pointer res = s7_eval_c_string(x-&gt;s7, string_to_eval);<br>    errmsg = s7_get_output_string(x-&gt;s7, s7_current_error_port(x-&gt;s7));<br>    if ((errmsg) &amp;&amp; (*errmsg)){<br>        msg = (char *)calloc(strlen(errmsg) + 1, sizeof(char));<br>        strcpy(msg, errmsg);<br>    }<br>    s7_close_output_port(x-&gt;s7, s7_current_error_port(x-&gt;s7));<br>    s7_set_current_error_port(x-&gt;s7, old_port);<br>    s7_gc_unprotect_at(x-&gt;s7, gc_loc);<br>    if (msg){<br>        object_error(x, &quot;s4m Error: %s&quot;, msg);<br>        free(msg);<br>    }else{<br>        scm4max_post_s7_res(x, res);<br>    }<br>}<br><br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Apr 11, 2020 at 5:35 AM &lt;<a href="mailto:bil@ccrma.stanford.edu">bil@ccrma.stanford.edu</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">&gt; What is the reason we need to do the gc_protect and later unprotect of <br>
&gt; the old port?<br>
<br>
It looks like I never addressed that in s7.html.  There is a short<br>
explanation in s7.h under s7_gc_protect.  In s7, the GC can run<br>
at any time.  If you have stored a reference to an s7 object,<br>
and the GC might run during its lifetime, and its lifetime<br>
is not really short (there&#39;s a lag between the making of an object<br>
and its first possible GC), you need to protect it.  It will remain<br>
protected until you unprotect it, so to avoid an ever-growing heap,<br>
you need to unprotect it.<br>
<br>
<br>
</blockquote></div>