[m-rev.] for review: minimal support for ssdebug on multithreaded programs
Peter Wang
novalazy at gmail.com
Thu Jun 24 15:26:39 AEST 2010
Branches: main, 10.04
Add an (undocumented) method for ssdebug, to allow debugging of only the
initial thread in a multi-threaded program.
ssdb/ssdb.m:
Make the debugger_state mutable thread-local, so that all threads but
the initial one can execute as if debugging is disabled.
Add `pause_debugging' and `resume_debugging' predicates that the user
must call around calls to `thread.spawn'. Mercury only supports
thread-local mutables which inherit their values from the parent
thread, so when the thread is created the debugger_state mutable must
be set to `off'. The predicates may have other uses, too.
README.ssdebug:
List debugging of multi-threaded programs as a limitation.
diff --git a/README.ssdebug b/README.ssdebug
index 658bf33..3522c61 100644
--- a/README.ssdebug
+++ b/README.ssdebug
@@ -90,4 +90,6 @@ LIMITATIONS
- There is no I/O tabling.
+- Debugging of threaded programs is not supported.
+
-----------------------------------------------------------------------------
diff --git a/ssdb/ssdb.m b/ssdb/ssdb.m
index 111cf61..3b8808d 100755
--- a/ssdb/ssdb.m
+++ b/ssdb/ssdb.m
@@ -20,8 +20,12 @@
:- module ssdb.
:- interface.
+
+:- import_module io.
:- import_module list.
+%-----------------------------------------------------------------------------%
+
:- type ssdb_proc_id
---> ssdb_proc_id(
module_name :: string,
@@ -103,6 +107,26 @@
:- impure pred handle_event_redo_nondet(ssdb_proc_id::in,
list_var_value::in) is det.
+%-----------------------------------------------------------------------------%
+
+:- type debugging_paused.
+
+ % These low-level predicates allow you to suspend the debugger temporarily.
+ %
+ % Debugging of multi-threaded programs is unsupported, but it is possible
+ % to debug the initial thread only, if you pause debugging while spawning
+ % a thread:
+ %
+ % ssdb.pause_debugging(Paused, !IO),
+ % thread.spawn(some_thread_proc, !IO),
+ % ssdb.resume_debugging(Paused, !IO)
+ %
+ % The spawned thread will simply execute as if debugging was disabled.
+ % It will continue running in the background during debugger prompts.
+ %
+:- pred pause_debugging(debugging_paused::out, io::di, io::uo) is det.
+:- pred resume_debugging(debugging_paused::in, io::di, io::uo) is det.
+
%----------------------------------------------------------------------------%
%----------------------------------------------------------------------------%
@@ -113,7 +137,6 @@
:- import_module bool.
:- import_module char.
:- import_module dir.
-:- import_module io.
:- import_module int.
:- import_module map.
:- import_module maybe.
@@ -146,6 +169,8 @@
---> debugger_off
; debugger_on.
+:- type debugging_paused == debugger_state.
+
:- type stack_frame
---> stack_frame(
% Event Number
@@ -309,15 +334,19 @@ init_list_params = list_params(new_list_path, 2).
:- mutable(saved_output_stream, io.output_stream, io.stdout_stream, ground,
[untrailed, attach_to_io_state]).
- % This must be after the tty streams.
-:- mutable(debugger_state, debugger_state, init_debugger_state, ground,
- [untrailed, attach_to_io_state]).
+ % This is thread-local to allow debugging of the initial thread in
+ % multi-threaded programs. As thread-local mutables inherit their values
+ % from the parent thread, the user must temporarily disable debugging while
+ % the child thread is created, using `pause_debugging'.
+ %
+:- mutable(debugger_state, debugger_state, debugger_off, ground,
+ [untrailed, thread_local, attach_to_io_state]).
-:- func init_debugger_state = debugger_state is det.
+:- initialise(init_debugger_state/2).
-init_debugger_state = DebuggerState :-
- some [!IO] promise_pure (
- impure invent_io(!:IO),
+:- pred init_debugger_state(io::di, io::uo) is det.
+
+init_debugger_state(!IO) :-
io.get_environment_var("SSDB", MaybeEnv, !IO),
io.get_environment_var("SSDB_TTY", MaybeTTY, !IO),
(
@@ -351,8 +380,7 @@ init_debugger_state = DebuggerState :-
;
DebuggerState = debugger_off
),
- impure consume_io(!.IO)
- ).
+ set_debugger_state(DebuggerState, !IO).
:- pred add_source_commands(io::di, io::uo) is det.
@@ -436,6 +464,25 @@ step_next_stop(!IO) :-
%-----------------------------------------------------------------------------%
+pause_debugging(Paused, !IO) :-
+ get_debugger_state(Paused, !IO),
+ (
+ Paused = debugger_off
+ ;
+ Paused = debugger_on,
+ set_debugger_state(debugger_off, !IO)
+ ).
+
+resume_debugging(Paused, !IO) :-
+ (
+ Paused = debugger_on,
+ set_debugger_state(debugger_on, !IO)
+ ;
+ Paused = debugger_off
+ ).
+
+%-----------------------------------------------------------------------------%
+
set_context(FileName, Line) :-
impure set_cur_filename(FileName),
impure set_cur_line_number(Line).
--------------------------------------------------------------------------
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