[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