Ticket UUID: | 8f559999fa000614504de7a7eefbc99dc7beea2b | |||
Title: | background error swallowed with command delete trace on a coroutine | |||
Type: | Bug | Version: | head | |
Submitter: | pooryorick | Created on: | 2017-06-22 17:11:10 | |
Subsystem: | 20. [interp] | Assigned To: | nobody | |
Priority: | 5 Medium | Severity: | Important | |
Status: | Closed | Last Modified: | 2017-06-23 08:12:13 | |
Resolution: | Invalid | Closed By: | sebres | |
Closed on: | 2017-06-23 08:12:13 | |||
Description: |
(text/x-fossil-wiki)
When an error occurs in a coroutine that has a delete trace set on it, the delete trace is invoked before the background error handler is invoked. When a coroutine is acting as the main routine in a script it may then carry out the remainder of the program, oblivious to the error: <code><verbatim> proc bgerror {error options} { puts stderr [dict get $options -errorinfo] exit 1 } proc p1 {} { yield [info coroutine] error {never gonna give you up} } coroutine main ::apply [list {} { yield [info coroutine] coroutine c1 p1 trace add command c1 delete [info coroutine] yieldto c1 exit 0 } [namespace current]] after idle main interp bgerror {} [namespace which bgerror] vwait forever </verbatim></code> | |||
User Comments: |
sebres added on 2017-06-23 08:12:13:
(text/x-fossil-wiki)
I realized that your tracing initialization is wrong here - command executed from trace expects specified arguments. If you rewrite your code like: <code><verbatim> proc bgerror {error options} { puts stderr [dict get $options -errorinfo] puts stderr *************exit-1 exit 1 } proc p1 {} { yield [info coroutine] puts *************produce-error error {never gonna give you up} } proc trace-c1 {args} { puts *************in-trace--$args } coroutine main ::apply [list {} { yield [info coroutine] coroutine c1 p1 # wrong trace: # trace add command c1 delete [info coroutine] trace add command c1 delete [list trace-c1 [info coroutine]] yieldto c1 puts stderr *************exit-0 exit 0 } [namespace current]] after idle main interp bgerror {} [namespace which bgerror] vwait forever </verbatim></code> You'll then see: <code><verbatim> *************produce-error *************in-trace--::main ::c1 {} delete never gonna give you up while executing "error {never gonna give you up}" (procedure "p1" line 4) invoked from within "p1" invoked from within "c1" invoked from within "main" ("after" script) *************exit-1 </verbatim></code> Thus I close this as invalid. Please reopen if I'm wrong. sebres added on 2017-06-22 20:00:20: Please note that bgerror is an idle-event (with newest generation-value). It comparable with (after idle bgerror ...). In this case, it will be definitelly executed in the next event-cycle. But the trace will be executed still inside the same cycle (within processing of the last event). To do it in other order: - rather don't use bgerror handling. - or rewrite your trace also using "after idle". So works as expected, thus I'll recommend to close the ticket. |