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.)
p is #<point* #2 0x28979a0>
q is #<point* #2 0x28979a0>found in object table as: #<void* #3 0x28981b0>
release-point called on serial 3found in object table as: #<void* #4 0x28979a0>
release-point called on serial 4
*** after GC:
foreign serial is *** after GC:, corresponding to not-there, a mem-allocated something else object with reference count == 10008704
Bye.(define ptr-serials '())
;----
(c-declare "struct { int x; int y; } point;")
(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))(let ((ptr-serial (object->serial-number ptr)))
(c-define (release-point ptr)
((pointer void)) scheme-object "scm_release_point" ""
(set! ptr-serials (cons ptr-serial ptr-serials))(table-ref ##serial-number-to-object-table ptr-serial 'not-there)))
(println "release-point called on serial " ptr-serial)
(println "found in object table as: "
(for-each
((c-lambda ((pointer void)) void "___release_rc") ptr)
no-err)
(c-define-type point (type "point" (point*) "scm_release_point"))
(define p ((c-lambda () point
"___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))
(define q ((c-lambda () point
"___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))
(println "p is " p)
(println "q is " p)
(set! p #f)
(set! q #f)
(##gc)
(newline)
(println "*** after GC:")
(lambda (ptr-serial)(newline))
(print "foreign serial is " ptr-serial)
(print ", corresponding to "
(table-ref ##serial-number-to-object-table ptr-serial 'not-there))
(print ", a "
(if
((c-lambda (scheme-object) bool "___result = ___MEM_ALLOCATED(___arg1);")
(table-ref ##serial-number-to-object-table ptr-serial 'not-there)) "" "not")
" mem-allocated")
(print " "
((c-lambda (scheme-object) char-string "___result = ___HD_TYP(___BODY(___arg1)[-1]) == ___STILL ? \"still\" : \"something else\";")
(table-ref ##serial-number-to-object-table ptr-serial 'not-there)))
(println " object with reference count == "
((c-lambda (scheme-object) int "___result = ___UNTAG(___arg1)[___BODY_OFS - 6 + 1];")
(table-ref ##serial-number-to-object-table ptr-serial 'not-there)))
ptr-serials)
(println "Bye.")On Mon, Dec 30, 2013 at 6:56 PM, Mikael <mikael.rcv@gmail.com> wrote:What's the behvior if you allocate 1 000 000 instead, is the problem amplified proportionally?2013/12/30 Estevo <euccastro@gmail.com>
It seems that's not the problem. Refcount is 0, yet the object is kept alive.
Running the modified script below, I get the following:
[BEGIN OUTPUT]
p is #<point* #2 0x12309a0>
release-point called on serial 3
found in object table as: #<void* #3 0x12309a0>
*** after GC:
foreign serial is 3, corresponding to #<void* #3 0x12309a0>, a mem-allocated still object with reference count == 0
Bye.[END OUTPUT]
;--------------------------------------------------------------------------------------(define ptr-serial #f)
(c-declare "struct { int x; int y; } point;")
(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))
(set! ptr-serial (object->serial-number ptr))
(c-define (release-point ptr)
((pointer void)) scheme-object "scm_release_point" ""
(println "release-point called on serial " ptr-serial)
(println "found in object table as: "
(table-ref ##serial-number-to-object-table ptr-serial 'not-there))(c-define-type point (type "point" (point*) "scm_release_point"))
((c-lambda ((pointer void)) void "___release_rc") ptr)
no-err)
(newline)
(define p ((c-lambda () point
"___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))
(println "p is " p)
(set! p #f)
(##gc)
(println "*** after GC:")
(print "foreign serial is " ptr-serial)
(print ", corresponding to "
(table-ref ##serial-number-to-object-table ptr-serial 'not-there))
(print ", a "
(if ((c-lambda (scheme-object) bool "___result = ___MEM_ALLOCATED(___arg1);")
(table-ref ##serial-number-to-object-table ptr-serial 'not-there))
""
"not")
" mem-allocated")
(print " "
((c-lambda (scheme-object) char-string "___result = ___HD_TYP(___BODY(___arg1)[-1]) == ___STILL ? \"still\" : \"something else\";")
(table-ref ##serial-number-to-object-table ptr-serial 'not-there)))
(println " object with reference count == "
((c-lambda (scheme-object) int "___result = ___UNTAG(___arg1)[___BODY_OFS - 6 + 1];")
(table-ref ##serial-number-to-object-table ptr-serial 'not-there)))
(println "Bye.")On Mon, Dec 30, 2013 at 10:09 AM, Mikael <mikael.rcv@gmail.com> wrote:
Refcount is 1 by default so you need to decrease it for it to GFC?Allocate a zillion points and check the two respective ways.2013/12/29 Estevo <euccastro@gmail.com>_______________________________________________Here's a more realistic version of what I was trying to do: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`:
(c-declare "struct { int x; int y; } point;")
(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))
(c-define (release-point ptr)
((pointer void)) scheme-object "scm_release_point" ""
(println "release-point called")
((c-lambda ((pointer void)) void "___release_rc") ptr)
no-err)
(c-define-type point (pointer "point" (point*) "scm_release_point"))(println "Bye.")
(define p ((c-lambda () point
"___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))
(println "p is " p)
(set! p #f)
(##gc)
==9631== Memcheck, a memory error detector
==9631== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==9631== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==9631== Command: ./test-c-define
==9631==
p is #<point* #2 0x5c04620>
release-point called
Bye.
==9631==
==9631== HEAP SUMMARY:
==9631== in use at exit: 158 bytes in 2 blocks
==9631== total heap usage: 154 allocs, 152 frees, 4,247,245 bytes allocated
==9631==
==9631== 158 (87 direct, 71 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==9631== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9631== by 0x4C7DC6: ___alloc_mem (os_base.c:185)
==9631== by 0x4B6905: alloc_mem_aligned (mem.c:452)
==9631== by 0x4B77A7: alloc_scmobj_still (mem.c:1245)
==9631== by 0x4B78B1: ___alloc_scmobj (mem.c:1285)
==9631== by 0x4C3DEE: ___POINTER_to_SCMOBJ (c_intf.c:5154)
==9631== by 0x4B1C88: scm_release_point (test-c-define.c:665)
==9631== by 0x4C1027: ___release_foreign (c_intf.c:1713)
==9631== by 0x4BAEA4: free_unmarked_still_objs (mem.c:3271)
==9631== by 0x4BD472: ___garbage_collect (mem.c:4698)
==9631== by 0x4E4357: ___H__20___kernel (_kernel.c:9170)
==9631== by 0x4B49B2: trampoline (setup.c:1618)
==9631==
==9631== LEAK SUMMARY:
==9631== definitely lost: 87 bytes in 1 blocks
==9631== indirectly lost: 71 bytes in 1 blocks
==9631== possibly lost: 0 bytes in 0 blocks
==9631== still reachable: 0 bytes in 0 blocks
==9631== suppressed: 0 bytes in 0 blocks
==9631==
==9631== For counts of detected and suppressed errors, rerun with: -v
==9631== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)On Thu, Dec 26, 2013 at 11:23 PM, Estevo <euccastro@gmail.com> wrote:
(##gc)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.
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.)
; ~/gambit-dbg/bin/gsc -exe -cc-options -g test-c-define.scm && valgrind --leak-check=full ./test-c-define
(c-declare #<<c-declare-end
typedef struct { int x; int y; } point;
void scm_release_point(unsigned long);
___SCMOBJ c_release_point(void *ptr) {
scm_release_point((unsigned long)ptr);
___EXT(___release_rc)(ptr);
return ___FIX(___NO_ERR);
}
c-declare-end
)
(c-define (release-point ptr) (unsigned-long) void "scm_release_point" ""
(println "release-point called"))
(c-define-type point (pointer "point" (point*) "c_release_point"))
(define p ((c-lambda () point
"___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))
(println "p is " p)
(set! p #f)
(##gc); for good measure...(##gc)
(println "Bye.")
valgrind --leak-check=full ./test-c-define
==16301== Memcheck, a memory error detector
==16301== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==16301== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==16301== Command: ./test-c-define
==16301==
p is #<point* #2 0x5c04640>
release-point called
Bye.
==16301==
==16301== HEAP SUMMARY:
==16301== in use at exit: 71 bytes in 1 blocks
==16301== total heap usage: 153 allocs, 152 frees, 4,247,198 bytes allocated
==16301==
==16301== 71 bytes in 1 blocks are definitely lost in loss record 1 of 1
==16301== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16301== by 0x4C922E: ___alloc_mem (os_base.c:185)
==16301== by 0x4B7DB5: alloc_mem_aligned (mem.c:452)
==16301== by 0x4B8C57: alloc_scmobj_still (mem.c:1245)
==16301== by 0x4B8D61: ___alloc_scmobj (mem.c:1285)
==16301== by 0x4B8E44: ___make_vector (mem.c:1362)
==16301== by 0x4C677B: ___make_sfun_stack_marker (c_intf.c:6452)
==16301== by 0x4B359E: scm_release_point (test-c-define.c:139)
==16301== by 0x4B354B: c_release_point (test-c-define.c:130)
==16301== by 0x4C24D7: ___release_foreign (c_intf.c:1713)
==16301== by 0x4BC354: free_unmarked_still_objs (mem.c:3271)
==16301== by 0x4BE922: ___garbage_collect (mem.c:4698)
==16301==
==16301== LEAK SUMMARY:
==16301== definitely lost: 71 bytes in 1 blocks
==16301== indirectly lost: 0 bytes in 0 blocks
==16301== possibly lost: 0 bytes in 0 blocks
==16301== still reachable: 0 bytes in 0 blocks
==16301== suppressed: 0 bytes in 0 blocks
==16301==
==16301== For counts of detected and suppressed errors, rerun with: -v
==16301== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Gambit-list mailing list
Gambit-list@iro.umontreal.ca
https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list