Steps toward a richer debug facility by horribly abusing the runtime.

This commit is contained in:
Tony Garnock-Jones 2013-04-23 16:26:10 -04:00
parent 6fd0ad0451
commit 71ee3ac0b7
2 changed files with 47 additions and 40 deletions

View File

@ -9,13 +9,12 @@
(require "../quasiqueue.rkt") (require "../quasiqueue.rkt")
(require/typed "gui.rkt" (require/typed "gui.rkt"
[opaque AnyState any-state?] [open-debugger (Any -> Debugger)])
[open-debugger (Any -> (Values (AnyState -> Void) (-> Void)))])
(define-type Debugger (All (S) (S -> S)))
(provide debug) (provide debug)
(struct: debugger ([out : (AnyState -> Void)] [in : (-> Void)]))
(: debug : (All (ParentState) (Spawn ParentState) -> (Spawn ParentState))) (: debug : (All (ParentState) (Spawn ParentState) -> (Spawn ParentState)))
(define (debug spawn-child) (define (debug spawn-child)
(match-define (core:spawn child-spec parent-k debug-name) spawn-child) (match-define (core:spawn child-spec parent-k debug-name) spawn-child)
@ -27,9 +26,7 @@
(define (wrapped-cotransition k) (define (wrapped-cotransition k)
(: receiver : (All (S) (Transition S) -> R)) (: receiver : (All (S) (Transition S) -> R))
(define (receiver child-transition) (define (receiver child-transition)
(define-values (send-to-debugger! receive-from-debugger!) (define d (open-debugger debug-name))
(open-debugger debug-name))
(define d (debugger send-to-debugger! receive-from-debugger!))
((inst k S) (wrap-transition d child-transition))) ((inst k S) (wrap-transition d child-transition)))
((inst original-cotransition R) receiver)) ((inst original-cotransition R) receiver))
wrapped-cotransition)) wrapped-cotransition))
@ -37,12 +34,11 @@
(list 'debug debug-name))) (list 'debug debug-name)))
(: wrap-transition : (All (ChildState) (: wrap-transition : (All (ChildState)
debugger Debugger
(Transition ChildState) (Transition ChildState)
-> (Transition ChildState))) -> (Transition ChildState)))
(define (wrap-transition d child-transition) (define (wrap-transition d child-transition0)
((debugger-out d) (cast child-transition AnyState)) (define child-transition ((inst d (Transition ChildState)) child-transition0))
((debugger-in d))
(match-define (core:transition child-state child-actions) child-transition) (match-define (core:transition child-state child-actions) child-transition)
(core:transition child-state ((inst action-tree-map ChildState) (core:transition child-state ((inst action-tree-map ChildState)
(wrap-action d) (wrap-action d)
@ -57,7 +53,7 @@
(quasiqueue->list (action-tree->quasiqueue actions)))) (quasiqueue->list (action-tree->quasiqueue actions))))
(: wrap-action : (All (ChildState) (: wrap-action : (All (ChildState)
debugger Debugger
-> ((Action ChildState) -> (Action ChildState)))) -> ((Action ChildState) -> (Action ChildState))))
(define ((wrap-action d) action) (define ((wrap-action d) action)
(cond (cond
@ -70,7 +66,7 @@
(: wrap-preaction : (All (ChildState) (: wrap-preaction : (All (ChildState)
Boolean Boolean
debugger Debugger
(PreAction ChildState) (PreAction ChildState)
-> (PreAction ChildState))) -> (PreAction ChildState)))
(define (wrap-preaction meta? d preaction) (define (wrap-preaction meta? d preaction)
@ -87,7 +83,7 @@
preaction])) preaction]))
(: wrap-interruptk : (All (ChildState) (: wrap-interruptk : (All (ChildState)
debugger Debugger
(InterruptK ChildState) (InterruptK ChildState)
-> (InterruptK ChildState))) -> (InterruptK ChildState)))
(define (wrap-interruptk d ik) (define (wrap-interruptk d ik)
@ -95,7 +91,7 @@
(wrap-transition d (ik state)))) (wrap-transition d (ik state))))
(: wrap-spawnk : (All (ChildState) (: wrap-spawnk : (All (ChildState)
debugger Debugger
(Option (PID -> (InterruptK ChildState))) (Option (PID -> (InterruptK ChildState)))
-> (Option (PID -> (InterruptK ChildState))))) -> (Option (PID -> (InterruptK ChildState)))))
(define (wrap-spawnk d maybe-k) (define (wrap-spawnk d maybe-k)
@ -104,10 +100,10 @@
(: wrap-handler : (All (ChildState) (: wrap-handler : (All (ChildState)
Boolean Boolean
debugger Debugger
(Handler ChildState) (Handler ChildState)
-> (Handler ChildState))) -> (Handler ChildState)))
(define (wrap-handler meta? d h) (define (wrap-handler meta?0 d h)
(lambda (event) (lambda (event0)
((debugger-out d) (cast (cons meta? event) AnyState)) (match-define (cons meta? event) ((inst d (Pairof Boolean EndpointEvent)) (cons meta?0 event0)))
(wrap-interruptk d (h event)))) (wrap-interruptk d (h event))))

View File

@ -15,12 +15,13 @@
(require images/icons/misc) (require images/icons/misc)
(require images/icons/style) (require images/icons/style)
(require data/queue)
(require racket/pretty) (require racket/pretty)
(require (prefix-in core: "../types.rkt")) (require (prefix-in core: "../types.rkt"))
(provide any-state? (provide open-debugger)
open-debugger)
;; Frame ;; Frame
;; Toolbar ;; Toolbar
@ -45,18 +46,28 @@
(struct historical-moment (alive? state endpoints) #:transparent) (struct historical-moment (alive? state endpoints) #:transparent)
(define (any-state? x) #t)
(define (open-debugger name) (define (open-debugger name)
(define to-debugger (make-channel)) (define to-debugger (make-channel))
(define from-debugger (make-semaphore 0)) (define from-debugger (make-channel))
(parameterize ((current-eventspace (make-eventspace))) (parameterize ((current-eventspace (make-eventspace)))
(new debugger% (new debugger%
[name name] [name name]
[from-vm to-debugger] [from-vm to-debugger]
[to-vm from-debugger])) [to-vm from-debugger]))
(values (lambda (t) (channel-put to-debugger t)) (wrap/unwrapper
(lambda () (semaphore-wait from-debugger)))) (lambda (v)
(channel-put to-debugger v)
(channel-get from-debugger))))
;; This is utterly vile.
(define (wrap/unwrapper thunk)
(local-require racket/unsafe/ops)
(lambda (wrapped-val)
;; (pretty-print `(wrapped-val ,wrapped-val))
(define inner (unsafe-struct-ref wrapped-val 0))
;; (pretty-print `(inner ,inner))
(unsafe-struct-set! wrapped-val 0 (thunk inner))
wrapped-val))
(define debugger% (define debugger%
(class object% (class object%
@ -67,7 +78,13 @@
(define mutex (make-semaphore 1)) (define mutex (make-semaphore 1))
(define stepping? #t) (define stepping? #t)
(define waiting? #f) (define k-queue (make-queue))
(define (reply-to-vm reply)
(call-with-semaphore mutex
(lambda () (if stepping?
(channel-put to-vm reply)
(enqueue! k-queue reply)))))
(define current-historical-moment (historical-moment #t (void) '())) (define current-historical-moment (historical-moment #t (void) '()))
(define displayed-endpoints '()) (define displayed-endpoints '())
@ -150,9 +167,8 @@
mutex mutex
(lambda () (lambda ()
(set! stepping? #t) (set! stepping? #t)
(when waiting? (when (non-empty-queue? k-queue)
(set! waiting? #f) (channel-put to-vm (dequeue! k-queue))))))))
(semaphore-post to-vm)))))))
(toolbar-spacer) (toolbar-spacer)
(define step-button (define step-button
(toolbar-button (step-icon #:color run-icon-color) (toolbar-button (step-icon #:color run-icon-color)
@ -160,9 +176,8 @@
(call-with-semaphore (call-with-semaphore
mutex mutex
(lambda () (lambda ()
(when waiting? (when (non-empty-queue? k-queue)
(set! waiting? #f) (channel-put to-vm (dequeue! k-queue))))))))
(semaphore-post to-vm)))))))
(send play-button enable #f) (send play-button enable #f)
(send step-button enable #f) (send step-button enable #f)
@ -335,12 +350,7 @@
[else (define-values (type detail) (format-action a)) [else (define-values (type detail) (format-action a))
(apply-action! a) (apply-action! a)
(record-event! now "Act" type detail)])) (record-event! now "Act" type detail)]))
(call-with-semaphore (reply-to-vm x)]
mutex
(lambda ()
(if stepping?
(semaphore-post to-vm)
(set! waiting? #t))))]
[(cons meta? e) [(cons meta? e)
(define prefix (if meta? "Meta" "")) (define prefix (if meta? "Meta" ""))
(match e (match e
@ -350,7 +360,8 @@
(record-event! now "Evt" (string-append prefix "Absence") (record-event! now "Evt" (string-append prefix "Absence")
(string-append (format-role role) " " (~v reason)))] (string-append (format-role role) " " (~v reason)))]
[(core:message-event _ message) [(core:message-event _ message)
(record-event! now "Evt" (string-append prefix "Recv") (~v message))])])) (record-event! now "Evt" (string-append prefix "Recv") (~v message))])
(reply-to-vm x)]))
(define (controller-thread-loop) (define (controller-thread-loop)
(sync (handle-evt from-vm (sync (handle-evt from-vm