<div dir="ltr"><div>But wait a minute... I had missed the point that foreigns themselves (that is, not only the data they point to) have a reference count. Sure enough, foreigns that are returned by POINTER_to_SCMOBJ *are ___STILL allocated*! That means they already have the `data` field I wanted to add to Gambit!<br>
<br></div>*slaps forehead*<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Dec 30, 2013 at 7:54 PM, Estevo <span dir="ltr"><<a href="mailto:euccastro@gmail.com" target="_blank">euccastro@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">(Ignore the "q is ..." printout. As you see in the script, I just printed p again there instead, by mistake.)<br>
</div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Dec 30, 2013 at 7:51 PM, Estevo <span dir="ltr"><<a href="mailto:euccastro@gmail.com" target="_blank">euccastro@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Well, just with 2 (modified script follows below, again) I get memory corruption (note that it seems like the value of the car of `ptr-serials` has become the string "*** after GC", which is only ever passed to println.)<br>
</div><div><br>p is #<point* #2 0x28979a0><br>q is #<point* #2 0x28979a0><div><br>release-point called on serial 3<br></div>found in object table as: #<void* #3 0x28981b0><div><br>
release-point called on serial 4<br></div>found in object table as: #<void* #4 0x28979a0><br>
<br>*** after GC:<br>foreign serial is *** after GC:, corresponding to not-there, a mem-allocated something else object with reference count == 10008704<br><br>Bye.<div><br><br>;----<br><br>(c-declare "struct { int x; int y; } point;")<br>
<br>(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))<br><br></div>(define ptr-serials '())<div><br><br>(c-define (release-point ptr)<br> ((pointer void)) scheme-object "scm_release_point" ""<br>
</div>
(let ((ptr-serial (object->serial-number ptr)))<br> (set! ptr-serials (cons ptr-serial ptr-serials))<div><br> (println "release-point called on serial " ptr-serial)<br> (println "found in object table as: "<br>
</div>
(table-ref ##serial-number-to-object-table ptr-serial 'not-there)))<div><br> ((c-lambda ((pointer void)) void "___release_rc") ptr)<br> no-err)<br><br>(c-define-type point (type "point" (point*) "scm_release_point"))<br>
<br>(define p ((c-lambda () point<br> "___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))<br><br>(define q ((c-lambda () point<br> "___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))<br>
<br>(println "p is " p)<br>(println "q is " p)<br><br>(set! p #f)<br>(set! q #f)<br><br>(##gc)<br><br>(newline)<br>(println "*** after GC:")<br></div>(for-each<br> (lambda (ptr-serial)<div>
<br> (print "foreign serial is " ptr-serial)<br>
(print ", corresponding to "<br> (table-ref ##serial-number-to-object-table ptr-serial 'not-there))<br><br> (print ", a "<br> (if<br> ((c-lambda (scheme-object) bool "___result = ___MEM_ALLOCATED(___arg1);")<br>
(table-ref ##serial-number-to-object-table ptr-serial 'not-there)) "" "not")<br> " mem-allocated")<br><br> (print " "<br> ((c-lambda (scheme-object) char-string "___result = ___HD_TYP(___BODY(___arg1)[-1]) == ___STILL ? \"still\" : \"something else\";")<br>
(table-ref ##serial-number-to-object-table ptr-serial 'not-there)))<br><br> (println " object with reference count == "<br> ((c-lambda (scheme-object) int "___result = ___UNTAG(___arg1)[___BODY_OFS - 6 + 1];")<br>
(table-ref ##serial-number-to-object-table ptr-serial 'not-there)))<br></div> (newline))<br> ptr-serials)<br><br>(println "Bye.")<br><br><br></div></div><div><div>
<div class="gmail_extra"><br><br><div class="gmail_quote">
On Mon, Dec 30, 2013 at 6:56 PM, Mikael <span dir="ltr"><<a href="mailto:mikael.rcv@gmail.com" target="_blank">mikael.rcv@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">What's the behvior if you allocate 1 000 000 instead, is the problem amplified proportionally?</div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/12/30 Estevo <span dir="ltr"><<a href="mailto:euccastro@gmail.com" target="_blank">euccastro@gmail.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">It seems that's not the problem. Refcount is 0, yet the object is kept alive. <br><br>Running the modified script below, I get the following:<br>
<div><br>[BEGIN OUTPUT]<br><br>p is #<point* #2 0x12309a0><br>
release-point called on serial 3<br>found in object table as: #<void* #3 0x12309a0><br><br>*** after GC:<br>foreign serial is 3, corresponding to #<void* #3 0x12309a0>, a mem-allocated still object with reference count == 0<br>
Bye.<br><br></div><div>[END OUTPUT]<br></div><div><br>;--------------------------------------------------------------------------------------<div><br><br>(c-declare "struct { int x; int y; } point;")<br>
<br>(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))<br>
<br></div>(define ptr-serial #f)<div><br><br>(c-define (release-point ptr)<br> ((pointer void)) scheme-object "scm_release_point" ""<br></div> (set! ptr-serial (object->serial-number ptr))<br>
(println "release-point called on serial " ptr-serial)<br>
(println "found in object table as: "<br> (table-ref ##serial-number-to-object-table ptr-serial 'not-there))<div><br> ((c-lambda ((pointer void)) void "___release_rc") ptr)<br> no-err)<br>
<br></div>(c-define-type point (type "point" (point*) "scm_release_point"))<div><br>
<br>(define p ((c-lambda () point<br> "___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))<br><br>(println "p is " p)<br><br>(set! p #f)<br><br>(##gc)<br><br></div>(newline)<br>(println "*** after GC:")<br>
(print "foreign serial is " ptr-serial)<br>(print ", corresponding to "<br> (table-ref ##serial-number-to-object-table ptr-serial 'not-there))<br><br>(print ", a "<br> (if ((c-lambda (scheme-object) bool "___result = ___MEM_ALLOCATED(___arg1);")<br>
(table-ref ##serial-number-to-object-table ptr-serial 'not-there)) <br> "" <br> "not")<br> " mem-allocated")<br><br>(print " "<br> ((c-lambda (scheme-object) char-string "___result = ___HD_TYP(___BODY(___arg1)[-1]) == ___STILL ? \"still\" : \"something else\";")<br>
(table-ref ##serial-number-to-object-table ptr-serial 'not-there)))<br><br>(println " object with reference count == "<br> ((c-lambda (scheme-object) int "___result = ___UNTAG(___arg1)[___BODY_OFS - 6 + 1];")<br>
(table-ref ##serial-number-to-object-table ptr-serial 'not-there)))<br><br>(println "Bye.")<br><br><br></div></div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Mon, Dec 30, 2013 at 10:09 AM, Mikael <span dir="ltr"><<a href="mailto:mikael.rcv@gmail.com" target="_blank">mikael.rcv@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Refcount is 1 by default so you need to decrease it for it to GFC?<div><br></div><div>Allocate a zillion points and check the two respective ways.</div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">
2013/12/29 Estevo <span dir="ltr"><<a href="mailto:euccastro@gmail.com" target="_blank">euccastro@gmail.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div>
<div dir="ltr"><div>Here's a more realistic version of what I was trying to do:<br><br>(c-declare "struct { int x; int y; } point;")<br><br>(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))<br>
<br>(c-define (release-point ptr)<br> ((pointer void)) scheme-object "scm_release_point" ""<br> (println "release-point called")<br> ((c-lambda ((pointer void)) void "___release_rc") ptr)<br>
no-err)<br><br>(c-define-type point (pointer "point" (point*) "scm_release_point"))<div><br><br>(define p ((c-lambda () point<br> "___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))<br>
<br>(println "p is " p)<br>(set! p #f)<br><br>(##gc)<br><br></div>(println "Bye.")<br><br></div>valgrind's complaint is different in this one. What is leaked here (again, unless valgrind is giving me a false positive) seems to be the Scheme representation of `ptr`:<br>
<br>==9631== Memcheck, a memory error detector<br>==9631== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.<br>==9631== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info<br>==9631== Command: ./test-c-define<br>
==9631== <br>p is #<point* #2 0x5c04620><br>release-point called<br>Bye.<br>==9631== <br>==9631== HEAP SUMMARY:<br>==9631== in use at exit: 158 bytes in 2 blocks<br>==9631== total heap usage: 154 allocs, 152 frees, 4,247,245 bytes allocated<br>
==9631== <br>==9631== 158 (87 direct, 71 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2<br>==9631== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)<br>==9631== by 0x4C7DC6: ___alloc_mem (os_base.c:185)<br>
==9631== by 0x4B6905: alloc_mem_aligned (mem.c:452)<br>==9631== by 0x4B77A7: alloc_scmobj_still (mem.c:1245)<br>==9631== by 0x4B78B1: ___alloc_scmobj (mem.c:1285)<br>==9631== by 0x4C3DEE: ___POINTER_to_SCMOBJ (c_intf.c:5154)<br>
==9631== by 0x4B1C88: scm_release_point (test-c-define.c:665)<br>==9631== by 0x4C1027: ___release_foreign (c_intf.c:1713)<br>==9631== by 0x4BAEA4: free_unmarked_still_objs (mem.c:3271)<br>==9631== by 0x4BD472: ___garbage_collect (mem.c:4698)<br>
==9631== by 0x4E4357: ___H__20___kernel (_kernel.c:9170)<br>==9631== by 0x4B49B2: trampoline (setup.c:1618)<br>==9631== <br>==9631== LEAK SUMMARY:<br>==9631== definitely lost: 87 bytes in 1 blocks<br>==9631== indirectly lost: 71 bytes in 1 blocks<br>
==9631== possibly lost: 0 bytes in 0 blocks<br>==9631== still reachable: 0 bytes in 0 blocks<br>==9631== suppressed: 0 bytes in 0 blocks<br>==9631== <br>==9631== For counts of detected and suppressed errors, rerun with: -v<br>
==9631== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)<br><br></div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Dec 26, 2013 at 11:23 PM, Estevo <span dir="ltr"><<a href="mailto:euccastro@gmail.com" target="_blank">euccastro@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div>Valgrind reports Gambit is leaking a "sfun stack marker" if I call, from a foreign release function, another function defined with `c-define`. The code below is
about the most innocent looking thing I could come up with.<br><br>Doesn't Gambit like c-define functions called within release
functions, or is Valgrind giving me a false positive here (as it is wont to do quite often.)<br>
<br>; ~/gambit-dbg/bin/gsc -exe -cc-options -g test-c-define.scm && valgrind --leak-check=full ./test-c-define<br><br>(c-declare #<<c-declare-end<br><br>typedef struct { int x; int y; } point;<br><br>void scm_release_point(unsigned long);<br>
<br>___SCMOBJ c_release_point(void *ptr) {<br> scm_release_point((unsigned long)ptr);<br> ___EXT(___release_rc)(ptr);<br> return ___FIX(___NO_ERR);<br>}<br><br>c-declare-end<br>)<br><br>(c-define (release-point ptr) (unsigned-long) void "scm_release_point" ""<br>
(println "release-point called"))<br><br>(c-define-type point (pointer "point" (point*) "c_release_point"))<br><br>(define p ((c-lambda () point<br> "___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))<br>
<br>(println "p is " p)<br>(set! p #f)<br><br>(##gc)<br></div><div>; for good measure...<br></div>(##gc)<br></div>(##gc)<br><div><div><br>(println "Bye.")<br><br><br>valgrind --leak-check=full ./test-c-define<br>
==16301== Memcheck, a memory error detector<br>==16301== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.<br>==16301== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info<br>==16301== Command: ./test-c-define<br>
==16301== <br>p is #<point* #2 0x5c04640><br>release-point called<br>Bye.<br>==16301== <br>==16301== HEAP SUMMARY:<br>==16301== in use at exit: 71 bytes in 1 blocks<br>==16301== total heap usage: 153 allocs, 152 frees, 4,247,198 bytes allocated<br>
==16301== <br>==16301== 71 bytes in 1 blocks are definitely lost in loss record 1 of 1<br>==16301== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)<br>==16301== by 0x4C922E: ___alloc_mem (os_base.c:185)<br>
==16301== by 0x4B7DB5: alloc_mem_aligned (mem.c:452)<br>==16301== by 0x4B8C57: alloc_scmobj_still (mem.c:1245)<br>==16301== by 0x4B8D61: ___alloc_scmobj (mem.c:1285)<br>==16301== by 0x4B8E44: ___make_vector (mem.c:1362)<br>
==16301== by 0x4C677B: ___make_sfun_stack_marker (c_intf.c:6452)<br>==16301== by 0x4B359E: scm_release_point (test-c-define.c:139)<br>==16301== by 0x4B354B: c_release_point (test-c-define.c:130)<br>==16301== by 0x4C24D7: ___release_foreign (c_intf.c:1713)<br>
==16301== by 0x4BC354: free_unmarked_still_objs (mem.c:3271)<br>==16301== by 0x4BE922: ___garbage_collect (mem.c:4698)<br>==16301== <br>==16301== LEAK SUMMARY:<br>==16301== definitely lost: 71 bytes in 1 blocks<br>
==16301== indirectly lost: 0 bytes in 0 blocks<br>==16301== possibly lost: 0 bytes in 0 blocks<br>==16301== still reachable: 0 bytes in 0 blocks<br>==16301== suppressed: 0 bytes in 0 blocks<br>==16301== <br>
==16301== For counts of detected and suppressed errors, rerun with: -v<br>==16301== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)<br></div></div></div>
</blockquote></div><br></div>
</div></div><br></div></div>_______________________________________________<br>
Gambit-list mailing list<br>
<a href="mailto:Gambit-list@iro.umontreal.ca" target="_blank">Gambit-list@iro.umontreal.ca</a><br>
<a href="https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list" target="_blank">https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list</a><br>
<br></blockquote></div><br></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>