[m-rev.] already reviewed: add debugger state to ssdb
Olivier Annet
oan at missioncriticalit.com
Fri Oct 5 14:18:00 AEST 2007
Hi,
Peter Ross has reviewed this code with me already.
===================================================================
Estimated hours taken: 8
Branches: main
Define a debugger state which records all the information needed
by the debugger.
Currently we record in this state the event number, the call sequence
number, the call depth and a shadow stack of all the calls.
compiler/Mmakefile:
Pass the ssdb init file to c2init, otherwise the ssdb
initialization routines will not be called.
ssdb/ssdb.m:
Print out the event number, call sequence number and call depth at
each event. Add code to manage the debuger state at each event.
Index: compiler/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/Mmakefile,v
retrieving revision 1.94
diff -u -r1.94 Mmakefile
--- compiler/Mmakefile 3 Oct 2007 23:48:15 -0000 1.94
+++ compiler/Mmakefile 5 Oct 2007 04:10:30 -0000
@@ -13,7 +13,8 @@
# Override the settings in ../Mmake.workspace so that in debugging grades we
# do not include mer_mdbcomp.init twice in the list of files passed to mkinit.
#
-C2INITFLAGS = --trace-init-file $(BROWSER_DIR)/$(BROWSER_LIB_NAME).init
+C2INITFLAGS = --trace-init-file $(BROWSER_DIR)/$(BROWSER_LIB_NAME).init \
+ --trace-init-file $(SSDB_DIR)/$(SSDB_LIB_NAME).init
-include Mmake.compiler.params
Index: ssdb/ssdb.m
===================================================================
RCS file: /home/mercury1/repository/mercury/ssdb/ssdb.m,v
retrieving revision 1.2
diff -u -r1.2 ssdb.m
--- ssdb/ssdb.m 4 Oct 2007 01:03:47 -0000 1.2
+++ ssdb/ssdb.m 5 Oct 2007 04:10:30 -0000
@@ -44,28 +44,240 @@
:- implementation.
-:- import_module io.
-
:- import_module bool.
+:- import_module io.
:- import_module int.
:- import_module list.
+:- import_module require.
:- import_module string.
%----------------------------------------------------------------------------%
+:- type debugger_state
+ ---> state(
+ event_number :: int, % Current event number
+ csn :: int, % Call Sequence Number
+ call_depth :: int, % Depth of the function
+ stack :: stack % The shadow stack
+ ).
+
+
+:- type stack == list(stack_elem).
+
+:- type stack_elem
+ ---> elem(
+ proc_id :: ssdb_proc_id,
+ initial_state :: debugger_state
+ % The debugger state at the call port.
+ ).
+
+
+
+%----------------------------------------------------------------------------%
+
+ %
+ % Initialize the debugger state
+ % XXX Will be extended
+ %
+:- func init_debugger_state = debugger_state.
+
+init_debugger_state = DbgState :-
+ EventNum = 0,
+ CSN = 0,
+ Depth = 0,
+ Stack = [],
+ DbgState = state(EventNum, CSN, Depth, Stack).
+
+:- mutable(debugger_state, debugger_state, init_debugger_state, ground,
+ [untrailed, attach_to_io_state]).
+
+%----------------------------------------------------------------------------%
+
+
%
% For the moment we just write the event out.
% Later this will be extended.
%
handle_event(ProcId, Event) :-
- promise_impure (
- trace [io(!IO)] (
- io.write(Event, !IO),
- io.write_string(" ", !IO),
+ impure get_event_num_inc(EventNum),
+ impure update_depth(Event, PrintDepth),
+
+ (
+ Event = ssdb_call,
+ impure get_csn_inc(_),
+
+ semipure get_debugger_state(InitialState),
+ S = elem(ProcId, InitialState),
+ impure push(S)
+ ;
+ Event = ssdb_exit,
+ impure pop(S)
+ ;
+ Event = ssdb_redo,
+ error("ssdb_redo: not yet implemented")
+ ;
+ Event = ssdb_fail,
+ error("ssdb_fail: not yet implemented")
+ ),
+
+ PrintCSN = S ^ initial_state ^ csn,
+
+ some [!IO]
+ (
+ impure invent_io(!:IO),
+ io.write_string(" ", !IO),
+ io.write_int(EventNum, !IO),
+ io.write_string(" ", !IO),
io.write_string(ProcId ^ proc_name, !IO),
- io.nl(!IO)
- )
+ io.write_string(".", !IO),
+ io.write(Event, !IO),
+ io.write_string(" | DEPTH = ", !IO),
+ io.write_int(PrintDepth, !IO),
+ io.write_string(" | CSN = ", !IO),
+ io.write_int(PrintCSN, !IO),
+ io.nl(!IO),
+
+ impure consume_io(!.IO),
+
+ % XXX don not forget get the latest modification (like new breakpoint)
+ true
).
+
+ %
+ % Return the event number after increment
+ %
+:- impure pred get_event_num_inc(int::out) is det.
+
+get_event_num_inc(EventNum) :-
+ semipure get_debugger_state(State0),
+ EventNum0 = State0 ^ event_number,
+ EventNum = EventNum0 + 1,
+ State = State0 ^ event_number := EventNum,
+ impure set_debugger_state(State).
+
+ %
+ % For the given event type, update the depth in the debugger state
+ % and return the depth for the given event.
+ %
+:- impure pred update_depth(ssdb_event_type::in, int::out) is det.
+
+update_depth(Event, PrintDepth) :-
+ semipure get_debugger_state(State0),
+ Depth0 = State0 ^ call_depth,
+ (
+ ( Event = ssdb_call
+ ; Event = ssdb_redo
+ ),
+ Depth = Depth0 + 1,
+ PrintDepth = Depth0
+ ;
+ ( Event = ssdb_exit
+ ; Event = ssdb_fail
+ ),
+ Depth = Depth0 - 1,
+ PrintDepth = Depth
+ ),
+ State = State0 ^ call_depth := Depth,
+ impure set_debugger_state(State).
+
+ %
+ % Return the csn after increment
+ %
+:- impure pred get_csn_inc(int::out) is det.
+
+get_csn_inc(CSN) :-
+ semipure get_debugger_state(State0),
+ CSN0 = State0 ^ csn,
+ CSN = CSN0 + 1,
+ State = State0 ^ csn := CSN,
+ impure set_debugger_state(State).
+
+ %
+ % push the element on to the debugger shadow stack
+ %
+:- impure pred push(stack_elem::in) is det.
+
+push(E) :-
+ semipure get_debugger_state(State0),
+ Stack0 = State0 ^ stack,
+ Stack = [E | Stack0],
+ State = State0 ^ stack := Stack,
+ impure set_debugger_state(State).
+
+ %
+ % pop the debugger shadow stack returning
+ % the element on the top of the stack.
+ %
+:- impure pred pop(stack_elem::out) is det.
+
+pop(E) :-
+ semipure get_debugger_state(State0),
+ Stack0 = State0 ^ stack,
+ (
+ Stack0 = [],
+ error("ssdb.pop: empty stack")
+ ;
+ Stack0 = [E | Stack]
+ ),
+ State = State0 ^ stack := Stack,
+ impure set_debugger_state(State).
+
+ %
+ % Return the current event number
+ %
+:- semipure pred get_event_num(int::out) is det.
+
+get_event_num(EventNum) :-
+ semipure get_debugger_state(State0),
+ EventNum = State0 ^ event_number.
+
+ %
+ % Return the current csn
+ %
+:- semipure pred get_csn(int::out) is det.
+
+get_csn(CSN) :-
+ semipure get_debugger_state(State0),
+ CSN = State0 ^ csn.
+
+%----------------------------------------------------------------------------%
+
+:- impure pred invent_io(io::uo) is det.
+
+:- pragma foreign_proc("C",
+ invent_io(_IO::uo),
+ [will_not_call_mercury, thread_safe], "").
+
+:- pragma foreign_proc("Erlang",
+ invent_io(_IO::uo),
+ [will_not_call_mercury, thread_safe], "void").
+
+:- pragma foreign_proc("C#",
+ invent_io(_IO::uo),
+ [will_not_call_mercury, thread_safe], "").
+
+:- pragma foreign_proc("Java",
+ invent_io(_IO::uo),
+ [will_not_call_mercury, thread_safe], "").
+
+:- impure pred consume_io(io::di) is det.
+
+:- pragma foreign_proc("C",
+ consume_io(_IO::di),
+ [will_not_call_mercury, thread_safe], "").
+
+:- pragma foreign_proc("Erlang",
+ consume_io(_IO::di),
+ [will_not_call_mercury, thread_safe], "void").
+
+:- pragma foreign_proc("C#",
+ consume_io(_IO::di),
+ [will_not_call_mercury, thread_safe], "").
+
+:- pragma foreign_proc("Java",
+ consume_io(_IO::di),
+ [will_not_call_mercury, thread_safe], "").
+
%----------------------------------------------------------------------------%
%----------------------------------------------------------------------------%
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list