Fixed some bugs in the double-stacktrace window; adjusted the repl to

be able to insert more with-stack-checkpoint calls in useful places;
adjust test suites to match the change in when the stacktrace icon
shows up
This commit is contained in:
Robby Findler 2011-11-06 08:17:10 -06:00
parent e1ce0a0d1e
commit bfa6b1d953
6 changed files with 1578 additions and 1593 deletions

View File

@ -21,6 +21,7 @@ profile todo:
"embedded-snip-utils.rkt"
"drsig.rkt"
"bindings-browser.rkt"
"stack-checkpoint.rkt"
net/sendurl
net/url
racket/match
@ -282,7 +283,7 @@ profile todo:
(send rep get-definitions-text)))])
(let* ([stack1 (or pre-stack '())]
[stack2 (if (exn? exn)
(map cdr (filter cdr (continuation-mark-set->context (exn-continuation-marks exn))))
(map cdr (filter cdr (cut-stack-at-checkpoint exn)))
'())]
[src-locs (cond
[(exn:srclocs? exn)
@ -638,9 +639,9 @@ profile todo:
(define (show-backtrace-window/edition-pairs/two error-text dis1 editions1 dis2 editions2 defs ints)
(reset-backtrace-window)
(when (mf-bday?)
(instantiate message% ()
(label (string-constant happy-birthday-matthias))
(parent (send current-backtrace-window get-area-container))))
(new message%
[label (string-constant happy-birthday-matthias)]
[parent (send current-backtrace-window get-area-container)]))
(define tab-panel
(if (and (pair? dis1) (pair? dis2))
(new tab-panel%
@ -652,24 +653,22 @@ profile todo:
(λ (l) (if (zero? (send tab-panel get-selection))
(list ec1)
(list ec2)))))])
(new panel% [parent (send current-backtrace-window get-area-container)])))
(define text1 (and (pair? dis1) (new (text:wide-snip-mixin text:hide-caret/selection%))))
(define ec1 (and (pair? dis1)
(new (canvas:color-mixin canvas:wide-snip%)
[parent tab-panel]
[editor text1])))
(define text2 (and (pair? dis2) (new (text:wide-snip-mixin text:hide-caret/selection%))))
(define ec2 (and (pair? dis2)
(new (canvas:color-mixin canvas:wide-snip%)
[parent tab-panel]
[editor text2])))
(when (pair? dis1)
(add-one-set-to-frame text1 ec1 error-text dis1 editions1 defs ints))
(when (pair? dis2)
(add-one-set-to-frame text2 ec2 error-text dis2 editions2 defs ints))
(new vertical-panel% [parent (send current-backtrace-window get-area-container)])))
(define ec1 (add-ec/text dis1 editions1 defs ints tab-panel error-text))
(define ec2 (add-ec/text dis2 editions2 defs ints tab-panel error-text))
(when (and (pair? dis1) (pair? dis2))
(send tab-panel change-children (λ (l) (list ec1)))))
(define (add-ec/text dis1 editions1 defs ints tab-panel error-text)
(cond
[(pair? dis1)
(define text1 (new (text:wide-snip-mixin text:hide-caret/selection%)))
(define ec1 (new (canvas:color-mixin canvas:wide-snip%)
[parent tab-panel]
[editor text1]))
(add-one-set-to-frame text1 ec1 error-text dis1 editions1 defs ints)
ec1]
[else #f]))
(define (add-one-set-to-frame text ec error-text dis editions defs ints)
(letrec ([di-vec (list->vector dis)]

View File

@ -29,6 +29,7 @@ TODO
browser/external
"drsig.rkt"
"local-member-names.rkt"
"stack-checkpoint.rkt"
;; the dynamic-require below loads this module,
;; so we make the dependency explicit here, even
@ -40,42 +41,6 @@ TODO
(define orig-output-port (current-output-port))
(define (oprintf . args) (apply fprintf orig-output-port args))
;; run a thunk, and if an exception is raised, make it possible to cut the
;; stack so that the surrounding context is hidden
(define checkpoints (make-weak-hasheq))
(define (call-with-stack-checkpoint thunk)
(define checkpoint #f)
(call-with-exception-handler
(λ (exn)
(when (and checkpoint ; just in case there's an exception before it's set
(not (hash-has-key? checkpoints exn)))
(hash-set! checkpoints exn checkpoint))
exn)
(lambda ()
(set! checkpoint (current-continuation-marks))
(thunk))))
;; returns the stack of the input exception, cutting off any tail that was
;; registered as a checkpoint
(define (cut-stack-at-checkpoint exn)
(define stack (continuation-mark-set->context (exn-continuation-marks exn)))
(define checkpoint
(cond [(hash-ref checkpoints exn #f) => continuation-mark-set->context]
[else #f]))
(if (not checkpoint)
stack
(let loop ([st stack]
[sl (length stack)]
[cp checkpoint]
[cl (length checkpoint)])
(cond [(sl . > . cl) (cons (car st) (loop (cdr st) (sub1 sl) cp cl))]
[(sl . < . cl) (loop st sl (cdr cp) (sub1 cl))]
[(equal? st cp) '()]
[else (loop st sl (cdr cp) (sub1 cl))]))))
(define-syntax-rule (with-stack-checkpoint expr)
(call-with-stack-checkpoint (lambda () expr)))
(define no-breaks-break-parameterization
(parameterize-break #f (current-break-parameterization)))
@ -164,37 +129,7 @@ TODO
;; the highlight must be set after the error message, because inserting into the text resets
;; the highlighting.
(define (drracket-error-display-handler msg exn)
(let* ([cut-stack (if (and (exn? exn)
(main-user-eventspace-thread?))
(cut-stack-at-checkpoint exn)
'())]
[srclocs-stack (filter values (map cdr cut-stack))]
[stack
(filter
values
(map (λ (srcloc)
(let ([source (srcloc-source srcloc)]
[pos (srcloc-position srcloc)]
[span (srcloc-span srcloc)])
(and source pos span
srcloc)))
srclocs-stack))]
[src-locs (if (exn:srclocs? exn)
((exn:srclocs-accessor exn) exn)
(if (null? stack)
'()
(list (car srclocs-stack))))])
;; for use in debugging the stack trace stuff
#;
(when (exn? exn)
(parameterize ([print-struct #t])
(for-each
(λ (frame) (printf " ~s\n" frame))
(continuation-mark-set->context (exn-continuation-marks exn)))
(printf "\n")))
(drracket:debug:error-display-handler/stacktrace msg exn stack)))
(drracket:debug:error-display-handler/stacktrace msg exn))
(define (main-user-eventspace-thread?)
(let ([rep (current-rep)])
@ -1114,17 +1049,38 @@ TODO
(let loop ()
(let ([sexp/syntax/eof (with-stack-checkpoint (get-sexp/syntax/eof))])
(unless (eof-object? sexp/syntax/eof)
(call-with-values
(λ ()
(call-with-continuation-prompt
(λ () (with-stack-checkpoint (eval-syntax sexp/syntax/eof)))
(default-continuation-prompt-tag)
(and complete-program?
(λ args
(abort-current-continuation
(default-continuation-prompt-tag))))))
(λ x (parameterize ([pretty-print-columns pretty-print-width])
(for-each (λ (x) ((current-print) x)) x))))
(define results
;; we duplicate the 'expand-syntax-to-top-form' dance that eval-syntax
;; does here, so that we can put 'with-stack-checkpoint's in to limit
;; the amount of DrRacket code we see in stacktraces
(let loop ([stx sexp/syntax/eof])
(define top-expanded (with-stack-checkpoint (expand-syntax-to-top-form stx)))
(syntax-case top-expanded (begin)
[(begin a1 . args)
(let lloop ([args (syntax->list #'(a1 . args))])
(cond
[(null? (cdr args))
(loop (car args))]
[else
(loop (car args))
(lloop (cdr args))]))]
[_
(let ([expanded (with-stack-checkpoint (expand-syntax top-expanded))])
(call-with-values
(λ ()
(call-with-continuation-prompt
(λ ()
(with-stack-checkpoint (eval-syntax expanded)))
(default-continuation-prompt-tag)
(λ args
(apply
abort-current-continuation
(default-continuation-prompt-tag)
args))))
list))])))
(parameterize ([pretty-print-columns pretty-print-width])
(for ([x (in-list results)])
((current-print) x)))
(loop)))))))
(default-continuation-prompt-tag)
(λ args (void)))

View File

@ -0,0 +1,39 @@
#lang racket/base
(provide cut-stack-at-checkpoint with-stack-checkpoint)
;; run a thunk, and if an exception is raised, make it possible to cut the
;; stack so that the surrounding context is hidden
(define checkpoints (make-weak-hasheq))
(define (call-with-stack-checkpoint thunk)
(define checkpoint #f)
(call-with-exception-handler
(λ (exn)
(when (and checkpoint ; just in case there's an exception before it's set
(not (hash-has-key? checkpoints exn)))
(hash-set! checkpoints exn checkpoint))
exn)
(lambda ()
(set! checkpoint (current-continuation-marks))
(thunk))))
;; returns the stack of the input exception, cutting off any tail that was
;; registered as a checkpoint
(define (cut-stack-at-checkpoint exn)
(define stack (continuation-mark-set->context (exn-continuation-marks exn)))
(define checkpoint
(cond [(hash-ref checkpoints exn #f) => continuation-mark-set->context]
[else #f]))
(if (not checkpoint)
stack
(let loop ([st stack]
[sl (length stack)]
[cp checkpoint]
[cl (length checkpoint)])
(cond [(sl . > . cl) (cons (car st) (loop (cdr st) (sub1 sl) cp cl))]
[(sl . < . cl) (loop st sl (cdr cp) (sub1 cl))]
[(equal? st cp) '()]
[else (loop st sl (cdr cp) (sub1 cl))]))))
(define-syntax-rule (with-stack-checkpoint expr)
(call-with-stack-checkpoint (lambda () expr)))

File diff suppressed because it is too large Load Diff

View File

@ -140,7 +140,7 @@
(require-for-syntax (file @in-here{module-lang-test-tmp2.rkt}))
(provide s)
(define-syntax (s stx) e))}
@t{(require m) s}
@t{(require 'm) s}
@rx{compile: bad syntax;
literal data is not allowed, because no #%datum syntax transformer
is bound in: 1$})
@ -157,7 +157,7 @@
(test @t{#lang racket
(eval 'cons)}
#f
@rx{. compile: unbound identifier \(and no #%top syntax transformer is bound\) in: cons})
@rx{compile: unbound identifier \(and no #%top syntax transformer is bound\) in: cons})
(test @t{(module m (file @in-here{module-lang-test-tmp1.rkt}) 1 2 3)}
@t{1} ;; just make sure no errors.
"1")

View File

@ -157,13 +157,12 @@ This produces an ACK message
void)
(mktest "(lambda ())"
("{stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-22x22.png} repl-test-tmp3.rkt:1:0: lambda: bad syntax in: (lambda ())"
"{stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-multi.png} {stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:0: lambda: bad syntax in: (lambda ())")
"{stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-22x22.png} repl-test-tmp3.rkt:1:0: lambda: bad syntax in: (lambda ())")
'definitions
#f
void
@ -171,13 +170,12 @@ This produces an ACK message
;; make sure only a single syntax error occurs when in nested begin situation
(mktest "(begin (lambda ()) (lambda ()))"
("{stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-22x22.png} repl-test-tmp3.rkt:1:7: lambda: bad syntax in: (lambda ())"
"{stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-multi.png} {stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:7: lambda: bad syntax in: (lambda ())")
"{stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-22x22.png} repl-test-tmp3.rkt:1:7: lambda: bad syntax in: (lambda ())")
'definitions
#f
void
@ -246,7 +244,6 @@ This produces an ACK message
void)
(mktest "(parameterize ([print-struct #t])(define-struct s (x) (make-inspector))(printf \"~s\\n\" (make-s 1)))"
("#(struct:s 1)"
"#(struct:s 1)"
"#(struct:s 1)"
@ -260,10 +257,9 @@ This produces an ACK message
;; top-level semantics test
(mktest "(define (f) (+ 1 1)) (define + -) (f)"
("define-values: cannot change constant variable: +"
"define-values: cannot change constant variable: +"
"define-values: cannot change constant variable: +"
#rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: define-values: cannot change constant variable: \\+"
#rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: define-values: cannot change constant variable: \\+"
"define-values: cannot change constant variable: +"
#rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: define-values: cannot change constant variable: \\+"
#rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: define-values: cannot change constant variable: \\+")
@ -273,7 +269,6 @@ This produces an ACK message
void)
(mktest "(begin (define-struct a ()) (define-struct (b a) ()))"
(""
""
""
@ -321,8 +316,8 @@ This produces an ACK message
"{stop-22x22.png} compile: bad syntax; literal data is not allowed, because no #%datum syntax transformer is bound in: 1"
"{stop-22x22.png} repl-test-tmp3.rkt:1:43: compile: bad syntax; literal data is not allowed, because no #%datum syntax transformer is bound in: 1"
"{stop-22x22.png} compile: bad syntax; literal data is not allowed, because no #%datum syntax transformer is bound in: 1"
"{stop-multi.png} {stop-22x22.png} compile: bad syntax; literal data is not allowed, because no #%datum syntax transformer is bound in: 1"
"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:43: compile: bad syntax; literal data is not allowed, because no #%datum syntax transformer is bound in: 1")
"{stop-22x22.png} compile: bad syntax; literal data is not allowed, because no #%datum syntax transformer is bound in: 1"
"{stop-22x22.png} repl-test-tmp3.rkt:1:43: compile: bad syntax; literal data is not allowed, because no #%datum syntax transformer is bound in: 1")
'definitions
#f
void
@ -385,13 +380,12 @@ This produces an ACK message
void)
(mktest " (eval '(lambda ()))"
("{stop-multi.png} lambda: bad syntax in: (lambda ())"
"{stop-multi.png} lambda: bad syntax in: (lambda ())"
"{stop-multi.png} lambda: bad syntax in: (lambda ())"
("lambda: bad syntax in: (lambda ())"
"lambda: bad syntax in: (lambda ())"
"{stop-multi.png} lambda: bad syntax in: (lambda ())"
"{stop-multi.png} lambda: bad syntax in: (lambda ())")
"lambda: bad syntax in: (lambda ())"
"lambda: bad syntax in: (lambda ())"
"lambda: bad syntax in: (lambda ())"
"lambda: bad syntax in: (lambda ())")
'interactions
#f
void
@ -494,8 +488,8 @@ This produces an ACK message
"{stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-22x22.png} repl-test-tmp3.rkt:1:4: lambda: bad syntax in: (lambda ())"
"1\n2\n{stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-multi.png} {stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:4: lambda: bad syntax in: (lambda ())")
"{stop-22x22.png} lambda: bad syntax in: (lambda ())"
"{stop-22x22.png} repl-test-tmp3.rkt:1:4: lambda: bad syntax in: (lambda ())")
'definitions
#f
void
@ -542,9 +536,9 @@ This produces an ACK message
("{stop-22x22.png} cond: expected a clause with a question and an answer, but found a clause with 4 parts in:\n 1\n 2\n 3\n 4"
"{stop-22x22.png} cond: expected a clause with a question and an answer, but found a clause with 4 parts in:\n 1\n 2\n 3\n 4"
"{stop-22x22.png} repl-test-tmp3.rkt:2:7: cond: expected a clause with a question and an answer, but found a clause with 4 parts in:\n 1\n 2\n 3\n 4"
"{stop-multi.png} {stop-22x22.png} cond: expected a clause with a question and an answer, but found a clause with 4 parts in:\n 1\n 2\n 3\n 4"
"{stop-multi.png} {stop-22x22.png} cond: expected a clause with a question and an answer, but found a clause with 4 parts in:\n 1\n 2\n 3\n 4"
"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:2:7: cond: expected a clause with a question and an answer, but found a clause with 4 parts in:\n 1\n 2\n 3\n 4")
"{stop-22x22.png} cond: expected a clause with a question and an answer, but found a clause with 4 parts in:\n 1\n 2\n 3\n 4"
"{stop-22x22.png} cond: expected a clause with a question and an answer, but found a clause with 4 parts in:\n 1\n 2\n 3\n 4"
"{stop-22x22.png} repl-test-tmp3.rkt:2:7: cond: expected a clause with a question and an answer, but found a clause with 4 parts in:\n 1\n 2\n 3\n 4")
'definitions
#f
void
@ -577,8 +571,8 @@ This produces an ACK message
"{stop-22x22.png} if: bad syntax in: if"
"{stop-22x22.png} repl-test-tmp3.rkt:2:0: if: bad syntax in: if"
"{stop-22x22.png} if: bad syntax in: if"
"{stop-multi.png} {stop-22x22.png} if: bad syntax in: if"
"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:2:0: if: bad syntax in: if")
"{stop-22x22.png} if: bad syntax in: if"
"{stop-22x22.png} repl-test-tmp3.rkt:2:0: if: bad syntax in: if")
'definitions
#f
void
@ -590,8 +584,8 @@ This produces an ACK message
"{stop-22x22.png} compile: unbound identifier (and no #%app syntax transformer is bound) in: #%top-interaction"
"{stop-22x22.png} repl-test-tmp3.rkt:2:0: compile: unbound identifier (and no #%app syntax transformer is bound) in: #%top-interaction"
"{stop-22x22.png} compile: unbound identifier (and no #%app syntax transformer is bound) in: #%top-interaction"
"{stop-multi.png} {stop-22x22.png} compile: unbound identifier (and no #%app syntax transformer is bound) in: #%top-interaction"
"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:2:0: compile: unbound identifier (and no #%app syntax transformer is bound) in: #%top-interaction")
"{stop-22x22.png} compile: unbound identifier (and no #%app syntax transformer is bound) in: #%top-interaction"
"{stop-22x22.png} repl-test-tmp3.rkt:2:0: compile: unbound identifier (and no #%app syntax transformer is bound) in: #%top-interaction")
'definitions
#f
void
@ -869,8 +863,8 @@ This produces an ACK message
"{stop-22x22.png} λ: bad syntax in: (λ ())"
"{stop-22x22.png} repl-test-tmp3.rkt:1:0: λ: bad syntax in: (λ ())"
"{stop-22x22.png} λ: bad syntax in: (λ ())"
"{stop-multi.png} {stop-22x22.png} λ: bad syntax in: (λ ())"
"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:0: λ: bad syntax in: (λ ())")
"{stop-22x22.png} λ: bad syntax in: (λ ())"
"{stop-22x22.png} repl-test-tmp3.rkt:1:0: λ: bad syntax in: (λ ())")
'definitions
#f
void
@ -998,7 +992,6 @@ This produces an ACK message
"(with-handlers ((void values)) (eval '(lambda ())))))\n"
"(lambda ()\n"
"(display (get-output-string p)))))\n")
("x in: (lambda ())"
"x in: (lambda ())"
"x in: (lambda ())"