Errors remember the original thread
parent
a5503782d7
commit
ed4506c0b0
|
@ -367,7 +367,7 @@ TUPLE: callback-context ;
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
: do-callback ( quot token -- )
|
: do-callback ( quot token -- )
|
||||||
init-error-handler
|
init-catchstack
|
||||||
dup 2 setenv
|
dup 2 setenv
|
||||||
slip
|
slip
|
||||||
wait-to-return ; inline
|
wait-to-return ; inline
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
! Copyright (C) 2004, 2007 Slava Pestov.
|
! Copyright (C) 2004, 2008 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
IN: bootstrap.stage1
|
IN: bootstrap.stage1
|
||||||
USING: arrays debugger generic hashtables io assocs
|
USING: arrays debugger generic hashtables io assocs
|
||||||
kernel.private kernel math memory namespaces parser
|
kernel.private kernel math memory namespaces parser
|
||||||
prettyprint sequences vectors words system splitting
|
prettyprint sequences vectors words system splitting
|
||||||
init io.files bootstrap.image bootstrap.image.private vocabs
|
init io.files bootstrap.image bootstrap.image.private vocabs
|
||||||
vocabs.loader system ;
|
vocabs.loader system debugger continuations ;
|
||||||
|
|
||||||
{ "resource:core" } vocab-roots set
|
{ "resource:core" } vocab-roots set
|
||||||
|
|
||||||
|
@ -40,7 +40,14 @@ vocabs.loader system ;
|
||||||
[
|
[
|
||||||
"resource:core/bootstrap/stage2.factor"
|
"resource:core/bootstrap/stage2.factor"
|
||||||
dup resource-exists? [
|
dup resource-exists? [
|
||||||
run-file
|
[ run-file ]
|
||||||
|
[
|
||||||
|
:c
|
||||||
|
dup print-error flush
|
||||||
|
"listener" vocab
|
||||||
|
[ restarts. vocab-main execute ]
|
||||||
|
[ die ] if*
|
||||||
|
] recover
|
||||||
] [
|
] [
|
||||||
"Cannot find " write write "." print
|
"Cannot find " write write "." print
|
||||||
"Please move " write image write " to the same directory as the Factor sources," print
|
"Please move " write image write " to the same directory as the Factor sources," print
|
||||||
|
|
|
@ -51,7 +51,7 @@ SYMBOL: bootstrap-time
|
||||||
! Wrap everything in a catch which starts a listener so
|
! Wrap everything in a catch which starts a listener so
|
||||||
! you can see what went wrong, instead of dealing with a
|
! you can see what went wrong, instead of dealing with a
|
||||||
! fep
|
! fep
|
||||||
[
|
|
||||||
! We time bootstrap
|
! We time bootstrap
|
||||||
millis >r
|
millis >r
|
||||||
|
|
||||||
|
@ -108,9 +108,3 @@ SYMBOL: bootstrap-time
|
||||||
|
|
||||||
"output-image" get resource-path save-image-and-exit
|
"output-image" get resource-path save-image-and-exit
|
||||||
] if
|
] if
|
||||||
] [
|
|
||||||
:c
|
|
||||||
print-error restarts.
|
|
||||||
"listener" vocab-main execute
|
|
||||||
1 exit
|
|
||||||
] recover
|
|
||||||
|
|
|
@ -193,6 +193,3 @@ HELP: save-error
|
||||||
{ $values { "error" "an error" } }
|
{ $values { "error" "an error" } }
|
||||||
{ $description "Called by the error handler to set the " { $link error } " and " { $link restarts } " global variables after an error was thrown." }
|
{ $description "Called by the error handler to set the " { $link error } " and " { $link restarts } " global variables after an error was thrown." }
|
||||||
$low-level-note ;
|
$low-level-note ;
|
||||||
|
|
||||||
HELP: init-error-handler
|
|
||||||
{ $description "Called on startup to initialize the catch stack and set a pair of hooks which allow the Factor VM to signal errors to library code." } ;
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ IN: continuations
|
||||||
|
|
||||||
SYMBOL: error
|
SYMBOL: error
|
||||||
SYMBOL: error-continuation
|
SYMBOL: error-continuation
|
||||||
|
SYMBOL: error-thread
|
||||||
SYMBOL: restarts
|
SYMBOL: restarts
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
@ -24,6 +25,8 @@ SYMBOL: restarts
|
||||||
#! with a declaration.
|
#! with a declaration.
|
||||||
f { object } declare ;
|
f { object } declare ;
|
||||||
|
|
||||||
|
: init-catchstack V{ } clone 1 setenv ;
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
: catchstack ( -- catchstack ) catchstack* clone ; inline
|
: catchstack ( -- catchstack ) catchstack* clone ; inline
|
||||||
|
@ -169,17 +172,3 @@ M: condition compute-restarts
|
||||||
condition-continuation
|
condition-continuation
|
||||||
[ <restart> ] curry { } assoc>map
|
[ <restart> ] curry { } assoc>map
|
||||||
append ;
|
append ;
|
||||||
|
|
||||||
<PRIVATE
|
|
||||||
|
|
||||||
: init-error-handler ( -- )
|
|
||||||
V{ } clone set-catchstack
|
|
||||||
! VM calls on error
|
|
||||||
[
|
|
||||||
continuation error-continuation set-global rethrow
|
|
||||||
] 5 setenv
|
|
||||||
! VM adds this to kernel errors, so that user-space
|
|
||||||
! can identify them
|
|
||||||
"kernel-error" 6 setenv ;
|
|
||||||
|
|
||||||
PRIVATE>
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: alien arrays generic generic.math help.markup help.syntax
|
USING: alien arrays generic generic.math help.markup help.syntax
|
||||||
kernel math memory strings sbufs vectors io io.files classes
|
kernel math memory strings sbufs vectors io io.files classes
|
||||||
help generic.standard continuations system ;
|
help generic.standard continuations system debugger.private ;
|
||||||
IN: debugger
|
IN: debugger
|
||||||
|
|
||||||
ARTICLE: "errors-assert" "Assertions"
|
ARTICLE: "errors-assert" "Assertions"
|
||||||
|
@ -80,9 +80,6 @@ HELP: print-error
|
||||||
HELP: restarts.
|
HELP: restarts.
|
||||||
{ $description "Print a list of restarts for the most recently thrown error to the " { $link stdio } " stream." } ;
|
{ $description "Print a list of restarts for the most recently thrown error to the " { $link stdio } " stream." } ;
|
||||||
|
|
||||||
HELP: debug-help
|
|
||||||
{ $description "Print a synopsis of useful debugger words." } ;
|
|
||||||
|
|
||||||
HELP: error-hook
|
HELP: error-hook
|
||||||
{ $var-description "A quotation with stack effect " { $snippet "( error -- )" } " which is used by " { $link try } " to report the error to the user." }
|
{ $var-description "A quotation with stack effect " { $snippet "( error -- )" } " which is used by " { $link try } " to report the error to the user." }
|
||||||
{ $examples "The default value prints the error with " { $link print-error } ", followed by a list of restarts and a help message. The graphical listener sets this variable to display a popup instead." } ;
|
{ $examples "The default value prints the error with " { $link print-error } ", followed by a list of restarts and a help message. The graphical listener sets this variable to display a popup instead." } ;
|
||||||
|
@ -169,3 +166,6 @@ HELP: depth
|
||||||
HELP: assert-depth
|
HELP: assert-depth
|
||||||
{ $values { "quot" "a quotation" } }
|
{ $values { "quot" "a quotation" } }
|
||||||
{ $description "Runs a quotation. Throws an error if the total number of elements on the stack is not the same before and after the quotation runs." } ;
|
{ $description "Runs a quotation. Throws an error if the total number of elements on the stack is not the same before and after the quotation runs." } ;
|
||||||
|
|
||||||
|
HELP: init-debugger
|
||||||
|
{ $description "Called on startup to set a pair of hooks which allow the " { $link throw } " word to function." } ;
|
||||||
|
|
|
@ -5,7 +5,8 @@ math namespaces prettyprint sequences assocs sequences.private
|
||||||
strings io.styles vectors words system splitting math.parser
|
strings io.styles vectors words system splitting math.parser
|
||||||
tuples continuations continuations.private combinators
|
tuples continuations continuations.private combinators
|
||||||
generic.math io.streams.duplex classes compiler.units
|
generic.math io.streams.duplex classes compiler.units
|
||||||
generic.standard vocabs ;
|
generic.standard vocabs threads threads.private init
|
||||||
|
kernel.private ;
|
||||||
IN: debugger
|
IN: debugger
|
||||||
|
|
||||||
GENERIC: error. ( error -- )
|
GENERIC: error. ( error -- )
|
||||||
|
@ -57,27 +58,30 @@ M: string error. print ;
|
||||||
dup length [ restart. ] 2each
|
dup length [ restart. ] 2each
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
: debug-help ( -- )
|
|
||||||
nl
|
|
||||||
"Debugger commands:" print
|
|
||||||
nl
|
|
||||||
":help - documentation for this error" print
|
|
||||||
":s - data stack at exception time" print
|
|
||||||
":r - retain stack at exception time" print
|
|
||||||
":c - call stack at exception time" print
|
|
||||||
":edit - jump to source location (parse errors only)" print
|
|
||||||
|
|
||||||
":get ( var -- value ) accesses variables at time of the error" print
|
|
||||||
flush ;
|
|
||||||
|
|
||||||
: print-error ( error -- )
|
: print-error ( error -- )
|
||||||
[ error. flush ] curry
|
[ error. flush ] curry
|
||||||
[ global [ "Error in print-error!" print drop ] bind ]
|
[ global [ "Error in print-error!" print drop ] bind ]
|
||||||
recover ;
|
recover ;
|
||||||
|
|
||||||
|
: error-in-thread. ( -- )
|
||||||
|
error-thread get-global
|
||||||
|
"Error in thread " write
|
||||||
|
[
|
||||||
|
dup thread-id #
|
||||||
|
" (" % dup thread-name %
|
||||||
|
", " % dup thread-quot unparse-short % ")" %
|
||||||
|
] "" make
|
||||||
|
swap write-object ":" print nl ;
|
||||||
|
|
||||||
SYMBOL: error-hook
|
SYMBOL: error-hook
|
||||||
|
|
||||||
[ print-error restarts. debug-help ] error-hook set-global
|
[
|
||||||
|
error-in-thread.
|
||||||
|
print-error
|
||||||
|
restarts.
|
||||||
|
nl
|
||||||
|
"Type :help for debugging help." print flush
|
||||||
|
] error-hook set-global
|
||||||
|
|
||||||
: try ( quot -- )
|
: try ( quot -- )
|
||||||
[ error-hook get call ] recover ;
|
[ error-hook get call ] recover ;
|
||||||
|
@ -260,3 +264,31 @@ M: no-compilation-unit error.
|
||||||
|
|
||||||
M: no-vocab summary
|
M: no-vocab summary
|
||||||
drop "Vocabulary does not exist" ;
|
drop "Vocabulary does not exist" ;
|
||||||
|
|
||||||
|
! Hooks
|
||||||
|
M: thread error-in-thread ( error thread -- )
|
||||||
|
initial-thread get-global eq? [
|
||||||
|
die drop
|
||||||
|
] [
|
||||||
|
global [
|
||||||
|
error-in-thread. print-error flush
|
||||||
|
] bind
|
||||||
|
] if ;
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
: init-debugger ( -- )
|
||||||
|
V{ } clone set-catchstack
|
||||||
|
! VM calls on error
|
||||||
|
[
|
||||||
|
self error-thread set-global
|
||||||
|
continuation error-continuation set-global
|
||||||
|
rethrow
|
||||||
|
] 5 setenv
|
||||||
|
! VM adds this to kernel errors, so that user-space
|
||||||
|
! can identify them
|
||||||
|
"kernel-error" 6 setenv ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
[ init-debugger ] "debugger" add-init-hook
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
IN: temporary
|
||||||
|
USING: init namespaces sequences math tools.test kernel ;
|
||||||
|
|
||||||
|
[ t ] [
|
||||||
|
init-hooks get [ first "libc" = ] find drop
|
||||||
|
init-hooks get [ first "io.backend" = ] find drop <
|
||||||
|
] unit-test
|
|
@ -15,7 +15,7 @@ init-hooks global [ drop V{ } clone ] cache drop
|
||||||
dup init-hooks get at [ over call ] unless
|
dup init-hooks get at [ over call ] unless
|
||||||
init-hooks get set-at ;
|
init-hooks get set-at ;
|
||||||
|
|
||||||
: boot ( -- ) init-namespaces init-error-handler ;
|
: boot ( -- ) init-namespaces init-catchstack ;
|
||||||
|
|
||||||
: boot-quot ( -- quot ) 20 getenv ;
|
: boot-quot ( -- quot ) 20 getenv ;
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ M: realloc-error summary drop "Memory reallocation failed" ;
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
[ H{ } clone mallocs set-global ] "mallocs" add-init-hook
|
[ H{ } clone mallocs set-global ] "libc" add-init-hook
|
||||||
|
|
||||||
: add-malloc ( alien -- )
|
: add-malloc ( alien -- )
|
||||||
dup mallocs get-global set-at ;
|
dup mallocs get-global set-at ;
|
||||||
|
|
|
@ -429,7 +429,7 @@ HELP: collect
|
||||||
|
|
||||||
HELP: each
|
HELP: each
|
||||||
{ $values { "seq" sequence } { "quot" "a quotation with stack effect " { $snippet "( elt -- )" } } }
|
{ $values { "seq" sequence } { "quot" "a quotation with stack effect " { $snippet "( elt -- )" } } }
|
||||||
{ $description "Applies the quotation to each element of the sequence in turn." } ;
|
{ $description "Applies the quotation to each element of the sequence in order." } ;
|
||||||
|
|
||||||
HELP: reduce
|
HELP: reduce
|
||||||
{ $values { "seq" sequence } { "identity" object } { "quot" "a quotation with stack effect " { $snippet "( prev elt -- next )" } } { "result" "the final result" } }
|
{ $values { "seq" sequence } { "identity" object } { "quot" "a quotation with stack effect " { $snippet "( prev elt -- next )" } } { "result" "the final result" } }
|
||||||
|
@ -447,7 +447,7 @@ HELP: accumulate
|
||||||
|
|
||||||
HELP: map
|
HELP: map
|
||||||
{ $values { "seq" sequence } { "quot" "a quotation with stack effect " { $snippet "( old -- new )" } } { "newseq" "a new sequence" } }
|
{ $values { "seq" sequence } { "quot" "a quotation with stack effect " { $snippet "( old -- new )" } } { "newseq" "a new sequence" } }
|
||||||
{ $description "Applies the quotation to each element yielding a new element. The new elements are collected into a sequence of the same class as the input sequence." } ;
|
{ $description "Applies the quotation to each element of the sequence in order. The new elements are collected into a sequence of the same class as the input sequence." } ;
|
||||||
|
|
||||||
HELP: change-nth
|
HELP: change-nth
|
||||||
{ $values { "i" "a non-negative integer" } { "seq" "a mutable sequence" } { "quot" "a quotation with stack effect " { $snippet "( elt -- newelt )" } } }
|
{ $values { "i" "a non-negative integer" } { "seq" "a mutable sequence" } { "quot" "a quotation with stack effect " { $snippet "( elt -- newelt )" } } }
|
||||||
|
|
|
@ -4,13 +4,12 @@
|
||||||
IN: threads
|
IN: threads
|
||||||
USING: arrays hashtables heaps kernel kernel.private math
|
USING: arrays hashtables heaps kernel kernel.private math
|
||||||
namespaces sequences vectors continuations continuations.private
|
namespaces sequences vectors continuations continuations.private
|
||||||
dlists assocs system combinators debugger prettyprint io init
|
dlists assocs system combinators init boxes ;
|
||||||
boxes ;
|
|
||||||
|
|
||||||
SYMBOL: initial-thread
|
SYMBOL: initial-thread
|
||||||
|
|
||||||
TUPLE: thread
|
TUPLE: thread
|
||||||
name quot error-handler exit-handler
|
name quot exit-handler
|
||||||
id
|
id
|
||||||
continuation state
|
continuation state
|
||||||
mailbox variables sleep-entry ;
|
mailbox variables sleep-entry ;
|
||||||
|
@ -60,11 +59,10 @@ threads global [ H{ } assoc-like ] change-at
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
: <thread> ( quot name error-handler -- thread )
|
: <thread> ( quot name -- thread )
|
||||||
\ thread counter <box> [ ] {
|
\ thread counter <box> [ ] {
|
||||||
set-thread-quot
|
set-thread-quot
|
||||||
set-thread-name
|
set-thread-name
|
||||||
set-thread-error-handler
|
|
||||||
set-thread-id
|
set-thread-id
|
||||||
set-thread-continuation
|
set-thread-continuation
|
||||||
set-thread-exit-handler
|
set-thread-exit-handler
|
||||||
|
@ -179,20 +177,8 @@ M: real sleep
|
||||||
] 1 (throw)
|
] 1 (throw)
|
||||||
] "spawn" suspend 2drop ;
|
] "spawn" suspend 2drop ;
|
||||||
|
|
||||||
: default-thread-error-handler ( error thread -- )
|
|
||||||
global [
|
|
||||||
"Error in thread " write
|
|
||||||
dup thread-id pprint
|
|
||||||
" (" write
|
|
||||||
dup thread-name pprint ")" print
|
|
||||||
"spawned to call " write
|
|
||||||
thread-quot short.
|
|
||||||
nl
|
|
||||||
print-error flush
|
|
||||||
] bind ;
|
|
||||||
|
|
||||||
: spawn ( quot name -- thread )
|
: spawn ( quot name -- thread )
|
||||||
[ default-thread-error-handler ] <thread> [ (spawn) ] keep ;
|
<thread> [ (spawn) ] keep ;
|
||||||
|
|
||||||
: spawn-server ( quot name -- thread )
|
: spawn-server ( quot name -- thread )
|
||||||
>r [ [ ] [ ] while ] curry r> spawn ;
|
>r [ [ ] [ ] while ] curry r> spawn ;
|
||||||
|
@ -202,6 +188,8 @@ M: real sleep
|
||||||
[ >r set-namestack set-datastack r> call ] 3curry
|
[ >r set-namestack set-datastack r> call ] 3curry
|
||||||
"Thread" spawn drop ;
|
"Thread" spawn drop ;
|
||||||
|
|
||||||
|
GENERIC: error-in-thread ( error thread -- )
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
: init-threads ( -- )
|
: init-threads ( -- )
|
||||||
|
@ -209,13 +197,13 @@ M: real sleep
|
||||||
<dlist> 42 setenv
|
<dlist> 42 setenv
|
||||||
<min-heap> 43 setenv
|
<min-heap> 43 setenv
|
||||||
initial-thread global
|
initial-thread global
|
||||||
[ drop f "Initial" [ die ] <thread> ] cache
|
[ drop f "Initial" <thread> ] cache
|
||||||
<box> over set-thread-continuation
|
<box> over set-thread-continuation
|
||||||
f over set-thread-state
|
f over set-thread-state
|
||||||
dup register-thread
|
dup register-thread
|
||||||
set-self ;
|
set-self ;
|
||||||
|
|
||||||
[ self dup thread-error-handler call stop ]
|
[ self error-in-thread stop ]
|
||||||
thread-error-hook set-global
|
thread-error-hook set-global
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
Loading…
Reference in New Issue