added NAP-TIME to highway.ss
changed WHERE from a behavior to an event and updated sprofiler-mztake accordingly svn: r1617
This commit is contained in:
parent
5f88a3d5f3
commit
9206b90b8a
|
@ -2,7 +2,7 @@
|
|||
(lib "animation.ss" "frtime")
|
||||
(lib "useful-code.ss" "mztake"))
|
||||
|
||||
(define/bind (loc "highway.ss" 3) speed)
|
||||
(define/bind (loc "highway.ss" 4) speed)
|
||||
|
||||
(printf-b "current speed: ~a" speed)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(module highway mzscheme
|
||||
(let loop ([speed 0])
|
||||
(sleep 1)
|
||||
;; Generate some fake speeds readings:
|
||||
(loop (+ speed 4))))
|
||||
(let ([nap-time 0.8])
|
||||
(let loop ([speed 0])
|
||||
(sleep nap-time)
|
||||
;; Generate some fake speeds readings:
|
||||
(loop (+ speed 4)))))
|
|
@ -10,10 +10,10 @@
|
|||
|
||||
(define pings (make-hash 'equal))
|
||||
|
||||
((changes (where))
|
||||
. ==> . (match-lambda [(line function context rest ...)
|
||||
(hash-table-increment! pings (list function context))]
|
||||
[_ (void)]))
|
||||
(for-each-e (where)
|
||||
(match-lambda [(line function context rest ...)
|
||||
(hash-table-increment! pings (list function context))]
|
||||
[_ (void)]))
|
||||
|
||||
(define clicks (changes (quotient milliseconds 50)))
|
||||
|
||||
|
|
|
@ -4,56 +4,57 @@
|
|||
|
||||
About MzTake
|
||||
|
||||
_MzTake_ is a _scripted debugger_ for PLT Scheme. It helps
|
||||
_MzTake_ is a _scripted debugger_ for PLT Scheme. It helps
|
||||
programmers monitor the execution of a target program as it
|
||||
unfolds (and optionally pause or resume its execution). MzTake
|
||||
unfolds (and optionally pause or resume its execution). MzTake
|
||||
gives you the power to easily write real programs that debug real
|
||||
programs. You are no longer limited to a tool chest of buttons
|
||||
programs. You are no longer limited to a tool chest of buttons
|
||||
like "add breakpoint", "step-next", "step-into", and "step-over".
|
||||
|
||||
MzTake scripts are written in the FrTime programming
|
||||
language, which is bundled with DrScheme. FrTime supports the
|
||||
language, which is bundled with DrScheme. FrTime supports the
|
||||
implementation of reactive systems in a functional style.
|
||||
The key abstraction it adds is a type of value called a 'signal',
|
||||
which can change over time. FrTime infers dataflow dependencies
|
||||
between signals and automatically recomputes them when necessary. In
|
||||
which can change over time. FrTime infers dataflow dependencies
|
||||
between signals and automatically recomputes them when necessary. In
|
||||
order to use MzTake, you will need to familiarize yourself with the
|
||||
FrTime language by reading its own documentation.
|
||||
|
||||
With signals it is possible to respond to outside events concisely,
|
||||
without using callbacks. Consider a MzTake script to monitor the
|
||||
behavior of the program "highway.ss", in the demos directory of the
|
||||
MzTake collection:
|
||||
without using callbacks. Consider a MzTake script to monitor the
|
||||
behavior of the program "highway-mztake.ss", in the demos directory of
|
||||
the MzTake collection:
|
||||
|
||||
(require (lib "mztake.ss" "mztake"))
|
||||
(define/bind (loc "highway.ss" 3) speed)
|
||||
(printf-b "current speed: ~a" speed)
|
||||
;; more code
|
||||
(set-running! true)
|
||||
|
||||
This code executes a target module in the file "highway.ss"
|
||||
after installing a _trace point_ (also known as a _watch
|
||||
point_) just before the Scheme expression on the third line
|
||||
of "highway.ss". SPEED is a FrTime behavior that always
|
||||
of "highway.ss". SPEED is a FrTime behavior that always
|
||||
contains the *current* value of the variable named SPEED in
|
||||
the target program.
|
||||
|
||||
PRINTF-B works like Scheme's PRINTF function, consuming a
|
||||
format-string and fill-values, printing the result in
|
||||
DrScheme's interaction pane. Whereas PRINTF accumulates
|
||||
DrScheme's interaction pane. Whereas PRINTF accumulates
|
||||
outdated text on the screen, PRINTF-B will replace old text
|
||||
with updated text if any of the fill-values change. In this
|
||||
with updated text if any of the fill-values change. In this
|
||||
invocation, it prints the current speed to screen, throughout
|
||||
the execution of "highway.ss". The last line invokes SET-RUNNING!,
|
||||
the execution of "highway.ss". The last line invokes SET-RUNNING!,
|
||||
which lunches the execution of highway.ss
|
||||
|
||||
MzTake scripts are also powerful tools for building external
|
||||
test suites. Whereas typical test cases may only assert that
|
||||
test suites. Whereas typical test cases may only assert that
|
||||
the result of a computation is correct, MzTake scripts
|
||||
can dynamically break open an execution, record inner state,
|
||||
and *compute* with it. This allows you to confirm that the
|
||||
and *compute* with it. This allows you to confirm that the
|
||||
intermediate steps which lead to a correct answer were
|
||||
also correct. In the highway example, perhaps knowing the last ten speeds that
|
||||
would prove useful. You could PRINTF the value
|
||||
also correct. In the highway example, perhaps knowing the last ten speeds
|
||||
would prove useful. You could PRINTF the value
|
||||
onto a new line each time, but after ten updates the screen
|
||||
is already starting to fill up with information -- we are
|
||||
only interested in the last ten speeds, after all.
|
||||
|
@ -64,44 +65,30 @@ One possible solution:
|
|||
HISTORY-B consumes an event stream (CHANGES SPEED) and an
|
||||
optional number n, returning a FrTime behavior containing a
|
||||
FIFO ordered list of the n values emitted on that event
|
||||
stream. In this case, HISTORY-B maintains a list of the ten
|
||||
stream. In this case, HISTORY-B maintains a list of the ten
|
||||
most recent SPEEDS seen on SPEED.
|
||||
|
||||
We might want to pause the program when something goes awry. We do
|
||||
this by exploiting the fact that SET-RUNNING! function consumes a
|
||||
FrTime behavior. The value of a behavior can change over time, and
|
||||
SET-RUNNING! monitor these changes. Whenever the behavior is true, the
|
||||
target program runs, whenever it is false, the target program
|
||||
pauses. We can indicate to MzTake to pause when the speed exceeds 55
|
||||
We might want to pause the program when something goes awry. We do
|
||||
this by exploiting the fact that the SET-RUNNING! function consumes a
|
||||
FrTime behavior. The value of a behavior can change over time, and
|
||||
SET-RUNNING! monitors these changes. Whenever the behavior is true,
|
||||
the target program runs, and whenever it is false, the target program
|
||||
pauses. We can indicate to MzTake to pause when the speed exceeds 55
|
||||
as follow:
|
||||
|
||||
(printf-b "last ten speeds: ~a" (history-b (changes speed) 10))
|
||||
(set-running! (< speed 55))
|
||||
|
||||
Once paused, it becomes possible to interactively explore the state of
|
||||
the paused process. You can use the BIND function to reach into the
|
||||
scope of the target process and read the value of the variable:
|
||||
|
||||
(bind (speed) (printf "the speed is ~a~n" speed))
|
||||
|
||||
This lines finds the variable named "speed" in the scope at the point
|
||||
where the execution is paused, then binds its values to a variable
|
||||
named "speed" in the MzTake script, then executes its body. In this
|
||||
case, it print the value with PRINTF.
|
||||
|
||||
Since MzTake defines a #%top syntax, you can also directly type the
|
||||
name of a variable. MzTake will first look in the scope in the MzTake
|
||||
script. If the variable is not found, it will then in the target
|
||||
process. So, the example above can be written as:
|
||||
|
||||
(printf "the speed is ~a~n" speed)
|
||||
|
||||
so long as the script itself does not declare a SPEED variable.
|
||||
Once paused, it is possible to interactively explore the state of the
|
||||
paused process. You may enter names of variables bound in the target
|
||||
program, and MzTake will look up and return their values. For
|
||||
example, typing 'nap-time' in the REPL while the program is paused
|
||||
yields the value 0.8.
|
||||
|
||||
You can resume execution with "(set-running #t)", or
|
||||
some other behavior, or end the execution altogether with "(kill)".
|
||||
|
||||
Finally, FrTime provides a rich animation library. Combined
|
||||
Finally, FrTime provides a rich animation library. Combined
|
||||
with the MzTake debugger, it takes only a few lines to animate
|
||||
your algorithms and see them in action, easily letting you
|
||||
confirm (or refute!) that they are working correctly.
|
||||
|
@ -116,10 +103,10 @@ confirm (or refute!) that they are working correctly.
|
|||
|
||||
The demos directory contains a sub-directory for each of the demos.
|
||||
For instance, the highway directory contains "highway.ss" and
|
||||
"highway-mztake.ss". To run this demo, switch to the "FrTime" language
|
||||
"highway-mztake.ss". To run this demo, switch to the "FrTime" language
|
||||
level from the "Experimental Languages" section of DrScheme's language
|
||||
dialog, load "highway-mztake.ss", and click "Run". What you see is
|
||||
generated by the debugging script. Each demo directory contains
|
||||
dialog, load "highway-mztake.ss", and click "Run". What you see is
|
||||
generated by the debugging script. Each demo directory contains
|
||||
the following two files: one is the program being debugged
|
||||
(named after the directory), and the other is a file ending
|
||||
in "...-mztake.ss" (the MzTake script).
|
||||
|
@ -128,7 +115,7 @@ The demos are (starting with the simplest one):
|
|||
|
||||
./highway/highway-mztake.ss - The program simulates a very simple
|
||||
speedometer, and the MzTake script
|
||||
monitors it.
|
||||
monitors it.
|
||||
|
||||
./sine/sine-mztake.ss - Plots values extracted from a program
|
||||
which generates coordinates for a
|
||||
|
@ -149,7 +136,7 @@ That said, in order to become more proficient in using MzTake,
|
|||
you will want to learn more about the FrTime language.
|
||||
|
||||
You can refer to FrTime's own documentation by searching for
|
||||
"FrTime" in DrScheme's Help window. It explains how to use
|
||||
"FrTime" in DrScheme's Help window. It explains how to use
|
||||
time-varying behaviors and event streams in greater depth, and
|
||||
also describes the many useful functions FrTime provides to work
|
||||
with them.
|
||||
|
@ -162,9 +149,9 @@ _Debugging with MzTake_
|
|||
|
||||
MzTake is a library for the FrTime languages which provides functions
|
||||
that execute a target program (or many), and "connect" to points in
|
||||
its code. MzTake then provides the running FrTime script with
|
||||
its code. MzTake then provides the running FrTime script with
|
||||
interesting information (such as a variable's current value) which it
|
||||
derives from these "connections". FrTime then handles the rest.
|
||||
derives from these "connections". FrTime then handles the rest.
|
||||
|
||||
MzTake defines the following functions and macros:
|
||||
|
||||
|
@ -174,24 +161,24 @@ _Installing Trace Points_
|
|||
> (loc require-spec line-number column-number)
|
||||
|
||||
Creates a LOC structure containing the target file, the target line
|
||||
number, and (optionally) the target column number. LOC structures
|
||||
are consumed by TRACE and by DEFINE/BIND. The first argument to LOC
|
||||
number, and (optionally) the target column number. LOC structures
|
||||
are consumed by TRACE and by DEFINE/BIND. The first argument to LOC
|
||||
is a file specification suitable for require, provided as a
|
||||
datum. For instance, to install a trace point on the tenth line of
|
||||
datum. For instance, to install a trace point on the tenth line of
|
||||
the MzLib's list library, use:
|
||||
|
||||
(trace (loc '(lib "list.ss") 10) ...)
|
||||
|
||||
> (trace loc body ...)
|
||||
|
||||
Install a trace point at the location indicated by the LOC
|
||||
value. The result is a FrTime event stream containing one value
|
||||
each time the target reaches the location specified. To get the
|
||||
value event, TRACE evaluates its body (once per event. During the
|
||||
evaluation of the body, the target process is paused, and BIND is
|
||||
available to inspect the state of the paused program.
|
||||
Install a trace point at the location indicated by the LOC value.
|
||||
The result is a FrTime event stream containing one value each time
|
||||
the target reaches the location specified. To get the value event,
|
||||
TRACE evaluates its body (once per event. During the evaluation of
|
||||
the body, the target process is paused, and the body can inspect
|
||||
the state of the paused program.
|
||||
|
||||
The body is optional. If no body is provided, the value #t is used
|
||||
The body is optional. If no body is provided, the value #t is used
|
||||
by default.
|
||||
|
||||
Unless SET-MAIN! is used, the first call to trace sets the file
|
||||
|
@ -206,12 +193,14 @@ _Installing Trace Points_
|
|||
|
||||
When the target process is paused (or during the execution of a
|
||||
trace body), BIND reaches in the lexical context at the point of
|
||||
the pause (or of the trace point) and find the values for the
|
||||
variables whose names are given. These values are then bound in the
|
||||
body (in the MzTake script) to variable of the same name.
|
||||
the pause (or of the trace point) and finds the values for the
|
||||
variables whose names are given. These values are then bound in the
|
||||
body (in the MzTake script) to the variables of the same name.
|
||||
|
||||
It is an error to call BIND while the target process is running.
|
||||
|
||||
You can use BIND to look up values of identifiers in the target
|
||||
program that are shadowed by identifiers in the script.
|
||||
|
||||
> (bind* process symbol)
|
||||
|
||||
|
@ -221,16 +210,17 @@ _Installing Trace Points_
|
|||
|
||||
> (define/bind loc name ...)
|
||||
|
||||
Define the NAMEs the to behaviors reflecting the values of the
|
||||
giving name in the target program, at the given
|
||||
location. DEFINE/BIND is short for:
|
||||
Define the NAMEs to behaviors reflecting the values of the
|
||||
given names in the target program, at the given
|
||||
location. DEFINE/BIND is short for:
|
||||
|
||||
(define name (hold (trace loc (bind (name) name))))
|
||||
|
||||
|
||||
> (define/bind-e loc name ...)
|
||||
|
||||
Same as DEFINE/BIND, but returns an event stream instead of a behavior.
|
||||
Same as DEFINE/BIND, but binds event streams to the names instead
|
||||
of behaviors.
|
||||
|
||||
|
||||
> (exceptions)
|
||||
|
@ -252,21 +242,21 @@ _Installing Trace Points_
|
|||
> (set-running! event)
|
||||
> (set-running! event process)
|
||||
|
||||
Lunches the execution of the target process. Execution continues as
|
||||
long as the given behavior is true (aka, any value beside #f), or
|
||||
until an event comes on the given event stream with the value
|
||||
#f. When execution pauses, the target remains on the line where the
|
||||
paused occured. You can then inspect the state of the program with
|
||||
BIND, or resume execution with another call to SET-RUNNING!.
|
||||
Launches the execution of the target process. Execution continues
|
||||
as long as the given behavior is true (aka, any value beside #f),
|
||||
or until an event comes on the given event stream with the value
|
||||
#f. When execution pauses, the target remains on the line where
|
||||
the pause occured. You can then inspect the state of the program,
|
||||
or resume execution with another call to SET-RUNNING!.
|
||||
|
||||
|
||||
> (set-main! require-spec)
|
||||
> (set-main! require-spec process)
|
||||
|
||||
Sets the file where execution begins when SET-RUNNING! is called
|
||||
for the first time. When SET-MAIN! is not used explicitly,
|
||||
for the first time. When SET-MAIN! is not used explicitly,
|
||||
execution begins with the file specified in the first call to
|
||||
trace. It is an error to call SET-RUNNING! without first calling
|
||||
TRACE. It is an error to call SET-RUNNING! without first calling
|
||||
either TRACE or SET-MAIN!.
|
||||
|
||||
|
||||
|
@ -274,8 +264,8 @@ _Installing Trace Points_
|
|||
> (where process)
|
||||
|
||||
Returns an event stream that contains one event for each expression
|
||||
evaluated in the target process. Combined with HISTORY-B, this let
|
||||
you record entire execution traces for the target program.
|
||||
evaluated in the target process. Combined with HISTORY-B, this makes
|
||||
it possible to record entire execution traces for the target program.
|
||||
|
||||
|
||||
> (kill)
|
||||
|
@ -283,9 +273,9 @@ _Installing Trace Points_
|
|||
Kills the target process and releases all resources
|
||||
it used -- you cannot resume after a KILL.
|
||||
|
||||
This will not stop of evaluation of the MzTake script, however. In
|
||||
This will not stop evaluation of the MzTake script, however. In
|
||||
particular, if the script depends on input the varies independently
|
||||
of the target process, FrTime will continue to update them. You can
|
||||
of the target process, FrTime will continue to update them. You can
|
||||
use "Kill" command from DrScheme's "Scheme" menu to stop both the
|
||||
MzTake script and its target process at once.
|
||||
|
||||
|
@ -303,20 +293,20 @@ _Installing Trace Points_
|
|||
|
||||
The CURRENT-PROCESS parameter gets or sets the process manipulated
|
||||
by the MzTake function when they are not provided with a process
|
||||
argument. The CURRENT-PROCESS parameter is initialized with a blank
|
||||
argument. The CURRENT-PROCESS parameter is initialized with a blank
|
||||
process, and you can create additional processes using the
|
||||
CREATE-DEBUG-PROCESS function. Using more than one process at a
|
||||
CREATE-DEBUG-PROCESS function. Using more than one process at a
|
||||
time lets your MzTake run multiple programs different at once and
|
||||
compare their output using a single script.
|
||||
|
||||
|
||||
> (create-debug-process)
|
||||
|
||||
Creates a fresh blank debug process. Each debug process has its own
|
||||
Creates a fresh blank debug process. Each debug process has its own
|
||||
set of trace points, its own run trigger (set via SET-RUNNING!),
|
||||
its own exceptions stream, etc. Each debug process run
|
||||
its own exceptions stream, etc. Each debug process run
|
||||
independently from the others, and they can be paused and killed
|
||||
individually. All debug processes in a single MzTake script share
|
||||
individually. All debug processes in a single MzTake script share
|
||||
the same FrTime event space, and so it is possible to compare
|
||||
output and traces between each of them.
|
||||
|
||||
|
@ -324,18 +314,18 @@ _Installing Trace Points_
|
|||
> (current-policy policy)
|
||||
|
||||
Every file executed under MzTake can run either in fast mode or in
|
||||
debuggable mode. The CURRENT-POLICY decides which.
|
||||
debuggable mode. The CURRENT-POLICY decides which.
|
||||
|
||||
- debuggable mode: the file is instrumented with MzTake debugging
|
||||
information. It can be the target of trace point and it generate
|
||||
events on the WHERE stream. Execution can also be paused in the middle
|
||||
of code running in debuggable mode. The instrumentation overhead
|
||||
information. It can be the target of trace point and it generate
|
||||
events on the WHERE stream. Execution can also be paused in the middle
|
||||
of code running in debuggable mode. The instrumentation overhead
|
||||
is considerable, however, of the order of 10x-20x slowdown.
|
||||
|
||||
- fast mode: the file is not instrumented, and runs at its normal
|
||||
speed, but cannot be debugged. Inserting trace points into fast
|
||||
speed, but cannot be debugged. Inserting trace points into fast
|
||||
mode files after the beginning of the execution has no
|
||||
effect. Also, pausing while executing a fast mode file will be
|
||||
effect. Also, pausing while executing a fast mode file will be
|
||||
delayed until execution reaches a debuggable mode file.
|
||||
|
||||
MzTake uses the following rules, in order, to decide between fast
|
||||
|
@ -360,23 +350,23 @@ _Installing Trace Points_
|
|||
string?
|
||||
(listof (union path? string?)))))
|
||||
|
||||
A policy consist of a list of entries. Each entry is a pair
|
||||
A policy consist of a list of entries. Each entry is a pair
|
||||
specifying either fast mode or debuggable mode, then a directory,
|
||||
or a list of directories. Files in these directories, or their
|
||||
subdirectories will run under the given mode. The special symbol
|
||||
or a list of directories. Files in these directories, or their
|
||||
subdirectories will run under the given mode. The special symbol
|
||||
'everything-else can be used instead of a directory, and this will
|
||||
match any file. The policy is checked in order, and the first entry
|
||||
match any file. The policy is checked in order, and the first entry
|
||||
that applies to the given filename assign a mode the file.
|
||||
|
||||
The default policy run files of the directories specified by
|
||||
CURRENT-LIBRARY-COLLECTIONS-PATHS in fast mode, and runs everything
|
||||
else in debuggable mode. This poloicy is set as follow:
|
||||
else in debuggable mode. This poloicy is set as follow:
|
||||
|
||||
(current-policy `((fast ,(current-library-collection-paths))
|
||||
(debuggable everything-else)))
|
||||
|
||||
You can change this policy by calling the
|
||||
CURRENT-POLICY function with a new policy as an argument. The
|
||||
CURRENT-POLICY function with a new policy as an argument. The
|
||||
policy is assigned to a process when the process lunches.
|
||||
|
||||
|
||||
|
@ -394,7 +384,7 @@ Tips: When you have a behavior that you want to turn into
|
|||
|
||||
|
||||
MzTake defines a few functions on time-varying values
|
||||
that are particularly useful when debugging. You can require these
|
||||
that are particularly useful when debugging. You can require these
|
||||
functions with (require (lib "useful-code.ss" "mztake"))
|
||||
|
||||
> (history-e stream)
|
||||
|
@ -432,8 +422,8 @@ functions with (require (lib "useful-code.ss" "mztake"))
|
|||
> (sequence-match? seq stream)
|
||||
|
||||
Matches a sequence of items in a list to the history
|
||||
of event pings, on the event stream evs. Returns #t
|
||||
when it matches, and #f otherwise. Use when you expect
|
||||
of event pings, on the event stream evs. Returns #t
|
||||
when it matches, and #f otherwise. Use when you expect
|
||||
a certain pattern to show up, and want to know when:
|
||||
(sequence-match? '(0 1 2 1 0) (changes bind-trace))
|
||||
|
||||
|
@ -473,7 +463,7 @@ Known Problems
|
|||
|
||||
* Some legal syntax locations (used in setting trace points)
|
||||
are unreachable during program execution (they do not get
|
||||
triggered and produce empty eventstreams). For instance,
|
||||
triggered and produce empty eventstreams). For instance,
|
||||
the name clause of a LET is never the current point of execution:
|
||||
|
||||
(define x 12)
|
||||
|
@ -500,7 +490,7 @@ Known Problems
|
|||
|
||||
Authors and Thanks
|
||||
|
||||
MzTake is an experimental debugger. It should enable new
|
||||
MzTake is an experimental debugger. It should enable new
|
||||
debugging approaches that were not possible (easily) before.
|
||||
Please send feedback to the PLT-Scheme mailing list:
|
||||
http://www.plt-scheme.org/maillist/
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
[else (frp:send-synchronous-events (traces->events traces))])
|
||||
|
||||
;; With a where event to generate
|
||||
(let ([where-event ((frp:signal-thunk (debug-process-where process)) #t)]
|
||||
(let ([where-event (debug-process-where process)]
|
||||
[w (map (compose syntax-local-infer-name mark-source) marks)])
|
||||
(if no-traces?
|
||||
(frp:send-synchronous-event where-event w)
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
[kill-all (-> void?)]
|
||||
[set-running-e! ((frp:event?) (debug-process?) . opt-> . any)]
|
||||
[set-running! ((frp:value-nowable?) (debug-process?) . opt-> . any)]
|
||||
[where (() (debug-process?) . opt-> . frp:behavior?)]
|
||||
[where (() (debug-process?) . opt-> . frp:event?)]
|
||||
[current-policy (case-> (-> any)
|
||||
(any/c . -> . void?))]
|
||||
[current-process (case-> (-> debug-process?)
|
||||
|
@ -76,7 +76,7 @@
|
|||
(define where
|
||||
(opt-lambda ([p (current-process)])
|
||||
(unless (debug-process-where p)
|
||||
(set-debug-process-where! p (frp:new-cell empty)))
|
||||
(set-debug-process-where! p (frp:event-receiver)))
|
||||
(debug-process-where p)))
|
||||
|
||||
(define current-process (make-parameter (create-debug-process)))
|
||||
|
|
Loading…
Reference in New Issue
Block a user