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

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

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?

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