/* File: flrdebugger.P -- Flora debugger ** ** Author(s): Michael Kifer ** Contact: flora-users@lists.sourceforge.net ** ** Copyright (C) The Research Foundation of SUNY, 2001 ** ** FLORA-2 is free software; you can redistribute it and/or modify it under the ** terms of the GNU Library General Public License as published by the Free ** Software Foundation; either version 2 of the License, or (at your option) ** any later version. ** ** FLORA-2 is distributed in the hope that it will be useful, but WITHOUT ANY ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ** FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for ** more details. ** ** You should have received a copy of the GNU Library General Public License ** along with FLORA-2; if not, write to the Free Software Foundation, ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** $Id: flrdebugger.P,v 1.22 2003/06/18 07:01:33 kifer Exp $ ** */ :- compiler_options([xpp_on]). #include "standard.h" #include "flrheader.flh" #include "flora_terms.flh" :- import file_close/1, ioport2iostream/2 from file_io. :- import debug_display_call_hook/1, flora_switch/1 from usermod. :- import flora_configuration/2 from flrregistry. :- import process_control/2 from shell. :- import xpp_process_file/3 from parse. :- import flora_decode_predicate/6, flora_module_name/3, flora_module_predicate_symbol/3 from flrwrapper. :- import flora_set_xpp_options_for_read/1, flora_set_xpp_options_for_read/0, flora_clear_xpp_options/0 from flrutils. :- import flora_message_line/1, flora_message_line/2 from flrprint. :- import flLoadedModule/1 from flora2. :- import flora_concat_atoms/2, flora_slash/1, flora_set_counter/2 from flrporting. :- import flora_write_goal/2 from flrdecode. :- import flora_handle_trace/0, flora_handle_notrace/0 from usermod. %% This is a trick: the debugger wants the hook to be in usermod, %% but we want to work in a module :- import flora_write_debugger_hook/1 from usermod. :- dynamic debug_display_call_hook/1. :- dynamic flora_switch/1. :- dynamic flora_write_debugger_hook/1. :- dynamic hide_this_hide/2, show_this_hide/2, hide_this_show/2, trace_this_noprint/2, trace_this_print/2, flora_hide_this_hide/1, flora_hide_this_show/1, flora_show_this_hide/1, flora_trace_this_noprint/1, flora_trace_this_print/1. :- import hide_this_hide/2, show_this_hide/2, hide_this_show/2, trace_this_noprint/2, trace_this_print/2, flora_hide_this_hide/1, flora_hide_this_show/1, flora_show_this_hide/1, flora_trace_this_noprint/1, flora_trace_this_print/1 from usermod. :- export flora_read_debugger_data/1, flora_load_dyndata_for_user_modules/1, FLORA_SYMBOL('debugger_loaded'), flora_trace/0, flora_notrace/0. %% Assert the debugger hook ?- assert(debug_display_call_hook(flora_write_debugger_hook)). ?- assert(( flora_write_debugger_hook(X) :- (\+flora_switch(low_level_trace) -> flora_write_debug_call(X) ; flora_write_dbg_item(X) ) )). %% Get the debugging output stream :- dynamic flora_dbg_stream/1. ?- (flora_dbg_stream(Stream) -> close(Stream), retractall(flora_dbg_stream(_)) ; ioport2iostream(STDDBG,Stream), assert(flora_dbg_stream(Stream)) ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% flora_write_goal %%%%%%%%%%%%%%%%%%%%%%%%%%% flora_write_debug_call(Call) :- flora_dbg_stream(Stream), flora_write_goal(Stream,Call). flora_write_dbg_item(Item) :- flora_dbg_stream(Stream), write(Stream,Item). /*********************************************************************/ flora_trace :- assert(flora_switch(trace)), flora_handle_trace. flora_notrace :- retractall(flora_switch(trace)), flora_handle_notrace. /*********************************************************************/ flora_debug_dyndata_file(Filename) :- flora_configuration(installdir,FlrSysLib), flora_slash(S), flora_concat_atoms([FlrSysLib,S,debugger,S,'dynamic_data.dat'],Filename). flora_debug_statdata_file(Filename) :- flora_configuration(installdir,FlrSysLib), flora_slash(S), flora_concat_atoms([FlrSysLib,S,debugger,S,'static_data.dat'],Filename). %% If WS is a var -- loading static data %% Otherwise, loading dynamic data for the specified module flora_read_debugger_data(WS,_Datafile) :- %% Check if already loaded (var(WS) -> current_predicate(FLORA_SYMBOL('debugger_static_data_loaded')/0) ; flora_module_predicate_symbol(debugger_data_loaded, WS, WSSym), current_predicate(WSSym/0) ), !. flora_read_debugger_data(WS,Datafile) :- (var(WS) -> flora_set_xpp_options_for_read ; flora_set_xpp_options_for_read(WS) ), xpp_process_file(Datafile, CPP_process, IOportFromCPP), repeat, file_read(IOportFromCPP,T), (T = end_of_file -> true ; assert(T), fail ), process_control(CPP_process, wait(ExitStatus)), (ExitStatus==0, ! ; abort(('[Debugger] Error while preprocessing ', Datafile)) ), flora_clear_xpp_options, file_close(IOportFromCPP), flora_set_counter(xpp_on,0), (var(WS) -> flora_message_line('Static debugger data loaded') ; flora_message_line('Dynamic debugger data loaded for module ~w', WS) ), !. %% Read dynamic data for preloaded user modules flora_load_dyndata_for_user_modules([]). flora_load_dyndata_for_user_modules([M|List]) :- flora_debug_dyndata_file(DataFile), flora_read_debugger_data(M,DataFile), flora_load_dyndata_for_user_modules(List). flora_load_statdata :- flora_debug_statdata_file(DataFile), flora_read_debugger_data(_M,DataFile). %% The bridge is disabled during low level tracing flora_build_bridge_to_xsb_debugger :- assert((hide_this_hide(X,Y) :- \+flora_switch(low_level_trace),flora_hide_this_hide(X/Y))), assert((hide_this_show(X,Y) :- \+flora_switch(low_level_trace),flora_hide_this_show(X/Y))), assert((show_this_hide(X,Y) :- \+flora_switch(low_level_trace),flora_show_this_hide(X/Y))), assert((trace_this_noprint(X,Y) :- \+flora_switch(low_level_trace),flora_trace_this_noprint(X/Y))), assert((trace_this_print(X,Y) :- \+flora_switch(low_level_trace),flora_trace_this_print(X/Y))), %% Rule for handling system modules. %% This prevents tracing inside flora system modules. %% We might add a switch that would enable this optionally. %% Not clear if this is useful. assert((show_this_hide(X,Y) :- \+flora_switch(low_level_trace), functor(PX,X,Y), flora_decode_predicate(PX,_,WS,_,_,_), flora_module_name(WS,systemmodule,_) )), %% Rules for prefixes of predicates that need %% to be handled by the debugger assert((hide_this_hide(X,Y) :- \+flora_switch(low_level_trace), (flora_hide_this_hide(pref(X1/Y)), atom(X),atom(X1), str_sub(X1,X,0), ! ; flora_hide_this_hide(match(X1/Y)), atom(X),atom(X1), str_sub(X1,X), ! ) )), assert((hide_this_show(X,Y) :- \+flora_switch(low_level_trace), ( flora_hide_this_show(pref(X1/Y)), atom(X),atom(X1), str_sub(X1,X,0), ! ; flora_hide_this_show(match(X1/Y)), atom(X),atom(X1), str_sub(X1,X), ! ) )), assert((show_this_hide(X,Y) :- \+flora_switch(low_level_trace), ( flora_show_this_hide(pref(X1/Y)), atom(X),atom(X1), str_sub(X1,X,0), ! ; flora_show_this_hide(match(X1/Y)), atom(X),atom(X1), str_sub(X1,X), ! ) )), assert((trace_this_noprint(X,Y) :- \+flora_switch(low_level_trace), ( flora_trace_this_noprint(pref(X1/Y)), atom(X),atom(X1), str_sub(X1,X,0), ! ; flora_trace_this_noprint(match(X1/Y)), atom(X),atom(X1), str_sub(X1,X), ! ) )), assert((trace_this_print(X,Y) :- \+flora_switch(low_level_trace), ( flora_trace_this_print(pref(X1/Y)), atom(X),atom(X1), str_sub(X1,X,0), ! ; flora_trace_this_print(match(X1/Y)), atom(X),atom(X1), str_sub(X1,X), ! ) )). ?- findall(X,flLoadedModule(X),L), flora_load_statdata, flora_load_dyndata_for_user_modules(L). ?- flora_build_bridge_to_xsb_debugger. FLORA_SYMBOL('debugger_loaded').