[m-rev.] add prompt to ssdb

Peter Wang novalazy at gmail.com
Mon Oct 8 13:09:42 AEST 2007


On 2007-10-05, Olivier Annet <oan at missioncriticalit.com> wrote:
> 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

Format this in the usual way with full sentences.

> 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 
> +    %

Sentences end with full stops.

I don't know what "Type filled by" means.  Also `prompt' and
`handle_event' (below) are not functions.

> +:- 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)

E is not a good name.

Why 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)

Ditto.

>      ;
> -	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),

You should have the debugger state already.

> +
> +    PrintCSN = E ^ initial_state ^ ssdb_csn,

PrintCSN is not a good name because you don't just print it.

>  
> -    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

    IsSame is `yes' iff the two call sequence numbers are equal,
    `no' otherwise.

> +    %
> +:- 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
>      %

    Increment the current event number in the debugger state, returning
    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).

I think "Print" is misleading.  You don't print anything here.

>  
>      %
> -    % 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.

You could put this closer to get_event_num_inc.

>  
>      %
> -    % 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.

Indent that just one level.

> +
> +prompt(ShadowStack, Depth, WhatNext, !IO) :-
> +    io.write_string("ssdb> ", !IO),
> +        %read a string in input and return a string

Formatting.

> +    io.read_line_as_string(Result, !IO), 
> +    (
> +        Result = ok(String0),
> +            %string minus any single trailing newline character

Formatting.

> +        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)

Write if-then-elses like this:

    ( String = "h" ->
	...
    ;
	...

or

    (
	String = "h"
    ->
	...
    ;
	...

Peter

--------------------------------------------------------------------------
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