brunoalano / pyswip

Automatically exported from code.google.com/p/pyswip
MIT License
0 stars 0 forks source link

Segmentation fault when assertz-ing #1

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
On Ubuntu Gutsy, x86_64, python 2.4 and 2.5, SWI 5.6.50, I get the following:

Python 2.4.4 (#2, Oct  4 2007, 23:56:01) 
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyswip import Prolog
>>> prolog = Prolog()
>>> prolog.assertz("parent(yves,jm)")
Segmentation fault (core dumped)

Not really informative for now, I'll try to dig more into that

Original issue reported on code.google.com by yves.rai...@gmail.com on 21 Feb 2008 at 11:44

GoogleCodeExporter commented 9 years ago
I guess it's a 64bit platform issue. Do you observe the same problem when you 
run the
query in SWI-Prolog (using pl)?

Original comment by yucete...@gmail.com on 22 Feb 2008 at 6:44

GoogleCodeExporter commented 9 years ago
I've found the following:
http://retrograde-orbit.blogspot.com/2008/01/ctypes-bug-is-not-ctypes-bug.html

Could you please add this to core.py at about line 48 and try again?

class c_void(Structure):
    __fields__ = [('dummy',c_int)]
c_void_p = POINTER(c_void)

Thanks.

Original comment by yucete...@gmail.com on 22 Feb 2008 at 7:24

GoogleCodeExporter commented 9 years ago
core.py can be patched with the following:

=== cut ===
--- core.py.ORIG 
+++ core.py 
@@ -45,6 +45,11 @@
     print>>sys.stderr, "1) SWI-Prolog not installed as a shared library. Install
SWI-Prolog (5.6.34 works just fine)"
     sys.exit(1)

+# The following fixes a nasty ctypes 64bit bug.
+# Ref: http://code.google.com/p/pyswip/issues/detail?id=1
+class c_void(Structure):
+    __fields__ = [('dummy',c_int)]
+c_void_p = POINTER(c_void)

 # PySWIP constants
 PYSWIP_MAXSTR = 1024
@@ -462,6 +467,8 @@
 #PL_EXPORT(int)        PL_erase_external(char *rec);

 PL_new_module = _lib.PL_new_module
+PL_new_module.argtypes = [atom_t]
+PL_new_module.restype = module_t

 intptr_t = c_long
 ssize_t = intptr_t
=== cut ===

Original comment by yucete...@gmail.com on 22 Feb 2008 at 7:50

GoogleCodeExporter commented 9 years ago
Hello! (Sorry for being slow...)
I just tried out the above patch, but it still gives the same error (segfault 
when
doing assert(a|z)) :(
It works just fine on the Prolog command line.

I tried a few variations of 
http://retrograde-orbit.blogspot.com/2008/01/ctypes-bug-is-not-ctypes-bug.html
without much success so far...

Cheers!
y

Original comment by yves.rai...@gmail.com on 22 Feb 2008 at 10:29

GoogleCodeExporter commented 9 years ago
Hi,

I've miswritten _fields_ as __fields__ ; could you fix it and give it a try?

If that doesn't work, could you try to run the following?

from pyswip import *
assertz = Functor("assertz", 1)
father = Functor("father", 2)
call(assertz(father("a","b")))
q = Query(father("a","b"))
print q.nextSolution()

Thanks

Original comment by yucete...@gmail.com on 22 Feb 2008 at 11:11

GoogleCodeExporter commented 9 years ago
hello! i did saw the miswriting when checking the blog post, but it gives the 
same
result :( 
when running this bit of code, it segfaults at q = Query(father("a","b")):

>>> from pyswip import *
>>> assertz = Functor("assertz", 1)
>>> father = Functor("father", 2)
>>> call(assertz(father("a","b")))
1
>>> q = Query(father("a","b"))
Segmentation fault (core dumped)

Cheers!
y

Original comment by yves.rai...@gmail.com on 22 Feb 2008 at 11:17

GoogleCodeExporter commented 9 years ago
Query class is smaller than Prolog class's query function, so debugging it 
would be
simpler.

Could you please have a look at the Query constructor in easy.py between the 
lines
406-420 and try to narrow down whereabouts of the problem?(I know I'm supposed 
to do
that ;), but I'm unable to reproduce the problem here)  I'm especially 
suspicious
about lines 418-420.

Thanks

Original comment by yucete...@gmail.com on 22 Feb 2008 at 11:41

GoogleCodeExporter commented 9 years ago
Np :)
In the Query constructor, it segfaults at:
>>> from pyswip import *
>>> t = "father(a,b)"
>>> f = Functor.fromTerm(t)
Segmentation fault (core dumped)

Diving in a bit deeper give:
>>> from pyswip import *
>>> t = "father(a,b)"
>>> f = functor_t()
>>> PL_get_functor(t,addressof(f))
Segmentation fault (core dumped)

So it gets pretty low-level:
>>> core._lib.PL_get_functor(t,addressof(f))
Segmentation fault (core dumped)

Hope that helps...
y

Original comment by yves.rai...@gmail.com on 22 Feb 2008 at 12:00

GoogleCodeExporter commented 9 years ago

>>> t = "father(a,b)"
>>> core._lib.PL_get_functor(t,addressof(f))

I don't think that's supposed to work, since before that PL_get_chars should be
called to convert the string to a term.

>>> t = "father(a,b)"
>>> f = Functor.fromTerm(t)

This is also expected to be problematic, since "father(a,b)" is not 
automatically
converted to a term; but maybe Functor.fromTerm should check the type of its
arguments, and never should segfault (this is almost unavoidable when writing 
Python
code that interfaces with C)

If you've tried something like Query("father(a,b)") then it's not how pyswip is
supposed to work, it should be Query(father("a","b")).

Could you please change __init__ method of Query class with the following, so 
we see
exactly which line fails?

    def __init__(self, *terms, **kwargs):
        for key in kwargs:
            if key not in ["flags", "module"]:
                raise Exception("Invalid kwarg: %s" % key, key)

        print "1"
        flags = kwargs.get("flags", PL_Q_NODEBUG|PL_Q_CATCH_EXCEPTION)
        print "2"
        module = kwargs.get("module", None)
        print "3"

        t = terms[0]
        for tx in terms[1:]:
            t = _comma(t, tx)

        print "4"
        f = Functor.fromTerm(t)
        print "5"
        p = PL_pred(f.handle, module)
        print "6"
        Query.qid = PL_open_query(module, flags, p, f.a0)
        print "7"

Thanks ;)

Original comment by yucete...@gmail.com on 22 Feb 2008 at 12:56

GoogleCodeExporter commented 9 years ago
Well, as i mentioned above, it goes up to Functor.fromTerm(t)

>>> from pyswip import *
>>> assertz = Functor("assertz", 1)
>>> father = Functor("father", 2)
>>> call(assertz(father("a","b")))
1
>>> q = Query(father("a","b"))
1
2
3
4
Segmentation fault (core dumped)

Original comment by yves.rai...@gmail.com on 22 Feb 2008 at 1:14

GoogleCodeExporter commented 9 years ago
It seems the problem happens when calling PL_get_functor, as you found out. I 
could
segfault the interpreter using:

>>> from pyswip import *
>>> f = functor_t()
>>> PL_get_functor(1099,addressof(f))
0
>>> PL_get_functor(1000,addressof(f))
0
>>> PL_get_functor(5000,addressof(f))
Segmentation fault

The C counterpart of the last line doesn't crash but runs the debugger:

#include <stdio.h>
#include <SWI-Prolog.h>

int main(int argc, char **argv) {
    char *program = argv[0];
    char *plav[2];
    int n;
    functor_t f;

    plav[0] = program;
    plav[1] = NULL;

    if (!PL_initialise(1, plav))
        PL_halt(1);

    PL_get_functor(5000, &f);

    PL_halt(0);
    return 0;
}

It seems, the term reference passed to Functor.fromTerm is garbage. The term is
created by Functor.__call__, so I need to investigate that too. I'll also look 
at
Prolog.QueryWrapper.__call__ (which also messes with terms).

I didn't get a report on this for 32bit, so I'll assume this is a 64bit issue 
for
now; that means I should check integer and long types (c_int, c_ulong, etc.) in
__init__.py.

I'll post what I'll found, please you do so too :)

Thanks.

Also I found I've assigned Prolog types wrong 

Original comment by yucete...@gmail.com on 22 Feb 2008 at 2:39

GoogleCodeExporter commented 9 years ago
Any news about this problem since then ?

Original comment by dia.alj...@gmail.com on 26 Sep 2008 at 2:42

GoogleCodeExporter commented 9 years ago
Sadly no, I don't have the time to deal with pyswip anymore, and it seems nobody
wants to maintain it :(

Original comment by yucete...@gmail.com on 26 Sep 2008 at 2:45

GoogleCodeExporter commented 9 years ago
After trying to understand as I could and fighting with c_types, i first found 
an
error in your source in "core.py", line 293 where you put :
"PL_atom__restype = [c_char_p]" instead of "PL_atom_chars.restype = c_char_p"
And then, I went on checking "restypes" for each function and I added two lines 
:
"PL_get_atom.argtypes = [term_t, c_ulong]"
and
"PL_get_functor.argtypes = [term_t, c_ulong]"
(I guess we should check other argtypes and restypes if another segfault appear 
again)

Hope that helps ;-)

Original comment by dia.alj...@gmail.com on 9 Oct 2008 at 8:28

GoogleCodeExporter commented 9 years ago
Thanks :)

Would you like to be the maintainer of the project? If so I'll give you 
developer access.

Original comment by yucete...@gmail.com on 9 Oct 2008 at 10:05

GoogleCodeExporter commented 9 years ago
Well, sorry but I guess I don't have enough time for that but i'll think about 
it.

Original comment by dia.alj...@gmail.com on 9 Oct 2008 at 10:57

GoogleCodeExporter commented 9 years ago
Is there a similar way to do for ints?

Original comment by dksre...@gmail.com on 5 Nov 2009 at 2:44

GoogleCodeExporter commented 9 years ago
Following up and using the above suggestion, I made the segfault go away with 
this patch:

Index: pyswip/core.py
===================================================================
--- pyswip/core.py      (revision 111)
+++ pyswip/core.py      (working copy)
@@ -321,7 +321,7 @@

 PL_atom_chars = _lib.PL_atom_chars
 PL_atom_chars.argtypes = [atom_t]
-PL_atom_restype = [c_char_p]
+PL_atom_chars.restype = c_char_p

 PL_predicate = _lib.PL_predicate
 PL_predicate.argtypes = [c_char_p, c_int, c_char_p]
Index: pyswip/easy.py
===================================================================
--- pyswip/easy.py      (revision 111)
+++ pyswip/easy.py      (working copy)
@@ -40,7 +40,7 @@
         else:
             self.handle = handleOrChars
             PL_register_atom(self.handle)
-            self.chars = c_char_p(PL_atom_chars(self.handle)).value
+            self.chars = PL_atom_chars(self.handle)

     def fromTerm(cls, term):
         """Create an atom from a Term or term handle."""

Original comment by dylan-go...@dylex.net on 13 Oct 2011 at 8:54

GoogleCodeExporter commented 9 years ago
I too have the segfault problem.

Platform: 64-bit Ubuntu 10.04.3, swi 5.10.5, pyswip revision 111
I tried Dylan's changes but that didn't fix the segfault for me.  Dylan, could 
you have made any additional changes that you didn't report?

The good news is that the problem doesn't occur on 64-bit Ubuntu 11.10.

Original comment by Stanc...@gmail.com on 20 Jan 2012 at 10:29

GoogleCodeExporter commented 9 years ago
I made the changes specified in Comment 18 by Dylan.
I run on ubuntu 12.04 64-bit Segmentation Fault still exists

Original comment by mahesh.m...@gmail.com on 13 Jun 2012 at 4:29

GoogleCodeExporter commented 9 years ago
Having same issue on OS X, before and after applying Dylan's patch.

OS X 10.7.4
SWI-Prolog version 6.0.2 for i386-darwin11.4.0
Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
pyswip 0.2.2

>>> from pyswip import Prolog
>>> prolog = Prolog()
>>> prolog.consult("test.pl")
Segmentation fault: 11

File test.pl is OK and works just fine using swipl.

?- [test].
% test compiled 0.00 sec, 65 clauses
true.

Any news or suggestions? THANKS.

Original comment by cbcafi...@gmail.com on 24 Jun 2012 at 2:32

GoogleCodeExporter commented 9 years ago
Addendum: Ditto for test in pyswip/prolog.py

me$ python pyswip/prolog.py
?- assertz(father(michael,john)). [ Michael is the father of John ]
Segmentation fault: 11

Original comment by cbcafi...@gmail.com on 24 Jun 2012 at 3:40

GoogleCodeExporter commented 9 years ago
Following all the source changes listed in this thread, I was able to get 
PySWIP working on Ubuntu 10.04 64-bit!  Thank you to everyone who helped.

Now that there is working code, I think it would be nice to upload it to the 
PySWIP site: http://code.google.com/p/pyswip/

Is anyone currently an admin?

Original comment by jpthomps...@gmail.com on 10 Aug 2012 at 5:24

GoogleCodeExporter commented 9 years ago
Actually, my last comment wasn't completely correct.  The Sudoku solver works 
but Send More Money still has a segmentation fault.

Original comment by jpthomps...@gmail.com on 10 Aug 2012 at 5:30

GoogleCodeExporter commented 9 years ago

Hi jpthompson23,

Rodrigo Starr updated the code to work on 64bit in May. Are you using the 
latest code in the svn?

Yuce

Original comment by yucete...@gmail.com on 10 Aug 2012 at 7:45

GoogleCodeExporter commented 9 years ago
No, I had been using the one from here 
http://code.google.com/p/pyswip/downloads/list

But I just downloaded the one from svn using "svn checkout 
http://pyswip.googlecode.com/svn/trunk/ pyswip-read-only" and I found that the 
examples still segfault--even the sudoku one, which should work if he applied 
the fixes in this thread like I did.

Original comment by jpthomps...@gmail.com on 10 Aug 2012 at 8:30

GoogleCodeExporter commented 9 years ago
Rodrigo Starr didn't make this fix in the code: 
http://code.google.com/p/pyswip/issues/detail?id=1#c14

Original comment by jpthomps...@gmail.com on 10 Aug 2012 at 8:37

GoogleCodeExporter commented 9 years ago
I've added you as a commiter to the project. It would be great if you could 
update the code in the svn with your fixes.

Original comment by yucete...@gmail.com on 10 Aug 2012 at 11:07

GoogleCodeExporter commented 9 years ago
Thanks!  Try testing out the latest here: 

http://code.google.com/p/pyswip/downloads/detail?name=pyswip-0.2.2-r118.tar.gz

Original comment by jpthomps...@gmail.com on 14 Aug 2012 at 3:39

GoogleCodeExporter commented 9 years ago
BTW, I noticed that PySWIP is much more stable if SWI-Prolog is compiled using 
the -ggdb flag.  I don't know why this is.  Does anyone have any insight?  I am 
on Ubuntu 10.04 and my SWIP version is 6.0.2.

Original comment by jpthomps...@gmail.com on 14 Aug 2012 at 3:43

GoogleCodeExporter commented 9 years ago
I tested this patch in several systems (Windows and Linux, 32 and 64) and the 
error did not repeat.

I will close this issue as the patch seems to be working.

Original comment by rodrigo....@gmail.com on 29 Dec 2012 at 12:23

GoogleCodeExporter commented 9 years ago
In Comment 4 of issue 17 
(http://code.google.com/p/pyswip/issues/detail?id=17#c4), alexchandel describes 
a problem with OS X. I am reopening the issue until that problem is solved.

Original comment by rodrigo....@gmail.com on 20 Jan 2013 at 1:45

GoogleCodeExporter commented 9 years ago
great job on the issues! One of the last 4 commits (r132-r135) fixed the OS X 
segfaults. I successfully ran the hello world, and the Send More Money example 
on r135. Haven't tried the foreign language interface though.

Original comment by alexchan...@gmail.com on 22 Jan 2013 at 5:33

GoogleCodeExporter commented 9 years ago
Thanks for the feedback alexchandel.

I am closing this issue again.

Original comment by rodrigo....@gmail.com on 19 May 2013 at 1:45