racket/sandbox: add sandbox-propagate-exceptions

This commit is contained in:
Matthew Flatt 2012-05-25 18:34:41 -06:00
parent 263016f6f3
commit d6774d5d54
4 changed files with 38 additions and 7 deletions

View File

@ -32,6 +32,7 @@
sandbox-memory-limit
sandbox-eval-limits
sandbox-eval-handlers
sandbox-propagate-exceptions
call-with-trusted-sandbox-configuration
evaluator-alive?
kill-evaluator
@ -78,6 +79,7 @@
(define sandbox-eval-limits (make-parameter '(30 20))) ; 30sec, 20mb
(define sandbox-propagate-breaks (make-parameter #t))
(define sandbox-coverage-enabled (make-parameter #f))
(define sandbox-propagate-exceptions (make-parameter #t))
(define (call-with-trusted-sandbox-configuration thunk)
(parameterize ([sandbox-propagate-breaks #t]
@ -679,6 +681,7 @@
(define user-cust (make-custodian memory-cust))
(define user-cust-box (make-custodian-box user-cust #t))
(define coverage? (sandbox-coverage-enabled))
(define propagate-exceptions? (sandbox-propagate-exceptions))
(define uncovered #f)
(define default-coverage-source-filter #f)
(define input-ch (make-channel))
@ -759,7 +762,13 @@
(when (eof-object? expr)
(terminated! 'eof) (channel-put result-ch expr) (user-kill))
(with-handlers ([void (lambda (exn)
(channel-put result-ch (cons 'exn exn)))])
(if propagate-exceptions?
(channel-put result-ch (cons 'exn exn))
(begin
(call-with-continuation-prompt
(lambda ()
(raise exn)))
(channel-put result-ch (cons 'vals (list (void)))))))])
(define run
(if (evaluator-message? expr)
(case (evaluator-message-msg expr)

View File

@ -232,13 +232,14 @@ sandboxed code, for example:
]
An error will be signaled in such cases.
Evaluation can also be instrumented to track coverage information when
@racket[sandbox-coverage-enabled] is set. Exceptions (both syntax and
If the value of @racket[sandbox-propagate-exceptions] is true (the
default) when the sandbox is created, then exceptions (both syntax and
run-time) are propagated as usual to the caller of the evaluation
function (i.e., catch it with @racket[with-handlers]). However, note
that a sandboxed evaluator is convenient for testing, since all
exceptions happen in the same way, so you don't need special code to
catch syntax errors.
function (i.e., catch them with @racket[with-handlers]). If the value
of @racket[sandbox-propagate-exceptions] is @racket[#f] when the
sandbox is created, then uncaught exceptions in a sandbox evaluation
cause the error to be printed to the sandbox's error port, and the
caller of the evaluation receives @|void-const|.
Finally, the fact that a sandboxed evaluator accept syntax objects
makes it usable as the value for @racket[current-eval], which means
@ -456,6 +457,17 @@ the evaluator (or the break is lost if the evaluator is not used
further). The default is @racket[#t].}
@defboolparam[sandbox-propagate-exceptions propagate?]{
A parameter that controls how uncaught exceptions during a sandbox
evaluation are treated. When the parameter value is @racket[#t],
then the exception is propagated to the caller of sandbox.
When the parameter value is @racket[#f], the exception message
is printed to the sandbox's error port, and the caller of the
sandbox receives @|void-const| for the evaluation. The default
is @racket[#t].}
@defparam[sandbox-namespace-specs spec (cons/c (-> namespace?)
(listof module-path?))]{

View File

@ -172,6 +172,15 @@
(make-bytes 500000)))))
=err> "out of memor(?:y)"))
;; check non-propagation of errors
--top--
(parameterize ([sandbox-propagate-exceptions #f]
[sandbox-error-output 'string])
(make-base-evaluator! '(void)))
--eval--
(/ 0) => (void)
--top--
(regexp-match #rx"^.*?\n" (get-error-output ev)) => '("/: division by zero\n")
;; i/o
--top--
(parameterize ([sandbox-input "3\n"]

View File

@ -3,6 +3,7 @@ Changed the format of error messages
Added raise-argument-error, raise-result-error,
raise-arguments-error, raise-range-error
racket/contract: added procedure-arity-includes/c
racket/sandbox: added sandbox-propagate-exceptions
Version 5.3.0.8
Required modules are instantiated in the order that they are required