Ticket UUID: | 2038069 | |||
Title: | Too much errorinfo at catch | |||
Type: | Bug | Version: | obsolete: 8.6a1 | |
Submitter: | lars_h | Created on: | 2008-08-04 21:42:19 | |
Subsystem: | 47. Bytecode Compiler | Assigned To: | msofer | |
Priority: | 5 Medium | Severity: | ||
Status: | Closed | Last Modified: | 2008-08-07 03:57:27 | |
Resolution: | Fixed | Closed By: | msofer | |
Closed on: | 2008-08-05 15:55:16 | |||
Description: |
This is an issue where a bytecompiled [catch] behaves differently from an interpreted [catch]. It is present in 8.5, today's CVS HEAD (8.6a1 with NRE), and at least 8.4 too (haven't checked with any 8.3 or earlier). The issue is probably clearest in 8.5 (this is .0): % proc compiled {prefix script} {list [catch [lappend prefix $script] res info] $res $info} % proc interpreted {prefix script} {list [eval {catch [lappend prefix $script] res info}] $res $info} (Same code, except for the [eval] around the [catch] in the latter. Changing the command substitution to a variable substitution did not seem to make a difference.) % compiled {uplevel #0} {error FOO} 1 FOO {-code 1 -level 0 -errorcode NONE -errorinfo {FOO while executing "error FOO" ("uplevel" body line 1) invoked from within "uplevel #0 {error FOO}" invoked from within "catch [lappend prefix $script] res info"} -errorline 1} % interpreted {uplevel #0} {error FOO} 1 FOO {-code 1 -level 0 -errorcode NONE -errorinfo {FOO while executing "error FOO" ("uplevel" body line 1) invoked from within "uplevel #0 {error FOO}"} -errorline 1} Thus: the compiled [catch] includes itself in the -errorinfo, whereas the interpreted does not. IMHO the latter is more correct. (If there was also a reliable way of dropping the [uplevel] I'd be all ears, but I can live with that.) In today's 8.6a1+NRE, the compiled result is slightly different, but the interpreted result stays the same: % compiled {uplevel #0} {error FOO} 1 FOO {-code 1 -level 0 -errorcode NONE -errorinfo {FOO while executing "error FOO" ("uplevel" body line 1) invoked from within "catch [lappend prefix $script] res info"} -errorline 1} % interpreted {uplevel #0} {error FOO} 1 FOO {-code 1 -level 0 -errorcode NONE -errorinfo {FOO while executing "error FOO" ("uplevel" body line 1) invoked from within "uplevel #0 {error FOO}"} -errorline 1} I actually find this compiled behaviour a change to the worse, because it places greater emphasis on irrelevant details (how the command being caught is constructed and caught) while hiding some more relevant details (what the command being caught is). | |||
User Comments: |
[email protected] added on 2008-08-07 03:57:27:
Logged In: NO rather than use [eval], I'd use: set catch catch list [$catch [lappend prefix $script] res info] $res $info lars_h added on 2008-08-07 03:41:38: Logged In: YES user_id=938835 Originator: YES OK, so you've restored the pre-NRE behaviour. An improvement, although it still has compiled [catch]es putting information about commands not actually caught in the -errorinfo. I consider that a bug too, although obviously one of low prioriity. For now, I'll work around it by adding an [eval] to force use of the interpreted [catch] instead: proc hubs::eval::do-8.5 {prefix script} { list [eval {catch [lappend prefix $script] res info}] $res $info } Re "all ears": OK, that idea is to switch context for the [catch] and use fully-qualified names for the variables to avoid overwriting other variables; nothing that really required TIP#90. (Which is good, since I also have a [hubs::eval::do-8.4] for use in older interpreters.) There is no reentrancy problem, since the variables are only set when returning. That's good. The trick works for prefixes of "uplevel $level" and "namespace eval $ns", but not for "interp eval $path". That's *bad*, because the latter is one of my use-cases. Close but no cigar, I'm afraid. msofer added on 2008-08-05 22:55:16: Logged In: YES user_id=148712 Originator: NO committed, thx dgp added on 2008-08-05 22:41:53: Logged In: YES user_id=80530 Originator: NO Attached patch is a fix, and includes a test. If miguel, or anyone has a better fix that still passes the test, that's fine with me. After a fix is committed, I recommend we close this report. The other issues raised seem to me to be feature requests. dgp added on 2008-08-05 22:40:35: File Added - 287168: 2038069.patch Logged In: YES user_id=80530 Originator: NO File Added: 2038069.patch dgp added on 2008-08-05 22:18:23: Logged In: YES user_id=80530 Originator: NO Confirmed. If I disable the pure list branch at line 2604 of tclExecute.c HEAD, then this regression goes away. Some details about stack trace generatation went off down that branch. dgp added on 2008-08-05 22:14:46: Logged In: YES user_id=80530 Originator: NO Not confident yet, but appears to be a consequence of the re-implementation of the INST_EVAL_STK instruction. dgp added on 2008-08-05 22:02:08: Logged In: YES user_id=80530 Originator: NO Focusing just on the regression, uplevel is a red herring. Prior to miguel's NRE commits on July 13: % proc demo {} { list [catch [list set] m o] $m $o } % demo 1 {wrong # args: should be "set varName ?newValue?"} {-code 1 -level 0 -errorcode NONE -errorinfo {wrong # args: should be "set varName ?newValue?" while executing "set" invoked from within "catch [list set] m o"} -errorline 2} After the commits of July 13 & 14: % demo 1 {wrong # args: should be "set varName ?newValue?"} {-code 1 -level 0 -errorcode NONE -errorinfo {wrong # args: should be "set varName ?newValue?" while executing "catch [list set] m o"} -errorline 2} It is important that the script argument to [catch] is the result of a substitution to see this change. dgp added on 2008-08-05 21:47:39: Logged In: YES user_id=80530 Originator: NO The stack trace change in 8.6 came in with miguels original NRE commits on July 13-14. dgp added on 2008-08-05 21:13:43: Logged In: YES user_id=80530 Originator: NO To answer the "all ears" request first... TIP 90 includes the following example of how to use Tcl 8.5 features to robustly remove the effects of catch and uplevel from the stack trace of a "wrapper" command: namespace eval control { proc eval script { variable result variable options set code [uplevel 1 \ [list ::catch $script [namespace which -variable result] \ [namespace which -variable options]]] if {$code == 1} { set line [dict get $options -errorline] dict append options -errorinfo \ "\n (\"[lindex [info level 0] 0]\" body line $line)" } dict incr options -level return -options $options $result } } |
Attachments:
- 2038069.patch [download] added by dgp on 2008-08-05 22:40:35. [details]