[PATCH] Make Guile Debugger less flaky.

[ Thread Index | Date Index | More lilynet.net/frogs Archives ]


Move break-point and trace routines to a separate .scm file.

Update Debugging Chapter in CG.
---
 Documentation/contributor/programming-work.itexi |  168 +++++++++++++++++-----
 ly/guile-debugger.ly                             |   42 +++---
 scm/guile-debugger.scm                           |   27 ++++
 scm/lily.scm                                     |   22 ++--
 4 files changed, 189 insertions(+), 70 deletions(-)
 create mode 100755 scm/guile-debugger.scm

diff --git a/Documentation/contributor/programming-work.itexi b/Documentation/contributor/programming-work.itexi
index 17e4bc9..ecfb777 100644
--- a/Documentation/contributor/programming-work.itexi
+++ b/Documentation/contributor/programming-work.itexi
@@ -656,7 +656,10 @@ Do not run make po/po-update with GNU gettext < 0.10.35
 @section Debugging LilyPond
 
 The most commonly used tool for debugging LilyPond is the GNU debugger
-gdb.  Use of gdb is described in this section.
+gdb.
+The gdb tool is used for investigating and debugging core Lilypond code written in C++.
+Another tool is available for debugging Scheme code using the Guile debugger,
+This section describes using both gdb and the Guile Debugger.
 
 @subsection Debugging overview
 
@@ -671,9 +674,9 @@ the sequence in which functions are called and the arguments to the
 various function calls.
 
 
-@subsection Compiling with debugging information
+@subsection Compiling LilyPond for use with gdb
 
-In order to use a debugger with LilyPond, it is necessary to compile
+In order to use gdb with LilyPond, it is necessary to compile
 LilyPond with debugging information.  This is accomplished by running
 the following commands in the main LilyPond source directory.
 
@@ -683,51 +686,40 @@ the following commands in the main LilyPond source directory.
 make
 @end example
 
-This will create a version of LilyPond that contains the debugging
+This will create a version of LilyPond containing debugging
 information that will allow the debugger to tie the source code
 to the compiled code.
 
 You should not do @var{make install} if you want to use a debugger
-with LilyPond.  @var{make install} will strip the debugging information
+with LilyPond.  The @var{make install} command will strip debugging information
 from the LilyPond binary.
 
-To set breakpoints in Scheme functions, put
-
-@example
-\include "guile-debugger.ly"
-@end example
+@subsection Typical gdb usage
 
-in your input file after any scheme procedures you have defined in
-that file.  When your input file is processed, a guile prompt
-will be displayed.  At the guile prompt, you can set breakpoints with
-the @code{break!} procedure:
+Once you have compiled the Lilypond image with the necessary debugging information it will 
+have been written to a location in a subfolder of your current working directory:
 
 @example
-guile> (break! my-scheme-procedure)
+out/bin/lilypond
 @end example
 
-Once you have set the desired breakpoints, you exit the guile repl frame
-by typing:
-
+This is important as you will need to let gdb know where to find the image. 
+You can invoke gdb from the command line using
 @example
-guile> (quit)
+$ gdb out/bin/lilypond
 @end example
-
-When one of the scheme routines for which you have set breakpoints is
-entered, guile will interrupt execution in a debug frame.  At this point,
-you will have access to guile debugging commands.  For a listing of these
-commands, type:
-
+or you may use a graphical interface to gdb such as ddd
 @example
-debug> help
+$ gdb out/bin/lilypond
 @end example
+You can also use sets of standard gdb commands stored in a .gdbinit file (see next 
+section).
 
-@subsection Typical gdb usage
-
+ 
 @subsection Typical .gdbinit files
 
-The behavior of gdb can be readily customized through the use of
-@var{.gdbinit} files.  A @var{.gdbinit} file is a file named
+The behavior of gdb can be readily customized through the use of a
+@var{.gdbinit} file.  A @var{.gdbinit} file is a file named
 @var{.gdbinit} (notice the @qq{.} at the beginning of the file name)
 that is placed in a user's home directory.
 
@@ -756,10 +748,16 @@ define pmusic
 end
 @end example
 
+@subsection Debugging Scheme Code
+Scheme code can be developed using the Guile command line interpreter @code{top-repl}.
+You can either investigate interactively using just Guile or you can use the debugging 
+tools available within Guile.
+
+
 @subsection Using Guile interactively with LilyPond
 
 In order to experiment with Scheme programming in the LilyPond
-environment, it is convenient to have a Guile interpreter that
+environment, it is necessary to have a Guile interpreter that
 has all the LilyPond modules loaded.  This requires the following
 steps.
 
@@ -771,7 +769,7 @@ in the .ly file:
                  'lilypond-module (current-module))
 @end example
 
-Second, place a Scheme function in the .ly file that gives an interactive Guile
+Now, place a Scheme function in the .ly file that gives an interactive Guile
 prompt:
 
 @example
@@ -779,15 +777,15 @@ prompt:
 @end example
 
 When the .ly file is compiled, this causes the compilation to be interrupted
-and an interactive guile prompt to appear.  When the guile prompt appears,
+and an interactive guile prompt to appear.  Once the guile prompt appears,
 the LilyPond active module must be set as the current guile module:
 
 @example
 guile> (set-current-module lilypond-module)
 @end example
 
-Proper operation of these commands can be demonstrated by typing the name
-of a LilyPond public scheme function to see if it's properly defined:
+You can demonstrate these commands are operating properly by typing the name
+of a LilyPond public scheme function to check it has been define:
 
 @example
 guile> fret-diagram-verbose-markup
@@ -815,6 +813,106 @@ guile> (quit)
 
 The compilation of the .ly file will then continue.
 
+@subsection Using the Guile debugger
+
+To set breakpoints and/or enable tracing in Scheme functions, put
+
+@example
+\include "guile-debugger.ly"
+@end example
+
+in your input file after any scheme procedures you have defined in
+that file.  
+This will invoke the Guile command-line and have set up the environment for the debug 
+command lines.
+When your input file is processed, a guile prompt will be displayed.  
+You may now enter commands to set up breakpoints and enable tracing by the Guile debugger.
+
+@subsection Using Breakpoints
+
+At the guile prompt, you can set breakpoints with
+the @code{set-break!} procedure:
+
+@example
+guile> (set-break! my-scheme-procedure)
+@end example
+
+Once you have set the desired breakpoints, you exit the guile repl frame
+by typing:
+
+@example
+guile> (quit)
+@end example
+
+When one of the scheme routines for which you have set breakpoints is
+entered, guile will interrupt execution in a debug frame.  At this point,
+you will have access to guile debugging commands.  For a listing of these
+commands, type:
+
+@example
+debug> help
+@end example
+
+Alternatively you may code the breakpoints in your Lilypond source file using a command 
+such as:
+@example
+#(set-break! my-scheme-procedure)
+@end example
+immediately after the @code{\include} statement.  In this case the breakpoint will be set 
+straight after you enter the @code{(quit)} command at the guile prompt.
+
+Embedding breakpoint commands like this is particularly useful if you want to look at how 
+the Scheme procedures in the @var{.scm} files supplied with LilyPond work.
+
+In this case you can edit the file in the relevant directory to add this line near the top:
+
+@example
+(use-modules (scm guile-debugger)
+@end example
+Now you can set a breakpoint after the procedure you are interested in has been declared.
+For example if you are working on routines called by @var{print-book-with} in 
+@var{lily-library.scm}:
+
+@example
+(define (print-book-with parser book process-procedure)
+  (let* ((paper (ly:parser-lookup parser '$defaultpaper))
+	 (layout (ly:parser-lookup parser '$defaultlayout))
+	 (outfile-name (get-outfile-name parser)))
+    (process-procedure book paper layout outfile-name)))
+
+(define-public (print-book-with-defaults parser book)
+  (print-book-with parser book ly:book-process))
+
+(define-public (print-book-with-defaults-as-systems parser book)
+  (print-book-with parser book ly:book-process-to-systems))
+
+@end example
+
+At this point in the code you could add this to set a breakpoint at print-book-with:
+
+@example
+
+(set-break print-book-with)
+
+@end example
+
+@strong{Tracing}
+
+In the above example you will note that trace-points have also been set.  There are two 
+forms of trace available:
+
+@example
+(set-trace! my-scheme-procedure)
+@end example
+and
+@example
+(set-trace-subtree! my-scheme-procedure)
+@end example
+
+@code{set-trace!} allows Scheme to log a line to the standard output to show when the
+procedure is called and when it exits.  @code{set-trace-subtree!} traces each line in the
+body of the procedure as it is executed.
+
 @node Adding or modifying features
 @section Adding or modifying features
 
diff --git a/ly/guile-debugger.ly b/ly/guile-debugger.ly
index f6e63d3..70069b1 100644
--- a/ly/guile-debugger.ly
+++ b/ly/guile-debugger.ly
@@ -24,33 +24,27 @@
 %%  For more information, see the Contributor's Guide.
 
 
-\version "2.13.4"
-
-#(use-modules
-  (ice-9 debugger)
-  (ice-9 debugging trace)
-  (ice-9 debugging steps)
-  (ice-9 debugging ice-9-debugger-extensions))
-
-#(define (break! proc)
-   (install-trap (make <procedure-trap>
-                   #:procedure proc
-                   #:behaviour debug-trap)))
-
-#(define (trace! proc)
-   (install-trap (make <procedure-trap>
-                   #:procedure proc
-                   #:behaviour (list trace-trap
-                                     trace-at-exit))))
-
-#(define (trace-subtree! proc)
-   (install-trap (make <procedure-trap>
-                   #:procedure proc
-                   #:behaviour (list trace-trap
-                                     trace-until-exit))))
+\version "2.13.10"
 
+% define lilypond-module as a variable in the guile-user module and set to the current 
+% Scheme module (which will be the lilypond top-level  
+% module)                                                                                  
+   
 #(module-define! (resolve-module '(guile-user))
                  'lilypond-module
                  (current-module))
+%                                                                                                                                
+% Ensure we have command-line recall available at guile> prompt                                                                  
+%                                                                                                                                
+#(use-modules (ice-9 readline))                                                                                                  
+#(activate-readline)                                                                                                             
+#(display "\n Guile debugger for Lilypond\n")                                                                                    
+#(use-modules (scm guile-debugger))                                                                                              
+#(newline)    
 #(top-repl)
+%                                                                                                                                
+% top-repl has re-set the module to guile-user,                                                                                  
+%  so we need to set it back to lilypond-module                                                                                  
+%                                                                                                                                
+#(ly:module-copy (current-module) (resolve-module '(lilypond-module)))    
 #(set-current-module lilypond-module)
diff --git a/scm/guile-debugger.scm b/scm/guile-debugger.scm
new file mode 100755
index 0000000..5885a00
--- /dev/null
+++ b/scm/guile-debugger.scm
@@ -0,0 +1,27 @@
+(define-module ( scm guile-debugger)  
+  #:use-module  (ice-9 debugger) 
+  #:use-module  (ice-9 debugging traps)
+  #:use-module  (ice-9 debugging trace)
+  #:use-module  (ice-9 debugging steps) 
+  #:use-module  (ice-9 debugging ice-9-debugger-extensions) 
+  #:use-module  (ice-9 readline))
+  #:export (	set-break!
+				set-trace!
+				set-trace-subtree)
+(define (set-break! proc)
+       (install-trap (make <procedure-trap>
+                       #:procedure proc
+                       #:behaviour debug-trap)))
+     
+(define (set-trace! proc)
+       (install-trap (make <procedure-trap>
+                       #:procedure proc
+                       #:behaviour (list trace-trap
+                                         trace-at-exit))))
+     
+(define (set-trace-subtree! proc)
+       (install-trap (make <procedure-trap>
+                       #:procedure proc
+                       #:behaviour (list trace-trap
+                                         trace-until-exit))))
+
diff --git a/scm/lily.scm b/scm/lily.scm
index fca7857..9a152ed 100644
--- a/scm/lily.scm
+++ b/scm/lily.scm
@@ -190,17 +190,17 @@ messages into errors.")
 					;(set-debug-cell-accesses! 1000)
 
 (use-modules (ice-9 regex)
-	     (ice-9 safe)
-	     (ice-9 format)
-	     (ice-9 rdelim)
-             (ice-9 optargs)
-	     (oop goops)
-	     (srfi srfi-1)
-	     (srfi srfi-13)
-	     (srfi srfi-14)
-	     (scm clip-region)
-	     (scm memory-trace)
-	     (scm coverage))
+              (ice-9 safe)
+              (ice-9 format)
+              (ice-9 rdelim)
+              (ice-9 optargs)
+              (oop goops)
+              (srfi srfi-1)
+              (srfi srfi-13)
+              (srfi srfi-14)
+              (scm clip-region)
+              (scm memory-trace)
+              (scm coverage))
 
 (define-public fancy-format
   format)
-- 
1.6.3.3


--------------070304000207010303000705--

---
----
Join the Frogs!


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/