
Hello, I get a segfault when I do str <- peekCString ptr free ptr return (Just str) But not when I don't free the C pointer. I also get the same behaviour with ByteString.packCString... Could you please tell me if the memory is correctly freed by GHC when I don't do it myself? And how can I specify a custom free function (i.e. xmlFree function in libxml2)? Maybe I should use a data type with two fields : the String/ByteString and the ForeignPtr to the CString? Regards

Could you expand on this fragment of code? Perhaps a fullying
compilable example? It depends how you are getting the pointer, not
how you are reading data out of the pointer. For example, if you use
"withCString" to get ptr then the memory will be freed automatically.
Thomas
On Sun, Nov 29, 2009 at 9:00 AM, El Barto
Hello, I get a segfault when I do str <- peekCString ptr free ptr return (Just str)
But not when I don't free the C pointer. I also get the same behaviour with ByteString.packCString...
Could you please tell me if the memory is correctly freed by GHC when I don't do it myself? And how can I specify a custom free function (i.e. xmlFree function in libxml2)? Maybe I should use a data type with two fields : the String/ByteString and the ForeignPtr to the CString?
Regards
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Hello El, Sunday, November 29, 2009, 8:00:02 PM, you wrote: segfault is due to free, you may omit peekCString call. you should free only memory that was malloced and not freed other way
Hello, I get a segfault when I do str <- peekCString ptr free ptr return (Just str)
But not when I don't free the C pointer. I also get the same behaviour with ByteString.packCString...
Could you please tell me if the memory is correctly freed by GHC when I don't do it myself? And how can I specify a custom free function (i.e. xmlFree function in libxml2)? Maybe I should use a data type with two fields : the String/ByteString and the ForeignPtr to the CString?
Regards
-- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On Sun, 2009-11-29 at 18:00 +0100, El Barto wrote:
Hello, I get a segfault when I do str <- peekCString ptr free ptr return (Just str)
As Thomas says, you've not really given us enough info here. I'll make some guesses and observations anyway :-)
But not when I don't free the C pointer.
Are you sure the C code does not also free the memory? That would lead to a double-free which can easily manifest as a segfault.
I also get the same behaviour with ByteString.packCString...
That's pretty odd since packCString does not free the C string, it makes a copy. I suppose it could possibly segfault if your C string was not actually null terminated (as C strings must be). There are also variants that do not copy, such as unsafePackMallocCString. See the docs for a description.
Could you please tell me if the memory is correctly freed by GHC when I don't do it myself? And how can I specify a custom free function (i.e. xmlFree function in libxml2)?
See the documentation for ForeignPtr.
Maybe I should use a data type with two fields : the String/ByteString and the ForeignPtr to the CString?
Is your C String supposed to be freed using the C free() function, or is it supposed to be freed using xmlFree() or something? Duncan

Thanks for your help & time,
I checked the C API documentation:
http://xmlsoft.org/html/libxml-xmlreader.html#xmlTextReaderValue
"The result must be deallocated with xmlFree()"
I pushed the sources here:
http://github.com/gwenn/libxml-reader
My problem is with the function at line 249 in Text.XML.LibXML.XmlReader
To make it work, I have to comment out the line where xmlFree is called.
-- xmlChar * xmlTextReaderValue(xmlTextReaderPtr reader)
-- Returns:the string or NULL if not available. The result must be
deallocated with xmlFree()
foreign import ccall unsafe "xmlreader.h xmlTextReaderValue"
c_xmlTextReaderValue :: Ptr XmlTextReader -> IO (CString)
value :: (MonadIO m) => XmlReader -> m (Maybe B.ByteString)
value (XmlReader reader_fp) = liftIO $
withForeignPtr reader_fp $ \reader_ptr -> do
cstr <- c_xmlTextReaderValue reader_ptr
fromPtr B.packCString cstr c_xmlFree
fromPtr :: (Ptr a -> IO b) -> Ptr a -> (Ptr a -> IO ()) -> IO (Maybe b)
fromPtr c2h ptr free | ptr == nullPtr = return Nothing
| otherwise = do
r <- c2h ptr
free ptr -- FIXME
return (Just r)
May be the binding to xmlFree is wrong?
foreign import ccall unsafe "xmlreader.h xmlFree"
c_xmlFree :: Ptr a -> IO ()
To test, you will need libxml2-dev:
$ runhaskell Setup configure --extra-include-dirs=/usr/include/libxml2/
$ runhaskell Setup build
$ ./dist/build/Test/Test
C functions are described here:
http://xmlsoft.org/html/libxml-xmlreader.html
And here:
http://xmlsoft.org/html/libxml-globals.html
Regards.
On Sun, Nov 29, 2009 at 7:02 PM, Duncan Coutts wrote: On Sun, 2009-11-29 at 18:00 +0100, El Barto wrote: Hello,
I get a segfault when I do
str <- peekCString ptr
free ptr
return (Just str) As Thomas says, you've not really given us enough info here. I'll make some guesses and observations anyway :-) But not when I don't free the C pointer. Are you sure the C code does not also free the memory? That would lead
to a double-free which can easily manifest as a segfault. I also get the same behaviour with ByteString.packCString... That's pretty odd since packCString does not free the C string, it makes
a copy. I suppose it could possibly segfault if your C string was not
actually null terminated (as C strings must be). There are also variants that do not copy, such as
unsafePackMallocCString. See the docs for a description. Could you please tell me if the memory is correctly freed by GHC when
I don't do it myself?
And how can I specify a custom free function (i.e. xmlFree function in
libxml2)? See the documentation for ForeignPtr. Maybe I should use a data type with two fields : the String/ByteString
and the ForeignPtr to the CString? Is your C String supposed to be freed using the C free() function, or is
it supposed to be freed using xmlFree() or something? Duncan

Ok,
I used this advice:
http://www.haskell.org/haskellwiki/GHC/Using_the_FFI#Importing_C_functions_t...
to make 'xmlFree' callable from Haskell.
I was completly wrong in my first post...
I do apologize.
On Sun, Nov 29, 2009 at 8:56 PM, El Barto
Thanks for your help & time,
I checked the C API documentation: http://xmlsoft.org/html/libxml-xmlreader.html#xmlTextReaderValue "The result must be deallocated with xmlFree()"
I pushed the sources here: http://github.com/gwenn/libxml-reader
My problem is with the function at line 249 in Text.XML.LibXML.XmlReader To make it work, I have to comment out the line where xmlFree is called.
-- xmlChar * xmlTextReaderValue(xmlTextReaderPtr reader) -- Returns:the string or NULL if not available. The result must be deallocated with xmlFree() foreign import ccall unsafe "xmlreader.h xmlTextReaderValue" c_xmlTextReaderValue :: Ptr XmlTextReader -> IO (CString) value :: (MonadIO m) => XmlReader -> m (Maybe B.ByteString) value (XmlReader reader_fp) = liftIO $ withForeignPtr reader_fp $ \reader_ptr -> do cstr <- c_xmlTextReaderValue reader_ptr fromPtr B.packCString cstr c_xmlFree
fromPtr :: (Ptr a -> IO b) -> Ptr a -> (Ptr a -> IO ()) -> IO (Maybe b) fromPtr c2h ptr free | ptr == nullPtr = return Nothing | otherwise = do r <- c2h ptr free ptr -- FIXME return (Just r)
May be the binding to xmlFree is wrong? foreign import ccall unsafe "xmlreader.h xmlFree" c_xmlFree :: Ptr a -> IO ()
To test, you will need libxml2-dev: $ runhaskell Setup configure --extra-include-dirs=/usr/include/libxml2/ $ runhaskell Setup build $ ./dist/build/Test/Test
C functions are described here: http://xmlsoft.org/html/libxml-xmlreader.html And here: http://xmlsoft.org/html/libxml-globals.html
Regards.
On Sun, Nov 29, 2009 at 7:02 PM, Duncan Coutts < duncan.coutts@googlemail.com> wrote:
On Sun, 2009-11-29 at 18:00 +0100, El Barto wrote:
Hello, I get a segfault when I do str <- peekCString ptr free ptr return (Just str)
As Thomas says, you've not really given us enough info here.
I'll make some guesses and observations anyway :-)
But not when I don't free the C pointer.
Are you sure the C code does not also free the memory? That would lead to a double-free which can easily manifest as a segfault.
I also get the same behaviour with ByteString.packCString...
That's pretty odd since packCString does not free the C string, it makes a copy. I suppose it could possibly segfault if your C string was not actually null terminated (as C strings must be).
There are also variants that do not copy, such as unsafePackMallocCString. See the docs for a description.
Could you please tell me if the memory is correctly freed by GHC when I don't do it myself? And how can I specify a custom free function (i.e. xmlFree function in libxml2)?
See the documentation for ForeignPtr.
Maybe I should use a data type with two fields : the String/ByteString and the ForeignPtr to the CString?
Is your C String supposed to be freed using the C free() function, or is it supposed to be freed using xmlFree() or something?
Duncan
participants (4)
-
Bulat Ziganshin
-
Duncan Coutts
-
El Barto
-
Thomas DuBuisson