mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 18:03:36 +00:00
browser/browse.m:
browser/browser_info.m:
browser/collect_lib.m:
browser/declarative_debugger.m:
browser/declarative_oracle.m:
browser/declarative_user.m:
browser/diff.m:
browser/help.m:
browser/interactive_query.m:
browser/parse.m:
browser/util.m:
Replace implicit streams with explicit streams.
Shorten lines longer than 79 chars.
In some places, simplify some code, often using constructs such as
string.format that either did not exist or were too expensive to use
when the original code was written.
In some places, change predicate names that were not meaningful
without module qualification by *including* the module qualification
in the name (e.g. init -> browser_info_init).
In some places, add XXXs.
In browser_info.m, make the output stream *part* of the debugger type,
because without this, having the debugger type belong to the stream
typeclass does NOT make sense. (The typeclass instance for debugger
used to always write to the current output stream, which this diff
is replacing with the use of explicitly specified streams.)
In browse.m, consistently put stream arguments before other arguments.
In browse.m, when exporting Mercury predicates to C, export them
under names with the standard ML_BROWSE_ prefix, NOT under the name
of a *different* predicate with that prefix.
In diff.m, eliminate an unnecessary difference between what we print
when the difference between two terms is at the root, vs what we print
when the difference between two terms is lower down.
In interactive_query.m, when trying to write a program out to a file,
do NOT write the program to the current output stream if we cannot open
the file, since that would accomplish nothing useful.
Also in interactive_query.m, cleanup .dylib instead of .so on MacOS.
In util.m, delete some unused predicates.
In collect_lib.m, document why some code is not worth updating.
In declarative_oracle.m, rename predicates with previously-ambiguous
names.
browser/MDBFLAGS.in:
Specify --warn-implicit-stream-calls for all Mercury modules
in the browser directory from now.
trace/mercury_trace_browse.c:
trace/mercury_trace_cmd_browsing.c:
ssdb/ssdb.m:
Conform to the changes in browser/*.m.
tests/debugger/queens.{exp,exp2}:
Expect the extra output from browser/diff.m.
689 lines
25 KiB
Mathematica
689 lines
25 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 1998-2001, 2003, 2005-2006, 2011 The University of Melbourne.
|
|
% Copyright (C) 2015-2018 The Mercury team.
|
|
% This file is distributed under the terms specified in COPYING.LIB.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% File: debugger_interface.m.
|
|
% Authors: fjh, jahier.
|
|
%
|
|
% Purpose:
|
|
% This module provide support routines needed by
|
|
% runtime/mercury_trace_external.c for interfacing to an external
|
|
% (in a different process) debugger, in particular an Opium-style debugger.
|
|
%
|
|
% This module corresponds to what is called the "Query Handler" in Opium.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module mdb.debugger_interface.
|
|
:- interface.
|
|
|
|
% This module exports the following C functions:
|
|
% ML_DI_output_current_slots_user
|
|
% ML_DI_output_current_slots_comp
|
|
% ML_DI_output_current_vars
|
|
% ML_DI_output_current_nth_var
|
|
% ML_DI_output_current_live_var_names
|
|
% ML_DI_found_match_user
|
|
% ML_DI_found_match_comp
|
|
% ML_DI_read_request_from_socket
|
|
% These are used by trace/mercury_trace_external.c.
|
|
|
|
:- pred dummy_pred_to_avoid_warning_about_nothing_exported is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module mdb.interactive_query.
|
|
:- import_module mdb.util.
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.goal_path.
|
|
:- import_module mdbcomp.prim_data.
|
|
|
|
:- import_module io.
|
|
:- import_module list.
|
|
:- import_module require.
|
|
:- import_module univ.
|
|
|
|
dummy_pred_to_avoid_warning_about_nothing_exported.
|
|
|
|
% The stuff defined below is also defined in modules prog_data, hlds_data.
|
|
|
|
:- type arity == int.
|
|
|
|
:- type determinism == int.
|
|
% encoded as specified in ../runtime/mercury_stack_layout.h
|
|
% and ../compiler/stack_layout.m.
|
|
|
|
% Depending whether the Opium side is requesting for a user defined procedure
|
|
% or a compiler generated one, the event has not exactly the same structure.
|
|
% The differences between the two types of event are gathered in a forward_move
|
|
% slot of that type.
|
|
|
|
:- type pred_match
|
|
---> match_user_pred(
|
|
% match user-defined preds only
|
|
match(pred_or_func),
|
|
match(string) % declaration module name
|
|
)
|
|
|
|
; match_compiler_generated_pred(
|
|
% match compiler-generated preds only
|
|
match(string), % type name
|
|
match(string) % type module name
|
|
)
|
|
|
|
; match_any_pred.
|
|
% match either user-defined or compiler-generated preds
|
|
|
|
% This is known as "debugger_query" in the Opium documentation.
|
|
% The debugger_request type is used for request sent from the debugger process
|
|
% to the Mercury program being debugged. This type would need to be extended
|
|
% to handle spypoints, etc.
|
|
|
|
:- type debugger_request
|
|
---> hello_reply % yes, I'm here
|
|
|
|
; forward_move(
|
|
% A `forward_move' request instructs the debuggee
|
|
% to step forward until we reach a trace event
|
|
% which matches the specified attributes.
|
|
match(event_number),
|
|
match(call_number),
|
|
match(depth_number),
|
|
match(trace_port),
|
|
pred_match,
|
|
match(string), % definition module name
|
|
match(string), % pred name
|
|
match(arity),
|
|
match(int), % mode number
|
|
match(determinism),
|
|
match(list(univ)), % the arguments
|
|
% XXX we could provide better ways of
|
|
% matching on arguments
|
|
match(goal_path_string)
|
|
)
|
|
|
|
; current_slots
|
|
% A `current_slots' request instructs the debuggee to
|
|
% retrieve the attributes of the current trace
|
|
% event (except for argument slot) and report them
|
|
% to the debugger via the socket.
|
|
|
|
; current_vars
|
|
% A `current_vars' request instructs the debuggee to
|
|
% retrieve the list of values and the list of internal
|
|
% names of live variables of the current event and
|
|
% report it to the debugger via the socket.
|
|
% XXX should provide a way of getting
|
|
% just part of the arguments
|
|
% (to reduce unnecessary socket traffic)
|
|
|
|
; current_live_var_names
|
|
% A `current_live_var_names' request instructs the debuggee to
|
|
% retrieve the list of internal names of the currently
|
|
% live variables and a list of their corresponding types.
|
|
|
|
; current_nth_var(int)
|
|
% A 'current_nth_var' request instructs the debuggee to
|
|
% retrieve the specified live variable.
|
|
|
|
; abort_prog
|
|
% just abort the program
|
|
|
|
; no_trace
|
|
% stop tracing, and run the program to completion
|
|
|
|
; retry
|
|
% Restarts execution at the call port of the call
|
|
% corresponding to the current event
|
|
|
|
; stack
|
|
% Print the ancestors stack.
|
|
; nondet_stack
|
|
% Prints the contents of the fixed slots of the
|
|
% frames on the nondet stack.
|
|
|
|
; stack_regs
|
|
% Print the contents of the virtual machine registers
|
|
% that point to the det and nondet stacks.
|
|
|
|
; error(string)
|
|
% Something went wrong when trying to get the next request.
|
|
|
|
; query(imports)
|
|
% To type interactive queries.
|
|
|
|
; cc_query(imports)
|
|
% To type cc interactive queries.
|
|
|
|
; io_query(imports)
|
|
% To type interactive queries that perform io.
|
|
|
|
; mmc_options(options_string)
|
|
% Options to compile queries with.
|
|
|
|
; browse(string)
|
|
% To call the term browser.
|
|
|
|
; link_collect(string)
|
|
% Dynamically link the collect module with the current execution.
|
|
|
|
; collect
|
|
% Execute the collect command.
|
|
|
|
; current_grade
|
|
% Retrieve the grade the current execution has been compiled with.
|
|
|
|
; collect_arg_on
|
|
% Switch the argument collecting on (for collect request).
|
|
|
|
; collect_arg_off.
|
|
% Switch the argument collecting off (for collect request).
|
|
|
|
:- type event_number == int.
|
|
:- type call_number == int.
|
|
:- type depth_number == int.
|
|
|
|
% `match' is called "get status" in the Opium documentation.
|
|
% This type defines a unary predicate which determines whether
|
|
% or not a particular value will be selected.
|
|
:- type match(T)
|
|
---> nop % nop: value = -
|
|
; exact(T) % exact(X): value = X
|
|
; neg(T) % neg(X): value \= X
|
|
; list(list(T)) % list(L): list.member(value, L)
|
|
; interval(T,T). % interval(Low, High): Low =< X, X =< High
|
|
|
|
% The debugger_response type is used for response sent
|
|
% to the debugger process from the Mercury program being debugged.
|
|
:- type debugger_response
|
|
---> response_hello
|
|
% sending hello
|
|
% are you there?
|
|
|
|
; response_start
|
|
% start the synchronous communication with the debugger
|
|
|
|
% responses to forward_move
|
|
; response_forward_move_match_found
|
|
; response_forward_move_match_not_found
|
|
|
|
% responses to current
|
|
; response_current_slots_user(
|
|
% responses to current_slots for user event
|
|
event_number,
|
|
call_number,
|
|
depth_number,
|
|
trace_port,
|
|
pred_or_func,
|
|
string, % declaration module name
|
|
string, % definition module name
|
|
string, % pred name
|
|
arity,
|
|
int, % mode number
|
|
determinism,
|
|
goal_path_string,
|
|
line_number
|
|
)
|
|
|
|
; response_current_slots_comp(
|
|
% responses to current_slots for compiler generated event
|
|
event_number,
|
|
call_number,
|
|
depth_number,
|
|
trace_port,
|
|
string, % name type
|
|
string, % module type
|
|
string, % definition module
|
|
string, % pred name
|
|
arity,
|
|
int, % mode number
|
|
determinism,
|
|
goal_path_string,
|
|
line_number
|
|
)
|
|
|
|
% responses to current_vars
|
|
; response_current_vars(list(univ), list(string))
|
|
|
|
% responses to current_nth_var
|
|
; response_current_nth_var(univ)
|
|
|
|
% responses to current_live_var_names
|
|
; response_current_live_var_names(list(string), list(string))
|
|
|
|
% response sent when the last event is reached
|
|
; response_last_event
|
|
|
|
% responses to a successful browse request session
|
|
; response_browser_end
|
|
|
|
% responses to a successful mmc_option request
|
|
; response_mmc_option_ok
|
|
|
|
% responses to requests that proceeded successfully
|
|
; response_ok
|
|
|
|
% responses to requests that went wrong
|
|
; response_error(string)
|
|
|
|
% responses to stack
|
|
% The protocol between the debugger and the debuggee is described is
|
|
% trace/mercury_trace_external.c.
|
|
; response_level(int)
|
|
% stack level
|
|
; response_proc(string, string, string, int, int)
|
|
% compiler generated proc
|
|
; response_proc(string, string, int, int)
|
|
% user generated proc
|
|
; response_def_module(string)
|
|
; response_detail(int, int, int)
|
|
; response_pred
|
|
; response_func
|
|
; response_det(string)
|
|
; response_end_stack
|
|
|
|
% responses to stack_regs
|
|
; response_stack_regs(int, int, int)
|
|
|
|
% responses to link_collect
|
|
; response_link_collect_succeeded
|
|
; response_link_collect_failed
|
|
|
|
% responses to collect
|
|
; response_collect_linked
|
|
; response_collect_not_linked
|
|
|
|
% responses to current_grade
|
|
; response_grade(string)
|
|
|
|
% responses to collect
|
|
%; response_collected(collected_type)
|
|
% This is commented out because collected_type is unknown at compile time,
|
|
% since it is defined by users in the dynamically linked collect module.
|
|
|
|
% sent if the execution is not terminated after a collect request
|
|
; response_execution_continuing
|
|
|
|
% sent if the execution is terminated after a collect request
|
|
; response_execution_terminated
|
|
|
|
% responses to collect_arg_on
|
|
; response_collect_arg_on_ok
|
|
|
|
% responses to collect_arg_off
|
|
; response_collect_arg_off_ok.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
% send to the debugger (e.g. Opium) the wanted features.
|
|
|
|
% output_current_slots_user "ML_DI_output_current_slots_user":
|
|
% send to the debugger (e.g. Opium) the attributes of the current event
|
|
% except the list of arguments.
|
|
|
|
:- pragma foreign_export("C",
|
|
output_current_slots_user(in, in, in, in, in, in, in, in, in, in, in, in,
|
|
in, in, di, uo),
|
|
"ML_DI_output_current_slots_user").
|
|
|
|
:- pred output_current_slots_user(event_number::in, call_number::in,
|
|
depth_number::in, trace_port::in, pred_or_func::in,
|
|
/* declarated module name */ string::in,
|
|
/* definition module name */ string::in, /* pred name */ string::in,
|
|
arity::in, /* mode num */ int::in, determinism::in, goal_path_string::in,
|
|
line_number::in, io.output_stream::in, io::di, io::uo) is det.
|
|
|
|
output_current_slots_user(EventNumber, CallNumber, DepthNumber, Port,
|
|
PredOrFunc, DeclModuleName, DefModuleName, PredName, Arity, ModeNum,
|
|
Determinism, Path, LineNo, OutputStream, !IO) :-
|
|
Response = response_current_slots_user(EventNumber, CallNumber,
|
|
DepthNumber, Port, PredOrFunc, DeclModuleName, DefModuleName,
|
|
PredName, Arity, ModeNum, Determinism, Path, LineNo),
|
|
io.write(OutputStream, Response, !IO),
|
|
io.print(OutputStream, ".\n", !IO),
|
|
io.flush_output(OutputStream, !IO).
|
|
|
|
% output_current_slots_comp "ML_DI_output_current_slots_comp":
|
|
% send to the debugger (e.g. Opium) the attributes of the current event
|
|
% except the list of arguments.
|
|
|
|
:- pragma foreign_export("C",
|
|
output_current_slots_comp(in, in, in, in, in, in, in, in, in, in, in, in,
|
|
in, in, di, uo),
|
|
"ML_DI_output_current_slots_comp").
|
|
|
|
:- pred output_current_slots_comp(event_number::in, call_number::in,
|
|
depth_number::in, trace_port::in, /* name type */ string::in,
|
|
/* module type */ string::in, /* definition module */ string::in,
|
|
/* pred name */ string::in, arity::in, /* mode num */ int::in,
|
|
determinism::in, goal_path_string::in, line_number::in,
|
|
io.output_stream::in, io::di, io::uo) is det.
|
|
|
|
output_current_slots_comp(EventNumber, CallNumber, DepthNumber, Port,
|
|
NameType, ModuleType, DefModuleName, PredName, Arity,
|
|
ModeNum, Determinism, Path, LineNo, OutputStream, !IO) :-
|
|
Response = response_current_slots_comp(EventNumber, CallNumber,
|
|
DepthNumber, Port, NameType, ModuleType, DefModuleName,
|
|
PredName, Arity, ModeNum, Determinism, Path, LineNo),
|
|
io.write(OutputStream, Response, !IO),
|
|
io.print(OutputStream, ".\n", !IO),
|
|
io.flush_output(OutputStream, !IO).
|
|
|
|
% output_current_vars "ML_DI_output_current_vars":
|
|
% send to the debugger the list of the live variables of the current
|
|
% event.
|
|
|
|
:- pragma foreign_export("C", output_current_vars(in, in, in, di, uo),
|
|
"ML_DI_output_current_vars").
|
|
|
|
:- pred output_current_vars(list(univ)::in, list(string)::in,
|
|
io.output_stream::in, io::di, io::uo) is det.
|
|
|
|
output_current_vars(VarList, StringList, OutputStream, !IO) :-
|
|
Response = response_current_vars(VarList, StringList),
|
|
io.write(OutputStream, Response, !IO),
|
|
io.print(OutputStream, ".\n", !IO),
|
|
io.flush_output(OutputStream, !IO).
|
|
|
|
% output_current_nth_var "ML_DI_output_current_nth_var":
|
|
% send to the debugger the requested live variable of the current event.
|
|
|
|
:- pragma foreign_export("C", output_current_nth_var(in, in, di, uo),
|
|
"ML_DI_output_current_nth_var").
|
|
|
|
:- pred output_current_nth_var(univ::in, io.output_stream::in, io::di, io::uo)
|
|
is det.
|
|
|
|
output_current_nth_var(Var, OutputStream, !IO) :-
|
|
Response = response_current_nth_var(Var),
|
|
io.write(OutputStream, Response, !IO),
|
|
io.print(OutputStream, ".\n", !IO),
|
|
io.flush_output(OutputStream, !IO).
|
|
|
|
:- pragma foreign_export("C",
|
|
output_current_live_var_names(in, in, in, di, uo),
|
|
"ML_DI_output_current_live_var_names").
|
|
|
|
:- pred output_current_live_var_names(list(string)::in, list(string)::in,
|
|
io.output_stream::in, io::di, io::uo) is det.
|
|
|
|
output_current_live_var_names(LiveVarNameList, LiveVarTypeList, OutputStream,
|
|
!IO) :-
|
|
Response = response_current_live_var_names(LiveVarNameList,
|
|
LiveVarTypeList),
|
|
io.write(OutputStream, Response, !IO),
|
|
io.print(OutputStream, ".\n", !IO),
|
|
io.flush_output(OutputStream, !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pragma foreign_export("C", get_var_number(in) = out,
|
|
"ML_DI_get_var_number").
|
|
|
|
% This function is intended to retrieve the integer in
|
|
% "current_nth_var(int)" requests.
|
|
%
|
|
:- func get_var_number(debugger_request) = int.
|
|
|
|
get_var_number(DebuggerRequest) = VarNumber :-
|
|
( if DebuggerRequest = current_nth_var(Var) then
|
|
Var = VarNumber
|
|
else
|
|
unexpected($pred, "not a current_nth_var request")
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pragma foreign_export("C",
|
|
found_match_user(in, in, in, in, in, in, in, in, in, in, in, in, in, in),
|
|
"ML_DI_found_match_user").
|
|
|
|
:- pred found_match_user(event_number::in, call_number::in, depth_number::in,
|
|
trace_port::in, pred_or_func::in, /* declarated module name */ string::in,
|
|
/* defined module name */ string::in, /* pred name */ string::in,
|
|
arity::in, /* mode num */ int::in, determinism::in,
|
|
/* the arguments */ list(univ)::in, goal_path_string::in,
|
|
debugger_request::in) is semidet.
|
|
|
|
found_match_user(EventNumber, CallNumber, DepthNumber, Port, PredOrFunc,
|
|
DeclModuleName, DefModuleName, PredName, Arity, ModeNum,
|
|
Determinism, Args, Path, DebuggerRequest) :-
|
|
% XXX We could provide better ways of matching on arguments.
|
|
( if
|
|
DebuggerRequest = forward_move(MatchEventNumber,
|
|
MatchCallNumber, MatchDepthNumber, MatchPort,
|
|
UserPredMatch, MatchDefModuleName, MatchPredName,
|
|
MatchArity, MatchModeNum, MatchDeterminism,
|
|
MatchArgs, MatchPath)
|
|
then
|
|
match(MatchEventNumber, EventNumber),
|
|
match(MatchCallNumber, CallNumber),
|
|
match(MatchDepthNumber, DepthNumber),
|
|
match(MatchPort, Port),
|
|
( if
|
|
UserPredMatch = match_user_pred(MatchPredOrFunc,
|
|
MatchDeclModuleName)
|
|
then
|
|
match(MatchPredOrFunc, PredOrFunc),
|
|
match(MatchDeclModuleName, DeclModuleName)
|
|
else
|
|
UserPredMatch = match_any_pred
|
|
),
|
|
match(MatchDefModuleName, DefModuleName),
|
|
match(MatchPredName, PredName),
|
|
match(MatchArity, Arity),
|
|
match(MatchModeNum, ModeNum),
|
|
match(MatchDeterminism, Determinism),
|
|
match(MatchArgs, Args),
|
|
match(MatchPath, Path)
|
|
else
|
|
unexpected($pred, "forward_move expected")
|
|
).
|
|
|
|
% match(MatchPattern, Value) is true iff Value matches the specified
|
|
% pattern.
|
|
%
|
|
:- pred match(match(T)::in, T::in) is semidet.
|
|
|
|
match(nop, _).
|
|
match(exact(X), X).
|
|
match(neg(X), Y) :- X \= Y.
|
|
match(list(L), X) :- list.member(X, L).
|
|
match(interval(Low, High), X) :-
|
|
% X >= Low, X =< High
|
|
compare(LE, X, High),
|
|
( LE = (<) ; LE = (=) ),
|
|
compare(GE, X, Low),
|
|
( GE = (>) ; GE = (=) ).
|
|
|
|
:- pragma foreign_export("C",
|
|
found_match_comp(in, in, in, in, in, in, in, in, in, in, in, in, in, in),
|
|
"ML_DI_found_match_comp").
|
|
|
|
:- pred found_match_comp(event_number::in, call_number::in, depth_number::in,
|
|
trace_port::in, /* name type */ string::in, /* module type */ string::in,
|
|
/* definition module name */ string::in, /* pred name */ string::in,
|
|
arity::in, /* mode num */ int::in, determinism::in,
|
|
/* the arguments */ list(univ)::in, goal_path_string::in,
|
|
debugger_request::in) is semidet.
|
|
|
|
found_match_comp(EventNumber, CallNumber, DepthNumber, Port, NameType,
|
|
ModuleType, DefModuleName, PredName, Arity, ModeNum,
|
|
Determinism, Args, Path, DebuggerRequest) :-
|
|
% XXX We could provide better ways of matching on arguments.
|
|
( if
|
|
DebuggerRequest = forward_move(MatchEventNumber,
|
|
MatchCallNumber, MatchDepthNumber, MatchPort,
|
|
CompilerGeneratedPredMatch,
|
|
MatchDefModuleName, MatchPredName, MatchArity,
|
|
MatchModeNum, MatchDeterminism, MatchArgs, MatchPath)
|
|
then
|
|
match(MatchEventNumber, EventNumber),
|
|
match(MatchCallNumber, CallNumber),
|
|
match(MatchDepthNumber, DepthNumber),
|
|
match(MatchPort, Port),
|
|
( if
|
|
CompilerGeneratedPredMatch =
|
|
match_compiler_generated_pred(MatchNameType,
|
|
MatchModuleType)
|
|
then
|
|
match(MatchNameType, NameType),
|
|
match(MatchModuleType, ModuleType)
|
|
else
|
|
CompilerGeneratedPredMatch = match_any_pred
|
|
),
|
|
match(MatchDefModuleName, DefModuleName),
|
|
match(MatchPredName, PredName),
|
|
match(MatchArity, Arity),
|
|
match(MatchModeNum, ModeNum),
|
|
match(MatchDeterminism, Determinism),
|
|
match(MatchArgs, Args),
|
|
match(MatchPath, Path)
|
|
else
|
|
unexpected($pred, "forward_move expected")
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred read_request_from_socket(io.input_stream::in, debugger_request::out,
|
|
int::out, io::di, io::uo) is det.
|
|
|
|
:- pragma foreign_export("C",
|
|
read_request_from_socket(in, out, out, di, uo),
|
|
"ML_DI_read_request_from_socket").
|
|
|
|
read_request_from_socket(SocketStream, Request, RequestType, !IO) :-
|
|
io.read(SocketStream, MaybeRequest, !IO),
|
|
(
|
|
MaybeRequest = ok(Request0),
|
|
Request = Request0
|
|
;
|
|
MaybeRequest = error(ErrorMsg, _LineNum),
|
|
Request = error(ErrorMsg)
|
|
;
|
|
MaybeRequest = eof,
|
|
Request = error("end of file")
|
|
),
|
|
classify_request(Request, RequestType).
|
|
|
|
% debugging stuff.
|
|
% io.stderr_stream(StdErr, !IO),
|
|
% io.print(StdErr, "debugger_interface: Receive the Request:+", !IO),
|
|
% io.print(StdErr, Request, !IO),
|
|
% io.print(StdErr, "+ from opium\ndebugger_interface: RequestType = ",
|
|
% !IO),
|
|
% io.print(StdErr, RequestType, !IO),
|
|
% io.print(StdErr, ".\n", !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred get_list_modules_to_import(debugger_request::in, int::out,
|
|
imports::out) is det.
|
|
|
|
:- pragma foreign_export("C", get_list_modules_to_import(in, out, out),
|
|
"ML_DI_get_list_modules_to_import").
|
|
|
|
get_list_modules_to_import(DebuggerRequest, ListLength, ModulesList) :-
|
|
( if DebuggerRequest = query(List) then
|
|
ModulesList = List
|
|
else if DebuggerRequest = cc_query(List) then
|
|
ModulesList = List
|
|
else if DebuggerRequest = io_query(List) then
|
|
ModulesList = List
|
|
else
|
|
unexpected($pred, "not a query request")
|
|
),
|
|
length(ModulesList, ListLength).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred get_mmc_options(debugger_request::in, options_string::out) is det.
|
|
:- pragma foreign_export("C", get_mmc_options(in, out),
|
|
"ML_DI_get_mmc_options").
|
|
|
|
get_mmc_options(DebuggerRequest, Options) :-
|
|
( if DebuggerRequest = mmc_options(OptionsPrim) then
|
|
Options = OptionsPrim
|
|
else
|
|
unexpected($pred, "not a mmc_options request")
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% This predicate allows mercury_trace_external.c to retrieve the name
|
|
% of the object file to link the current execution with from a
|
|
% `link_collect(ObjectFileName)' request.
|
|
%
|
|
:- pred get_object_file_name(debugger_request::in, string::out) is det.
|
|
:- pragma foreign_export("C", get_object_file_name(in, out),
|
|
"ML_DI_get_object_file_name").
|
|
|
|
get_object_file_name(DebuggerRequest, ObjectFileName) :-
|
|
( if DebuggerRequest = link_collect(ObjectFileNamePrime) then
|
|
ObjectFileName = ObjectFileNamePrime
|
|
else
|
|
unexpected($pred, "not a link_collect request")
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred init_mercury_string(string::out) is det.
|
|
:- pragma foreign_export("C", init_mercury_string(out),
|
|
"ML_DI_init_mercury_string").
|
|
|
|
init_mercury_string("").
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% This predicate allows mercury_trace_external.c to retrieve the name
|
|
% of the variable to browse from a `browse(var_name)' request.
|
|
%
|
|
:- pred get_variable_name(debugger_request::in, string::out) is det.
|
|
:- pragma foreign_export("C", get_variable_name(in, out),
|
|
"ML_DI_get_variable_name").
|
|
|
|
get_variable_name(DebuggerRequest, Options) :-
|
|
( if DebuggerRequest = browse(OptionsPrime) then
|
|
Options = OptionsPrime
|
|
else
|
|
unexpected($pred, "not a browse request")
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred classify_request(debugger_request::in, int::out) is det.
|
|
|
|
% The numbers here should match the definition of
|
|
% MR_debugger_request_type in runtime/mercury_trace_external.c.
|
|
classify_request(hello_reply, 0).
|
|
classify_request(forward_move(_, _, _, _, _, _, _, _, _, _, _, _), 1).
|
|
classify_request(current_vars, 2).
|
|
classify_request(current_slots, 3).
|
|
classify_request(no_trace, 4).
|
|
classify_request(abort_prog, 5).
|
|
classify_request(error(_), 6).
|
|
classify_request(current_live_var_names, 7).
|
|
classify_request(current_nth_var(_), 8).
|
|
classify_request(retry, 9).
|
|
classify_request(stack, 10).
|
|
classify_request(nondet_stack, 11).
|
|
classify_request(stack_regs, 12).
|
|
classify_request(query(_),13).
|
|
classify_request(cc_query(_),14).
|
|
classify_request(io_query(_),15).
|
|
classify_request(mmc_options(_),16).
|
|
classify_request(browse(_),17).
|
|
classify_request(link_collect(_),18).
|
|
classify_request(collect,19).
|
|
classify_request(current_grade,20).
|
|
classify_request(collect_arg_on,21).
|
|
classify_request(collect_arg_off,22).
|
|
|
|
%---------------------------------------------------------------------------%
|