[cffi-devel] foreign-free not freeing memory not allocated by CFFI
I received a report of an error when a function is called from lispbuilder-sdl-mixer on the Mac in both SBCL and CCL. http://pastebin.com/NmLX1Hgg I think the problem is that CFFI does not allow memory to be freed if that memory has not also been allocated using CFFI. In my code below, a new 'sdl-version' struct is returned by (sdl-mixer-cffi::linked-version). The error seems to occur when I try to free the struct at the end of the function using foreign-free. (defun linked-version () "Returns the version number of the SDL_mixer dynamic library in use as #\(`MAJOR` `MINOR` `PATCH`\)." (let ((sdl-version (sdl-mixer-cffi::linked-version)) (version nil)) (cffi:with-foreign-slots ((sdl-cffi::major sdl-cffi::minor sdl-cffi::patch) sdl-version sdl-cffi::sdl-version) (setf version (vector sdl-cffi::major sdl-cffi::minor sdl-cffi::patch))) (cffi:foreign-free sdl-version) version)) Can I get around this somehow? -Luke
On Sat, May 21, 2011 at 1:21 AM, Luke Crook <luke@balooga.com> wrote:
I think the problem is that CFFI does not allow memory to be freed if that memory has not also been allocated using CFFI.
Indeed, you shouldn't call FOREIGN-FREE on pointers to memory not allocated by FOREIGN-ALLOC. You should be able to (defcfun free ...) and use that.
In my code below, a new 'sdl-version' struct is returned by (sdl-mixer-cffi::linked-version). The error seems to occur when I try to free the struct at the end of the function using foreign-free.
However, under SBCL FOREIGN-FREE is equivalent to free() -- not sure about CCL. According to SDL_Mixer's documentation, Mix_Linked_Version() returns a const pointer, so it seems that the bug here is that you're trying to free() non-malloc()ed memory. HTH. -- Luís Oliveira http://r42.eu/~luis/
On Sun, May 22, 2011 at 2:10 PM, Luís Oliveira <luismbo@gmail.com> wrote:
I think the problem is that CFFI does not allow memory to be freed if
On Sat, May 21, 2011 at 1:21 AM, Luke Crook <luke@balooga.com> wrote: that
memory has not also been allocated using CFFI.
Indeed, you shouldn't call FOREIGN-FREE on pointers to memory not allocated by FOREIGN-ALLOC. You should be able to (defcfun free ...) and use that.
In my code below, a new 'sdl-version' struct is returned by (sdl-mixer-cffi::linked-version). The error seems to occur when I try to free the struct at the end of the function using foreign-free.
However, under SBCL FOREIGN-FREE is equivalent to free() -- not sure about CCL. According to SDL_Mixer's documentation, Mix_Linked_Version() returns a const pointer, so it seems that the bug here is that you're trying to free() non-malloc()ed memory.
Thank you for pointing that out. I will fix that bug in my code. /* rcg06192001 get linked library's version. */ 139 <http://hg.libsdl.org/SDL_mixer/file/4b699c9a269d/mixer.c#l139> const SDL_version *Mix_Linked_Version(void) 140 <http://hg.libsdl.org/SDL_mixer/file/4b699c9a269d/mixer.c#l140> { 141 <http://hg.libsdl.org/SDL_mixer/file/4b699c9a269d/mixer.c#l141> static SDL_version linked_version; 142 <http://hg.libsdl.org/SDL_mixer/file/4b699c9a269d/mixer.c#l142> SDL_MIXER_VERSION(&linked_version); 143 <http://hg.libsdl.org/SDL_mixer/file/4b699c9a269d/mixer.c#l143> return(&linked_version); 144 <http://hg.libsdl.org/SDL_mixer/file/4b699c9a269d/mixer.c#l144> } FYI; Lispworks doesn't complain about freeing the pointer. -Luke
On Sun, 2011-05-22 at 23:19 -0700, Luke Crook wrote:
On Sun, May 22, 2011 at 2:10 PM, Luís Oliveira <luismbo@gmail.com> wrote:
I think the problem is that CFFI does not allow memory to be freed if
On Sat, May 21, 2011 at 1:21 AM, Luke Crook <luke@balooga.com> wrote: that
memory has not also been allocated using CFFI.
Indeed, you shouldn't call FOREIGN-FREE on pointers to memory not allocated by FOREIGN-ALLOC. You should be able to (defcfun free ...) and use that.
In my code below, a new 'sdl-version' struct is returned by (sdl-mixer-cffi::linked-version). The error seems to occur when I try to free the struct at the end of the function using foreign-free.
However, under SBCL FOREIGN-FREE is equivalent to free() -- not sure about CCL. According to SDL_Mixer's documentation, Mix_Linked_Version() returns a const pointer, so it seems that the bug here is that you're trying to free() non-malloc()ed memory.
Thank you for pointing that out. I will fix that bug in my code.
/* rcg06192001 get linked library's version. */
139 <http://hg.libsdl.org/SDL_mixer/file/4b699c9a269d/mixer.c#l139> const SDL_version *Mix_Linked_Version(void)
140 <http://hg.libsdl.org/SDL_mixer/file/4b699c9a269d/mixer.c#l140> {
141 <http://hg.libsdl.org/SDL_mixer/file/4b699c9a269d/mixer.c#l141> static SDL_version linked_version;
142 <http://hg.libsdl.org/SDL_mixer/file/4b699c9a269d/mixer.c#l142> SDL_MIXER_VERSION(&linked_version);
143 <http://hg.libsdl.org/SDL_mixer/file/4b699c9a269d/mixer.c#l143> return(&linked_version);
144 <http://hg.libsdl.org/SDL_mixer/file/4b699c9a269d/mixer.c#l144> }
FYI; Lispworks doesn't complain about freeing the pointer.
Which probably means that Lispworks' foreign-free doesn't check that the pointer is valid, silently corrupting memory -- Stelian Ionescu a.k.a. fe[nl]ix Quidquid latine dictum sit, altum videtur. http://common-lisp.net/project/iolib
participants (3)
-
Luke Crook
-
Luís Oliveira
-
Stelian Ionescu