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) (##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)
Afficher les réponses par date
Here's a more realistic version of what I was trying to do:
(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"))
(define p ((c-lambda () point "___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))
(println "p is " p) (set! p #f)
(##gc)
(println "Bye.")
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`:
==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:
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) (##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)
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:
(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"))
(define p ((c-lambda () point "___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))
(println "p is " p) (set! p #f)
(##gc)
(println "Bye.")
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`:
==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:
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) (##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
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]
;--------------------------------------------------------------------------------------
(c-declare "struct { int x; int y; } point;")
(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))
(define ptr-serial #f)
(c-define (release-point ptr) ((pointer void)) scheme-object "scm_release_point" "" (set! ptr-serial (object->serial-number ptr)) (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-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));")))
(println "p is " p)
(set! p #f)
(##gc)
(newline) (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:
(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"))
(define p ((c-lambda () point "___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))
(println "p is " p) (set! p #f)
(##gc)
(println "Bye.")
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`:
==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:
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) (##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
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]
;--------------------------------------------------------------------------------------
(c-declare "struct { int x; int y; } point;")
(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))
(define ptr-serial #f)
(c-define (release-point ptr) ((pointer void)) scheme-object "scm_release_point" "" (set! ptr-serial (object->serial-number ptr)) (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-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));")))
(println "p is " p)
(set! p #f)
(##gc)
(newline) (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:
(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"))
(define p ((c-lambda () point "___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))
(println "p is " p) (set! p #f)
(##gc)
(println "Bye.")
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`:
==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:
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) (##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
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> release-point called on serial 3 found in object table as: #<void* #3 0x28981b0> release-point called on serial 4 found in object table as: #<void* #4 0x28979a0>
*** after GC: foreign serial is *** after GC:, corresponding to not-there, a mem-allocated something else object with reference count == 10008704
Bye.
;----
(c-declare "struct { int x; int y; } point;")
(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))
(define ptr-serials '())
(c-define (release-point ptr) ((pointer void)) scheme-object "scm_release_point" "" (let ((ptr-serial (object->serial-number ptr))) (set! ptr-serials (cons ptr-serial ptr-serials)) (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-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:") (for-each (lambda (ptr-serial) (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))) (newline)) 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]
;--------------------------------------------------------------------------------------
(c-declare "struct { int x; int y; } point;")
(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))
(define ptr-serial #f)
(c-define (release-point ptr) ((pointer void)) scheme-object "scm_release_point" "" (set! ptr-serial (object->serial-number ptr)) (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-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));")))
(println "p is " p)
(set! p #f)
(##gc)
(newline) (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:
(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"))
(define p ((c-lambda () point "___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))
(println "p is " p) (set! p #f)
(##gc)
(println "Bye.")
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`:
==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:
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) (##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
(Ignore the "q is ..." printout. As you see in the script, I just printed p again there instead, by mistake.)
On Mon, Dec 30, 2013 at 7:51 PM, Estevo euccastro@gmail.com wrote:
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>
release-point called on serial 3 found in object table as: #<void* #3 0x28981b0>
release-point called on serial 4 found in object table as: #<void* #4 0x28979a0>
*** after GC: foreign serial is *** after GC:, corresponding to not-there, a mem-allocated something else object with reference count == 10008704
Bye.
;----
(c-declare "struct { int x; int y; } point;")
(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))
(define ptr-serials '())
(c-define (release-point ptr) ((pointer void)) scheme-object "scm_release_point" "" (let ((ptr-serial (object->serial-number ptr))) (set! ptr-serials (cons ptr-serial ptr-serials))
(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-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:") (for-each (lambda (ptr-serial)
(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))) (newline)) 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]
;--------------------------------------------------------------------------------------
(c-declare "struct { int x; int y; } point;")
(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))
(define ptr-serial #f)
(c-define (release-point ptr) ((pointer void)) scheme-object "scm_release_point" "" (set! ptr-serial (object->serial-number ptr)) (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-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));")))
(println "p is " p)
(set! p #f)
(##gc)
(newline) (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:
(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"))
(define p ((c-lambda () point "___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))
(println "p is " p) (set! p #f)
(##gc)
(println "Bye.")
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`:
==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:
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) (##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
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!
*slaps forehead*
On Mon, Dec 30, 2013 at 7:54 PM, Estevo euccastro@gmail.com wrote:
(Ignore the "q is ..." printout. As you see in the script, I just printed p again there instead, by mistake.)
On Mon, Dec 30, 2013 at 7:51 PM, Estevo euccastro@gmail.com wrote:
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>
release-point called on serial 3 found in object table as: #<void* #3 0x28981b0>
release-point called on serial 4 found in object table as: #<void* #4 0x28979a0>
*** after GC: foreign serial is *** after GC:, corresponding to not-there, a mem-allocated something else object with reference count == 10008704
Bye.
;----
(c-declare "struct { int x; int y; } point;")
(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))
(define ptr-serials '())
(c-define (release-point ptr) ((pointer void)) scheme-object "scm_release_point" "" (let ((ptr-serial (object->serial-number ptr))) (set! ptr-serials (cons ptr-serial ptr-serials))
(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-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:") (for-each (lambda (ptr-serial)
(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))) (newline)) 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]
;--------------------------------------------------------------------------------------
(c-declare "struct { int x; int y; } point;")
(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))
(define ptr-serial #f)
(c-define (release-point ptr) ((pointer void)) scheme-object "scm_release_point" "" (set! ptr-serial (object->serial-number ptr)) (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-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));")))
(println "p is " p)
(set! p #f)
(##gc)
(newline) (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:
(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"))
(define p ((c-lambda () point "___result_voidstar = ___EXT(___alloc_rc)(sizeof(point));")))
(println "p is " p) (set! p #f)
(##gc)
(println "Bye.")
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`:
==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:
> 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) > (##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
Ah no, not all still objects have a data field; only ___alloc_rc'ed ones.
On Wed, Jan 1, 2014 at 10:51 AM, Estevo euccastro@gmail.com wrote:
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!
*slaps forehead*
On Mon, Dec 30, 2013 at 7:54 PM, Estevo euccastro@gmail.com wrote:
(Ignore the "q is ..." printout. As you see in the script, I just printed p again there instead, by mistake.)
On Mon, Dec 30, 2013 at 7:51 PM, Estevo euccastro@gmail.com wrote:
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>
release-point called on serial 3 found in object table as: #<void* #3 0x28981b0>
release-point called on serial 4 found in object table as: #<void* #4 0x28979a0>
*** after GC: foreign serial is *** after GC:, corresponding to not-there, a mem-allocated something else object with reference count == 10008704
Bye.
;----
(c-declare "struct { int x; int y; } point;")
(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))
(define ptr-serials '())
(c-define (release-point ptr) ((pointer void)) scheme-object "scm_release_point" "" (let ((ptr-serial (object->serial-number ptr))) (set! ptr-serials (cons ptr-serial ptr-serials))
(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-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:") (for-each (lambda (ptr-serial)
(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))) (newline)) 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]
;--------------------------------------------------------------------------------------
(c-declare "struct { int x; int y; } point;")
(define no-err ((c-lambda () scheme-object "___result = ___FIX(___NO_ERR);")))
(define ptr-serial #f)
(c-define (release-point ptr) ((pointer void)) scheme-object "scm_release_point" "" (set! ptr-serial (object->serial-number ptr)) (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-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));")))
(println "p is " p)
(set! p #f)
(##gc)
(newline) (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: > > (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")) > > > (define p ((c-lambda () point > "___result_voidstar = > ___EXT(___alloc_rc)(sizeof(point));"))) > > (println "p is " p) > (set! p #f) > > (##gc) > > (println "Bye.") > > 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`: > > ==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.comwrote: > >> 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) >> (##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 > >