Throwing Prolog exceptions from C code
Hi there, I don't know if I am doing something stupid but, in order to throw a Prolog exception with term t from C code, I create the Term `throw(t)' and then I pass it to YapCallProlog(). Everything fails horribly and I have no idea why. I append a stack trace hoping it may be enlightening for someone. All the best Roberto -- Prof. Roberto Bagnara Computer Science Group Department of Mathematics, University of Parma, Italy http://www.cs.unipr.it/~bagnara/ mailto:bagnara@cs.unipr.it Program received signal SIGSEGV, Segmentation fault. do_goal (CodeAdr=0x81a5ac0 "", arity=1869768820, pt=0x81afe44, args_to_save=0, top=0) at C/exec.c:908 908 XREGS[i+1] = *pt++; (gdb) info stack #0 do_goal (CodeAdr=0x81a5ac0 "", arity=1869768820, pt=0x81afe44, args_to_save=0, top=0) at C/exec.c:908 #1 0x0806ce69 in execute_goal (t=135986753, nargs=0, mod=1) at C/exec.c:996 #2 0x0805025b in YapCallProlog (t=135986753) at C/c_interface.c:587 #3 0x400b631e in Prolog_raise_exception(unsigned long) (t=135986733) at /home/roberto/ppl/ppl/interfaces/Prolog/YAP/ppl_yap.cc:188 #4 0x400a6b0c in handle_exception(not_a_polyhedron_kind const&) ( e=@0x100e6b40) at /home/roberto/ppl/ppl/interfaces/Prolog/ppl_prolog.icc:139 #5 0x400a9303 in ppl_new_Polyhedron_from_dimension (t_tp=1686330, t_nd=54, t_ph=135986672) at /home/roberto/ppl/ppl/interfaces/Prolog/ppl_prolog.icc:681
I don't know if I am doing something stupid but, in order to throw a Prolog exception with term t from C code, I create the Term `throw(t)' and then I pass it to YapCallProlog(). Everything fails horribly and I have no idea why. I append a stack trace hoping it may be enlightening for someone.
That looks like a nasty bug :-(. I know it's not in the Manual, but have you tried using YapThrow(t) from the C-code? Cheers, Vitor
Vitor Santos Costa wrote:
I don't know if I am doing something stupid but, in order to throw a Prolog exception with term t from C code, I create the Term `throw(t)' and then I pass it to YapCallProlog(). Everything fails horribly and I have no idea why. I append a stack trace hoping it may be enlightening for someone.
That looks like a nasty bug :-(.
I know it's not in the Manual, but have you tried using
YapThrow(t)
from the C-code?
Hi Vitor, I have tried right now and still get a failure, but with a very different stack trace. Thanks a lot for your prompt responses Roberto -- Prof. Roberto Bagnara Computer Science Group Department of Mathematics, University of Parma, Italy http://www.cs.unipr.it/~bagnara/ mailto:bagnara@cs.unipr.it Program received signal SIGSEGV, Segmentation fault. 0x08051439 in StaticGetAPropHavingLock (ae=0x655f6e69, kind=65535) at Yatom.h:108 108 { (gdb) info stack #0 0x08051439 in StaticGetAPropHavingLock (ae=0x655f6e69, kind=65535) at Yatom.h:108 #1 0x08051481 in GetAProp (a=0x655f6e69, kind=65535) at C/adtdefs.c:264 #2 0x0809aebd in writeTerm (t=135986733, p=1200, depth=1, rinfixarg=0) at C/write.c:446 #3 0x0809b7c3 in plwrite (t=135986733, mywrite=0x807eee0 <format_putc>, flags=4) at C/write.c:675 #4 0x08080a37 in format (tail=135986955, args=34, sno=2) at C/iopreds.c:4227 #5 0x08080f4a in p_format2 () at C/iopreds.c:4356 #6 0x080a5f9a in absmi (inp=0) at C/absmi.c:5719 #7 0x0806c9bc in exec_absmi (top=1) at C/exec.c:881 #8 0x0806cbc2 in do_goal (CodeAdr=0x80f2130 "p'\n\bôÿÿÿ¨ \017\b", arity=0, pt=0x0, args_to_save=0, top=1) at C/exec.c:942 #9 0x0806d224 in RunTopGoal (t=214610) at C/exec.c:1128 #10 0x080504aa in YapRunGoal (t=214610) at C/c_interface.c:704 #11 0x0804eb11 in do_top_goal (Goal=214610) at console/yap.c:122 #12 0x0804f2b1 in exec_top_level (BootMode=1, filename=0x0) at console/yap.c:457 #13 0x0804f32f in main (argc=1, argv=0xbffff9e4) at console/yap.c:483 #14 0x42017499 in __libc_start_main () from /lib/i686/libc.so.6 (gdb)
I have tried right now and still get a failure, but with a very different stack trace.
That will take a bit more of time. I recently improved the C-interface to handle more of the functionality in SWI, and it seems I didn't do enough testing.
Thanks a lot for your prompt responses
Thanks for the bug reports! Cheers, Vitor
Hi Roberto,
Hi Vitor,
I have tried right now and still get a failure, but with a very different stack trace. Thanks a lot for your prompt responses
Sorry for the delay. There were indeed problems when using YapRunGoal, as it was only tested from the top-level. YapThrow and YapCallProlog seemed to be working fine. This is a program I used for testing (I updated some changes to the CVS version). Do you mind checking if it works for you? If it doesn't, please tell me. If it does, then I think I'll need some more info to track your bug. Cheers, Vitor PS: Yes, I know, the documentation is very bad :-(. /************************************************************************* * * * YAP Prolog * * * * Yap Prolog was developed at NCCUP - Universidade do Porto * * * * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * * * ************************************************************************** * * * File: x.c * * Last rev: * * mods: * * comments: example of exception handling in C-interface * * * *************************************************************************/ #include "config.h" #include "c_interface.h" #include <math.h> #if defined(__MINGW32__) || _MSC_VER #include <windows.h> #endif void PROTO(init_x, (void)); /* Throw a simple exception ?- x(a). */ static int p_x(void) { Term tf = YapMkAtomTerm(YapLookupAtom("hello")); YapThrow(tf); return(TRUE); } /* Throw a complex exception ?- x2(a). */ static int p_x2(void) { Term tf, t[3]; Functor f = YapMkFunctor(YapLookupAtom("f"),3); t[0] = YapMkAtomTerm(YapLookupAtom("hello")); t[1] = YapMkVarTerm(); t[2] = ARG1; tf = YapMkApplTerm(f,3,t); YapThrow(tf); return(TRUE); } /* Run a throw goal: exception is not thrown outside caller ?- ux(a). */ static int p_ux(void) { Term tf, t[3]; Functor f1 = YapMkFunctor(YapLookupAtom("throw"),1); Functor f2 = YapMkFunctor(YapLookupAtom("f"),3); t[0] = YapMkAtomTerm(YapLookupAtom("hello")); t[1] = YapMkVarTerm(); t[2] = ARG1; tf = YapMkApplTerm(f2,3,t); t[0] = tf; tf = YapMkApplTerm(f1,1,t); return(YapCallProlog(tf)); } /* Run goal as argument ?- g(X=2). ; ?- g(fail). ?- g(throw(a)). */ static int p_g(void) { return(YapCallProlog(ARG1)); } /* Run goal as argument and check for exceptions. Do a throw if so. ?- g2(X=2). ; ?- g2(fail). ?- g2(throw(a)). */ static int p_g2(void) { Term ex; int out = YapCallProlog(ARG1); if (YapGoalHasException(&ex)) { YapThrow(ex); return(FALSE); } return(out); } /* Use YapRunGoal, as it keeps the choice-point stack. Notice that we need to do prunegoal before we exit */ static int p_h(void) { int out = YapRunGoal(ARG1); if (out) { YapPruneGoal(); } return(out); } /* same and also check for exceptions. ?- h2(X=2). ; ?- h2(fail). ?- h2(throw(a)). */ static int p_h2(void) { Term ex; int out = YapRunGoal(ARG1); if (out) { YapPruneGoal(); } if (YapGoalHasException(&ex)) { YapThrow(ex); return(FALSE); } return(out); } void init_x(void) { UserCPredicate("x", p_x, 0); UserCPredicate("x", p_x2, 1); UserCPredicate("ux", p_ux, 1); UserCPredicate("g", p_g, 1); UserCPredicate("g2", p_g2, 1); UserCPredicate("h", p_h, 1); UserCPredicate("h2", p_h2, 1); } #ifdef _WIN32 int WINAPI PROTO(win_x, (HANDLE, DWORD, LPVOID)); int WINAPI win_x(HANDLE hinst, DWORD reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } return 1; } #endif
Vitor Santos Costa wrote:
Sorry for the delay.
There were indeed problems when using YapRunGoal, as it was only tested from the top-level. YapThrow and YapCallProlog seemed to be working fine.
This is a program I used for testing (I updated some changes to the CVS version). Do you mind checking if it works for you? If it doesn't, please tell me. If it does, then I think I'll need some more info to track your bug.
Dear Vitor, I have temporarily included your code into our YAP module (see near the end of http://www.cs.unipr.it/cgi-bin/cvsweb.cgi/ppl/interfaces/Prolog/YAP/ppl_yap.... It seems that the external predicates are not behaving as expected. I enclose under the signature the log of a gdb session. Please let me know what should I do to help in identifying the problem. All the best Roberto P.S. Very recently, a problem with the exception mechanism of GNU Prolog was identified. Roughly speaking, to make things work both GNU Prolog and foreign code have to be compiled with -fomit-frame-pointer, or both of them have to be compiled without using that option. Does this ring a bell? -- Prof. Roberto Bagnara Computer Science Group Department of Mathematics, University of Parma, Italy http://www.cs.unipr.it/~bagnara/ mailto:bagnara@cs.unipr.it $ gdb yap (gdb) r Starting program: /usr/local/bin/yap [ Restoring file startup ] [ YAP version Yap-4.3.22 ] ?- load_foreign_files(['ppl_yap'], [], init). yes ?- x(a). [ No handler for error f(hello,_96,a) ] ?- x2(a). no ?- ux(a). Program received signal SIGSEGV, Segmentation fault. 0x08051469 in StaticGetAPropHavingLock (ae=0x16911100, kind=65535) at Yatom.h:108 108 { (gdb) info stack #0 0x08051469 in StaticGetAPropHavingLock (ae=0x16911100, kind=65535) at Yatom.h:108 #1 0x080514b1 in GetAProp (a=0x16911100, kind=65535) at C/adtdefs.c:264 #2 0x0809af4d in writeTerm (t=135986733, p=1200, depth=1, rinfixarg=0) at C/write.c:446 #3 0x0809b853 in plwrite (t=135986733, mywrite=0x807ef10 <format_putc>, flags=4) at C/write.c:675 #4 0x08080a67 in format (tail=135986987, args=34, sno=2) at C/iopreds.c:4227 #5 0x08080f7a in p_format2 () at C/iopreds.c:4356 #6 0x080a602a in absmi (inp=0) at C/absmi.c:5719 #7 0x0806c9ec in exec_absmi (top=1) at C/exec.c:881 #8 0x0806cbf2 in do_goal (CodeAdr=0x80f2130 "", arity=0, pt=0x0, args_to_save=0, top=1) at C/exec.c:942 #9 0x0806d254 in RunTopGoal (t=214610) at C/exec.c:1128 #10 0x080504da in YapRunGoal (t=214610) at C/c_interface.c:704 #11 0x0804eb41 in do_top_goal (Goal=214610) at console/yap.c:122 #12 0x0804f2e1 in exec_top_level (BootMode=1, filename=0x0) at console/yap.c:457 #13 0x0804f35f in main (argc=1, argv=0xbffff994) at console/yap.c:483 #14 0x42017499 in __libc_start_main () from /lib/i686/libc.so.6 (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /usr/local/bin/yap [ Restoring file startup ] [ YAP version Yap-4.3.22 ] ?- load_foreign_files(['ppl_yap'], [], init). yes ?- g(X=2). no ?- g(fail). no ?- g(throw(a)). [ No handler for error a ] ?- h2(X=2). no ?- h2(fail). [ YAP version Yap-4.3.22 ] ?- h2(throw(a)). [ YAP version Yap-4.3.22 ] ?- Program exited normally. (gdb) q $
I have temporarily included your code into our YAP module (see near the end of http://www.cs.unipr.it/cgi-bin/cvsweb.cgi/ppl/interfaces/Prolog/YAP/ppl_yap.... It seems that the external predicates are not behaving as expected. I enclose under the signature the log of a gdb session. Please let me know what should I do to help in identifying the problem.
Hi Roberto. First, are you using the very latest CVS version? I uploaded several changes. Just to be sure. If so, what is the OS/compiler you are using?
P.S. Very recently, a problem with the exception mechanism of GNU Prolog was identified. Roughly speaking, to make things work both GNU Prolog and foreign code have to be compiled with -fomit-frame-pointer, or both of them have to be compiled without using that option. Does this ring a bell?
Actually, I do the opposite: I always compile the interface with frame pointer active. Strange. Cheers, Vitor
participants (2)
-
Roberto Bagnara -
Vitor Santos Costa