[m-rev.] add prompt to ssdb

Olivier Annet oan at missioncriticalit.com
Fri Oct 5 18:45:25 AEST 2007


Hi,


===================================================================


Estimated hours taken: 5
Branches: main

Prompt added. Some commands are available.
 s or "nothing" ---> step
 n              ---> next
 f              ---> finish 
 h		---> help


ssdb/ssdb.m:
	- Rename field names of the debugger_state type to be less ambiguous.
	- Add the stack in the debugger_state to records the different call
	- Add types what_next and next_stop to configure the stop phase of 
	the prompt
	In handle_event
	- Use of the variable NextStop to determine when to do a stop 
	- Call the prompt and recieve the next action to perform
	In prompt
	- Commands to go thru next step and next exit point added
    

? ssdb/.ssdb.m.swo
? ssdb/.ssdb.m.swp
? ssdb/Mercury
? ssdb/SSDB_FLAGS
? ssdb/mer_ssdb.err
? ssdb/mer_ssdb.mh
? ssdb/ssdb.err
? ssdb/ssdb.mh
Index: ssdb/ssdb.m
===================================================================
RCS file: /home/mercury1/repository/mercury/ssdb/ssdb.m,v
retrieving revision 1.3
diff -u -r1.3 ssdb.m
--- ssdb/ssdb.m	5 Oct 2007 04:23:20 -0000	1.3
+++ ssdb/ssdb.m	5 Oct 2007 08:16:05 -0000
@@ -49,28 +49,55 @@
 :- import_module int.
 :- import_module list.
 :- import_module require.
+:- import_module stack.
 :- 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
-            ).
+                % Current event number
+                ssdb_event_number   :: int,                 
+
+                % Call Sequence Number
+                ssdb_csn            :: int,                 
 
+                % Depth of the function
+                ssdb_call_depth     :: int,                 
+
+                % Where the program should stop next time
+                ssdb_next_stop      :: next_stop,           
+
+                % The shadow stack
+                ssdb_stack          :: stack(stack_elem)    
+            ).
 
-:- 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.
+                    % The debugger state at the call port.
             ).
 
+    %
+    % Type filled by the prompt function to configure the next step in the
+    % handle_event function 
+    %
+:- type what_next
+    --->    what_next_step
+    ;       what_next_next
+    ;       what_next_finish(int).
+
+
+    %
+    % Type filled by the handle_event function to determine the next stop of
+    % the prompt function
+    %
+:- type next_stop
+    --->    step
+    ;       next(int)
+    ;       final_port(int).
 
 
 %----------------------------------------------------------------------------%
@@ -85,75 +112,131 @@
     EventNum = 0,
     CSN = 0,
     Depth = 0,
-    Stack = [],
-    DbgState = state(EventNum, CSN, Depth, Stack).
+    NextStop = step,
+    Stack = stack.init,
+    DbgState = state(EventNum, CSN, Depth, NextStop, Stack).
 
 :- mutable(debugger_state, debugger_state, init_debugger_state, ground, 
-                [untrailed, attach_to_io_state]).
+    [untrailed, attach_to_io_state]).
 
 %----------------------------------------------------------------------------%
 
 
     %
-    % For the moment we just write the event out.
-    % Later this will be extended.
+    % Write the event out and call the prompt
+    % XXX Not yet implemented : redo, fail
     %
 handle_event(ProcId, Event) :-
     impure get_event_num_inc(EventNum),
     impure update_depth(Event, PrintDepth),
 
     (
-	Event = ssdb_call,
-	impure get_csn_inc(_),
+        Event = ssdb_call,
+        impure get_csn_inc(_),
 
-	semipure get_debugger_state(InitialState),
-	S = elem(ProcId, InitialState),
-	impure push(S)
+        semipure get_debugger_state(InitialState),
+        E = elem(ProcId, InitialState),
+        stack.push(InitialState ^ ssdb_stack, E, FinalStack),
+        StateEv = InitialState ^ ssdb_stack := FinalStack,
+        impure set_debugger_state(StateEv)
     ;
-	Event = ssdb_exit,
-	impure pop(S)
+        Event = ssdb_exit,
+        semipure get_debugger_state(InitialState),
+        stack.pop_det(InitialState ^ ssdb_stack, E, FinalStack),
+        StateEv = InitialState ^ ssdb_stack := FinalStack,
+        impure set_debugger_state(StateEv)
     ;
-	Event = ssdb_redo,
-	error("ssdb_redo: not yet implemented")
+        Event = ssdb_redo,
+        error("ssdb_redo: not yet implemented")
     ;
-	Event = ssdb_fail,
-	error("ssdb_fail: not yet implemented")
+        Event = ssdb_fail,
+        error("ssdb_fail: not yet implemented")
     ),
+ 
+    semipure get_debugger_state(State0),
+
+    PrintCSN = E ^ initial_state ^ ssdb_csn,
 
-    PrintCSN = S ^ initial_state ^ csn,
+    NextStop0 = State0 ^ ssdb_next_stop,
+    (
+        NextStop0 = step,
+        Stop = yes
+    ;
+        NextStop0 = next(StopCSN),
+        is_same_event(StopCSN, PrintCSN, Stop)
+    ;
+        NextStop0 = final_port(StopCSN),
+        (
+            Event = ssdb_exit,
+            is_same_event(StopCSN, PrintCSN, Stop)
+        ;
+            Event = ssdb_call,
+            Stop = no
+        )
+    ),
     
-    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.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),
+        Stop = yes,
+        some [!IO] 
+        (
+            impure invent_io(!:IO),
+            io.write_string("       ", !IO),
+            io.write_int(EventNum, !IO),
+            io.write_string("\t", !IO),
+            io.write_string(ProcId ^ proc_name, !IO),
+            io.write_string(".", !IO),
+            io.write(Event, !IO),
+            io.write_string("\t\t| DEPTH = ", !IO),
+            io.write_int(PrintDepth, !IO),
+            io.write_string("\t| CSN = ", !IO),
+            io.write_int(PrintCSN, !IO),
+            io.nl(!IO),
         
-        impure consume_io(!.IO),
+            semipure get_shadow_stack(ShadowStack),
+            impure prompt(ShadowStack, 0, WhatNext, !IO),
 
-            % XXX don not forget get the latest modification (like new breakpoint)
-	true
+            impure consume_io(!.IO),
+        
+            (
+                WhatNext = what_next_step,
+                NextStop = step
+            ;
+                WhatNext = what_next_next,
+                NextStop = next(PrintCSN)
+            ;
+                WhatNext = what_next_finish(EndCSN),
+                NextStop = final_port(EndCSN)
+            ),
+
+% XXX do not forget get the latest modification (like new breakpoint)
+            semipure get_debugger_state(State1),
+            State = State1 ^ ssdb_next_stop := NextStop,
+            impure set_debugger_state(State)
+        )
+    ;
+        Stop = no
     ).
 
 
     %
-    % Return the event number after increment
+    % Determine if two CSN are equals and if yes, do a stop
+    %
+:- pred is_same_event(int::in, int::in, bool::out) is det.
+
+is_same_event(CSNA, CSNB, IsSame) :-
+    IsSame = (CSNA = CSNB -> yes ; no).
+
+    %
+    % Increment and return the event number
+    % Update the state with the new event number
     %
 :- impure pred get_event_num_inc(int::out) is det.
 
 get_event_num_inc(EventNum) :-
     semipure get_debugger_state(State0),
-    EventNum0 = State0 ^ event_number,
+    EventNum0 = State0 ^ ssdb_event_number,
     EventNum = EventNum0 + 1,
-    State = State0 ^ event_number := EventNum,
+    State = State0 ^ ssdb_event_number := EventNum,
     impure set_debugger_state(State).
 
     %
@@ -164,82 +247,126 @@
 
 update_depth(Event, PrintDepth) :-
     semipure get_debugger_state(State0),
-    Depth0 = State0 ^ call_depth,
+    Depth0 = State0 ^ ssdb_call_depth,
     (
-	( Event = ssdb_call
-	; Event = ssdb_redo
-	),
-	Depth = Depth0 + 1,
-	PrintDepth = Depth0
-    ;
-	( Event = ssdb_exit
-	; Event = ssdb_fail
-	),
-	Depth = Depth0 - 1,
-	PrintDepth = 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,
+    State = State0 ^ ssdb_call_depth := Depth,
     impure set_debugger_state(State).
 
     %
-    % Return the csn after increment
+    % Increment and return the call sequence number
+    % Update the state with this new call sequence number
     %
 :- impure pred get_csn_inc(int::out) is det.
 
 get_csn_inc(CSN) :-
     semipure get_debugger_state(State0),
-    CSN0 = State0 ^ csn,
+    CSN0 = State0 ^ ssdb_csn,
     CSN = CSN0 + 1,
-    State = State0 ^ csn := CSN,
+    State = State0 ^ ssdb_csn := CSN,
     impure set_debugger_state(State).
 
     %
-    % push the element on to the debugger shadow stack
+    % Return the current event number
     %
-:- impure pred push(stack_elem::in) is det.
+:- semipure pred get_event_num(int::out) is det.
 
-push(E) :-
+get_event_num(EventNum) :-
     semipure get_debugger_state(State0),
-    Stack0 = State0 ^ stack,
-    Stack = [E | Stack0],
-    State = State0 ^ stack := Stack,
-    impure set_debugger_state(State).
+    EventNum = State0 ^ ssdb_event_number.
 
     %
-    % pop the debugger shadow stack returning
-    % the element on the top of the stack.
+    % Return the current call sequence number
     %
-:- impure pred pop(stack_elem::out) is det.
+:- semipure pred get_csn(int::out) is det.
 
-pop(E) :-
+get_csn(CSN) :-
     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).
-
+    CSN = State0 ^ ssdb_csn.
+    
     %
-    % Return the current event number
+    % Return the current shadow stack
     %
-:- semipure pred get_event_num(int::out) is det.
+:- semipure pred get_shadow_stack(stack(stack_elem)::out) is det.
 
-get_event_num(EventNum) :-
+get_shadow_stack(ShadowStack) :-
     semipure get_debugger_state(State0),
-    EventNum = State0 ^ event_number.
+    ShadowStack = State0 ^ ssdb_stack.
+
+%----------------------------------------------------------------------------%
 
     %
-    % Return the current csn
+    % Display the prompt to debug
+    %
+    % h     :: help
+    % f     :: finish (go to the next exit or fail of the current call)
+    % n     :: next
+    % s | _ :: next step
     %
-:- semipure pred get_csn(int::out) is det.
 
-get_csn(CSN) :-
-    semipure get_debugger_state(State0),
-    CSN = State0 ^ csn.
+:- impure pred prompt(stack(stack_elem)::in, int::in, what_next::out, 
+                io::di, io::uo) is det.
+
+prompt(ShadowStack, Depth, WhatNext, !IO) :-
+    io.write_string("ssdb> ", !IO),
+        %read a string in input and return a string
+    io.read_line_as_string(Result, !IO), 
+    (
+        Result = ok(String0),
+            %string minus any single trailing newline character
+        String = string.chomp(String0), 
+
+        ( 
+            String = "h" ->
+            io.nl(!IO),
+            io.write_string("s   :: step", !IO),
+            io.nl(!IO),
+            io.write_string("n   :: next", !IO),
+            io.nl(!IO),
+            io.write_string("f   :: finish", !IO),
+            io.nl(!IO),
+            io.nl(!IO),
+            impure prompt(ShadowStack, Depth, WhatNext, !IO)
+        
+        ; 
+            String = "n" ->
+            WhatNext = what_next_next
+        ;
+            (
+                String = "s"
+            ;
+                String = ""
+            )
+            ->
+                WhatNext = what_next_step
+        ;
+            String = "f" ->
+            stack.top_det(ShadowStack, FrameStack),
+            CSN = FrameStack ^  initial_state ^ ssdb_csn,
+            WhatNext = what_next_finish(CSN)
+        ;
+            io.write_string("huh?\n", !IO),
+            impure prompt(ShadowStack, Depth, WhatNext, !IO)
+        )
+    ;
+        Result = eof,
+        error("eof from read_line_as_string")
+    ;
+        Result = error(_),
+        error("error from read_line_as_string")
+    ).
+
 
 %----------------------------------------------------------------------------%
 
--------------------------------------------------------------------------
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