Subject: Raising exceptions with goal and call stack info

From: Katzer Joachim <[email-masked]>
Date: Mon, 11 Sep 2000 16:01:49 +0200

Hi,

i have written an extended throw predicate that raises an exception term like error(Type,Info)
where Info is a Key=Value list for additional information. I want to add the calling goal and the
call stack to this list. 

These are the predicates:

%% File exception.pl
exception(Error,Info) :-
	( is_list(Info) -> append(Info,SysInfo,XInfo)
	; XInfo = [Info|SysInfo]
	),
            prolog_current_frame(This),
	prolog_frame_attribute(This,parent,Parent),
	prolog_frame_attribute(Parent,goal,Goal),
	prolog_frame_attribute(Parent,parent,GParent),
	prolog_call_stack(GParent, Stack),
	SysInfo=[backtrace=Stack,goal=Goal],
	throw(error(Error,XInfo)).

prolog_call_stack(Frame, Stack) :- prolog_call_stack(Frame, [], Stack), !.
prolog_call_stack(Frame, ChildCall, Stack) :-
	prolog_frame_attribute(Frame,parent,Parent),
	prolog_frame_attribute(Frame,goal,Goal),
	( Goal = M:G -> M \== '$toplevel', functor(G,F,A), C = M:F/A
	; functor(Goal,F,A) -> C = F/A
	; C = Goal
	),
	( C = ChildCall -> Stack = Cs ; Stack = [C|Cs] ),
	!, prolog_call_stack(Parent,C,Cs).
prolog_call_stack(_,_,[]).

%% This is an example:

foo(1) :- bar(1).
bar(1) :- exception(foo(bar),[info=test]).

%% End of file 

In debug mode this works fine:

?- debug, catch(foo(1),E,writeq(E)).
error(foo(bar), [info=test, backtrace=[foo/1, system:catch/3, system:'$call'/1], goal=bar(1)])

E = error(foo(bar), [info=test, backtrace=[foo/1, system:catch/3, system:'$call'/1], goal=bar(1)]) 

Yes

But in nodebug mode SWI-Prolog crashs (segmentation fault on Solaris, stack overflow on WindowsNT):

?- catch(foo(1),E,writeq(E)).
Segmentation fault (core dumped)

Is there something wrong with this idea, or is this an SWI bug?
I'm using SWI-Prolog 3.3.10, on Solaris the additional exception/catch patch.

Thx 

Joachim Katzer