debugger.scm 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. ;;;; Guile Debugger
  2. ;;; Copyright (C) 1999, 2001, 2002, 2006 Free Software Foundation, Inc.
  3. ;;;
  4. ;; This library is free software; you can redistribute it and/or
  5. ;; modify it under the terms of the GNU Lesser General Public
  6. ;; License as published by the Free Software Foundation; either
  7. ;; version 2.1 of the License, or (at your option) any later version.
  8. ;;
  9. ;; This library is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ;; Lesser General Public License for more details.
  13. ;;
  14. ;; You should have received a copy of the GNU Lesser General Public
  15. ;; License along with this library; if not, write to the Free Software
  16. ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. (define-module (ice-9 debugger)
  18. #:use-module (ice-9 debugger command-loop)
  19. #:use-module (ice-9 debugger state)
  20. #:use-module (ice-9 debugger utils)
  21. #:use-module (ice-9 format)
  22. #:export (debug-stack
  23. debug
  24. debug-last-error
  25. debugger-error
  26. debugger-quit
  27. debugger-input-port
  28. debugger-output-port
  29. debug-on-error)
  30. #:no-backtrace)
  31. ;;; The old (ice-9 debugger) has been factored into its constituent
  32. ;;; parts:
  33. ;;;
  34. ;;; (ice-9 debugger) - public interface to all of the following
  35. ;;;
  36. ;;; (... commands) - procedures implementing the guts of the commands
  37. ;;; provided by the interactive debugger
  38. ;;;
  39. ;;; (... command-loop) - binding these commands into the interactive
  40. ;;; debugger command loop
  41. ;;;
  42. ;;; (... state) - implementation of an object that tracks current
  43. ;;; debugger state
  44. ;;;
  45. ;;; (... utils) - utilities for printing out frame and stack
  46. ;;; information in various formats
  47. ;;;
  48. ;;; The division between (... commands) and (... command-loop) exists
  49. ;;; because I (NJ) have another generic command loop implementation
  50. ;;; under development, and I want to be able to switch easily between
  51. ;;; that and the command loop implementation here. Thus the
  52. ;;; procedures in this file delegate to a debugger command loop
  53. ;;; implementation via the `debugger-command-loop-*' interface. The
  54. ;;; (ice-9 debugger command-loop) implementation can be replaced by
  55. ;;; any other that implements the `debugger-command-loop-*' interface
  56. ;;; simply by changing the relevant #:use-module line above.
  57. ;;;
  58. ;;; - Neil Jerram <neil@ossau.uklinux.net> 2002-10-26, updated 2005-07-09
  59. (define *not-yet-introduced* #t)
  60. (define (debug-stack stack . flags)
  61. "Invoke the Guile debugger to explore the specified @var{stack}.
  62. @var{flags}, if present, are keywords indicating characteristics of
  63. the debugging session: the valid keywords are as follows.
  64. @table @code
  65. @item #:continuable
  66. Indicates that the debugger is being invoked from a context (such as
  67. an evaluator trap handler) where it is possible to return from the
  68. debugger and continue normal code execution. This enables the
  69. @dfn{continuing execution} commands, for example @code{continue} and
  70. @code{step}.
  71. @item #:with-introduction
  72. Indicates that the debugger should display an introductory message.
  73. @end table"
  74. (start-stack 'debugger
  75. (let ((state (apply make-state stack 0 flags)))
  76. (with-input-from-port (debugger-input-port)
  77. (lambda ()
  78. (with-output-to-port (debugger-output-port)
  79. (lambda ()
  80. (if (or *not-yet-introduced*
  81. (memq #:with-introduction flags))
  82. (let ((ssize (stack-length stack)))
  83. (display "This is the Guile debugger -- for help, type `help'.\n")
  84. (set! *not-yet-introduced* #f)
  85. (if (= ssize 1)
  86. (display "There is 1 frame on the stack.\n\n")
  87. (format #t "There are ~A frames on the stack.\n\n" ssize))))
  88. (write-state-short state)
  89. (debugger-command-loop state))))))))
  90. (define (debug)
  91. "Invoke the Guile debugger to explore the context of the last error."
  92. (let ((stack (fluid-ref the-last-stack)))
  93. (if stack
  94. (debug-stack stack)
  95. (display "Nothing to debug.\n"))))
  96. (define debug-last-error debug)
  97. (define (debugger-error message)
  98. "Signal a debugger usage error with message @var{message}."
  99. (debugger-command-loop-error message))
  100. (define (debugger-quit)
  101. "Exit the debugger."
  102. (debugger-command-loop-quit))
  103. ;;; {Debugger Input and Output Ports}
  104. (define debugger-input-port
  105. (let ((input-port (current-input-port)))
  106. (make-procedure-with-setter
  107. (lambda () input-port)
  108. (lambda (port) (set! input-port port)))))
  109. (define debugger-output-port
  110. (let ((output-port (current-output-port)))
  111. (make-procedure-with-setter
  112. (lambda () output-port)
  113. (lambda (port) (set! output-port port)))))
  114. ;;; {Debug on Error}
  115. (define (debug-on-error syms)
  116. "Enable or disable debug on error."
  117. (set! lazy-handler-dispatch
  118. (if syms
  119. (lambda (key . args)
  120. (if (memq key syms)
  121. (begin
  122. (debug-stack (make-stack #t lazy-handler-dispatch)
  123. #:with-introduction
  124. #:continuable)
  125. (throw 'abort key)))
  126. (apply default-lazy-handler key args))
  127. default-lazy-handler)))
  128. ;;; (ice-9 debugger) ends here.