mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-11 20:03:28 +00:00
Estimated hours taken: 3 Branches: main Clean up in unused module imports in the Mercury system detected by --warn-unused-imports. analysis/*.m: browser/*.m: deep_profiler/*.m: compiler/*.m: library/*.m: mdbcomp/*.m: profiler/*.m: slice/*.m: Remove unused module imports. Fix some minor departures from our coding standards. analysis/Mercury.options: browser/Mercury.options: deep_profiler/Mercury.options: compiler/Mercury.options: library/Mercury.options: mdbcomp/Mercury.options: profiler/Mercury.options: slice/Mercury.options: Set --no-warn-unused-imports for those modules that are used as packages or otherwise break --warn-unused-imports, e.g. because they contain predicates with both foreign and Mercury clauses and some of the imports only depend on the latter.
685 lines
24 KiB
Mathematica
685 lines
24 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 1998-2001, 2003, 2005-2006 The University of Melbourne.
|
|
% This file may only be copied under the terms of the GNU Library General
|
|
% Public License - see the file COPYING.LIB in the Mercury distribution.
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% 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.prim_data.
|
|
:- import_module mdbcomp.program_representation.
|
|
|
|
:- 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)
|
|
% 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
|
|
---> hello
|
|
% sending hello
|
|
% are you there?
|
|
|
|
; start
|
|
% start the synchronous communication with the debugger
|
|
|
|
; forward_move_match_found
|
|
; forward_move_match_not_found
|
|
% responses to forward_move
|
|
|
|
% responses to current
|
|
; 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
|
|
)
|
|
|
|
; 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
|
|
; current_vars(list(univ), list(string))
|
|
|
|
% responses to current_nth_var
|
|
; current_nth_var(univ)
|
|
|
|
% responses to current_live_var_names
|
|
; current_live_var_names(list(string), list(string))
|
|
|
|
% response sent when the last event is reached
|
|
; last_event
|
|
|
|
% responses to a successful browse request session
|
|
; browser_end
|
|
|
|
% responses to a successful mmc_option request
|
|
; mmc_option_ok
|
|
|
|
% responses to requests that proceeded successfully
|
|
; ok
|
|
|
|
% responses to requests that went wrong
|
|
; error(string)
|
|
|
|
% responses to stack
|
|
% The protocol between the debugger and the debuggee is described is
|
|
% trace/mercury_trace_external.c.
|
|
; level(int) % stack level
|
|
; proc(string, string, string, int, int) % compiler generated proc
|
|
; proc(string, string, int, int) % user generated proc
|
|
; def_module(string)
|
|
; detail(int, int, int)
|
|
; (pred)
|
|
; (func)
|
|
; det(string)
|
|
; end_stack
|
|
|
|
% responses to stack_regs
|
|
; stack_regs(int, int, int)
|
|
|
|
% responses to link_collect
|
|
; link_collect_succeeded
|
|
; link_collect_failed
|
|
|
|
% responses to collect
|
|
; collect_linked
|
|
; collect_not_linked
|
|
|
|
% responses to current_grade
|
|
; grade(string)
|
|
|
|
% responses to collect
|
|
%; 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
|
|
; execution_continuing
|
|
|
|
% sent if the execution is terminated after a collect request
|
|
; execution_terminated
|
|
|
|
% responses to collect_arg_on
|
|
; collect_arg_on_ok
|
|
|
|
% responses to collect_arg_off
|
|
; 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) :-
|
|
CurrentTraceInfo = current_slots_user(EventNumber, CallNumber,
|
|
DepthNumber, Port, PredOrFunc, DeclModuleName, DefModuleName,
|
|
PredName, Arity, ModeNum, Determinism, Path, LineNo),
|
|
io.write(OutputStream, CurrentTraceInfo, !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) :-
|
|
CurrentTraceInfo = current_slots_comp(EventNumber, CallNumber,
|
|
DepthNumber, Port, NameType, ModuleType, DefModuleName,
|
|
PredName, Arity, ModeNum, Determinism, Path, LineNo),
|
|
io.write(OutputStream, CurrentTraceInfo, !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) :-
|
|
CurrentTraceInfo = current_vars(VarList, StringList),
|
|
io.write(OutputStream, CurrentTraceInfo, !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) :-
|
|
CurrentTraceInfo = current_nth_var(Var),
|
|
io.write(OutputStream, CurrentTraceInfo, !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) :-
|
|
CurrentTraceInfo = current_live_var_names(LiveVarNameList,
|
|
LiveVarTypeList),
|
|
io.write(OutputStream, CurrentTraceInfo, !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 :-
|
|
( DebuggerRequest = current_nth_var(Var) ->
|
|
Var = VarNumber
|
|
;
|
|
error("get_var_number: 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.
|
|
(
|
|
DebuggerRequest = forward_move(MatchEventNumber,
|
|
MatchCallNumber, MatchDepthNumber, MatchPort,
|
|
UserPredMatch, MatchDefModuleName, MatchPredName,
|
|
MatchArity, MatchModeNum, MatchDeterminism,
|
|
MatchArgs, MatchPath)
|
|
->
|
|
match(MatchEventNumber, EventNumber),
|
|
match(MatchCallNumber, CallNumber),
|
|
match(MatchDepthNumber, DepthNumber),
|
|
match(MatchPort, Port),
|
|
(
|
|
UserPredMatch = match_user_pred(MatchPredOrFunc,
|
|
MatchDeclModuleName)
|
|
->
|
|
match(MatchPredOrFunc, PredOrFunc),
|
|
match(MatchDeclModuleName, DeclModuleName)
|
|
;
|
|
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)
|
|
;
|
|
error("found_match: 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.
|
|
(
|
|
DebuggerRequest = forward_move(MatchEventNumber,
|
|
MatchCallNumber, MatchDepthNumber, MatchPort,
|
|
CompilerGeneratedPredMatch,
|
|
MatchDefModuleName, MatchPredName, MatchArity,
|
|
MatchModeNum, MatchDeterminism, MatchArgs, MatchPath)
|
|
->
|
|
match(MatchEventNumber, EventNumber),
|
|
match(MatchCallNumber, CallNumber),
|
|
match(MatchDepthNumber, DepthNumber),
|
|
match(MatchPort, Port),
|
|
(
|
|
CompilerGeneratedPredMatch =
|
|
match_compiler_generated_pred(MatchNameType,
|
|
MatchModuleType)
|
|
->
|
|
match(MatchNameType, NameType),
|
|
match(MatchModuleType, ModuleType)
|
|
;
|
|
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)
|
|
;
|
|
error("found_match: 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) :-
|
|
( DebuggerRequest = query(List) ->
|
|
ModulesList = List
|
|
; DebuggerRequest = cc_query(List) ->
|
|
ModulesList = List
|
|
; DebuggerRequest = io_query(List) ->
|
|
ModulesList = List
|
|
;
|
|
error("get_list_modules_to_import: not a query request")
|
|
),
|
|
length(ModulesList, ListLength).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred get_mmc_options(debugger_request::in, options::out) is det.
|
|
:- pragma foreign_export("C", get_mmc_options(in, out),
|
|
"ML_DI_get_mmc_options").
|
|
|
|
get_mmc_options(DebuggerRequest, Options) :-
|
|
( DebuggerRequest = mmc_options(OptionsPrim) ->
|
|
Options = OptionsPrim
|
|
;
|
|
error("get_mmc_options: 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) :-
|
|
( DebuggerRequest = link_collect(ObjectFileNamePrime) ->
|
|
ObjectFileName = ObjectFileNamePrime
|
|
;
|
|
error("get_object_file_name: 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) :-
|
|
( DebuggerRequest = browse(OptionsPrime) ->
|
|
Options = OptionsPrime
|
|
;
|
|
error("get_variable_name: 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).
|
|
|
|
%-----------------------------------------------------------------------------%
|