From 9206b90b8a47f8ef63bbffabb2b9950af0ad2719 Mon Sep 17 00:00:00 2001 From: Greg Cooper Date: Thu, 15 Dec 2005 01:29:48 +0000 Subject: [PATCH] added NAP-TIME to highway.ss changed WHERE from a behavior to an event and updated sprofiler-mztake accordingly svn: r1617 --- .../mztake/demos/highway/highway-mztake.ss | 2 +- collects/mztake/demos/highway/highway.ss | 9 +- .../demos/sprofiler/sprofiler-mztake.ss | 8 +- collects/mztake/doc.txt | 194 +++++++++--------- collects/mztake/engine.ss | 2 +- collects/mztake/mztake.ss | 4 +- 6 files changed, 105 insertions(+), 114 deletions(-) diff --git a/collects/mztake/demos/highway/highway-mztake.ss b/collects/mztake/demos/highway/highway-mztake.ss index a537a799eb..67e8e9bd96 100644 --- a/collects/mztake/demos/highway/highway-mztake.ss +++ b/collects/mztake/demos/highway/highway-mztake.ss @@ -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) diff --git a/collects/mztake/demos/highway/highway.ss b/collects/mztake/demos/highway/highway.ss index 775bef0786..f6d15110a2 100644 --- a/collects/mztake/demos/highway/highway.ss +++ b/collects/mztake/demos/highway/highway.ss @@ -1,5 +1,6 @@ (module highway mzscheme - (let loop ([speed 0]) - (sleep 1) - ;; Generate some fake speeds readings: - (loop (+ speed 4)))) \ No newline at end of file + (let ([nap-time 0.8]) + (let loop ([speed 0]) + (sleep nap-time) + ;; Generate some fake speeds readings: + (loop (+ speed 4))))) \ No newline at end of file diff --git a/collects/mztake/demos/sprofiler/sprofiler-mztake.ss b/collects/mztake/demos/sprofiler/sprofiler-mztake.ss index c7bd70cc90..282307e6d4 100644 --- a/collects/mztake/demos/sprofiler/sprofiler-mztake.ss +++ b/collects/mztake/demos/sprofiler/sprofiler-mztake.ss @@ -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))) diff --git a/collects/mztake/doc.txt b/collects/mztake/doc.txt index 233970daa0..4dd895f779 100644 --- a/collects/mztake/doc.txt +++ b/collects/mztake/doc.txt @@ -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/ diff --git a/collects/mztake/engine.ss b/collects/mztake/engine.ss index b05889643d..47092f2734 100644 --- a/collects/mztake/engine.ss +++ b/collects/mztake/engine.ss @@ -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) diff --git a/collects/mztake/mztake.ss b/collects/mztake/mztake.ss index 53425786df..da40c05497 100644 --- a/collects/mztake/mztake.ss +++ b/collects/mztake/mztake.ss @@ -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)))