Ticket UUID: | ba68d1e9484a3a92449fdaab4c377b534842c0e0 | |||
Title: | Errors that occur when using interp eval do not give relevant line number and filename locations | |||
Type: | Bug | Version: | any | |
Submitter: | anonymous | Created on: | 2025-02-25 17:00:06 | |
Subsystem: | 20. [interp] | Assigned To: | sebres | |
Priority: | 3 Low | Severity: | Cosmetic | |
Status: | Closed | Last Modified: | 2025-03-06 19:24:12 | |
Resolution: | Fixed | Closed By: | sebres | |
Closed on: | 2025-03-06 19:24:12 | |||
Description: |
More details can be found here: https://stackoverflow.com/questions/78134384/how-to-get-line-number-and-filename-locations-for-errors-that-occur-while-using To summarize, though, when an error occurs while using interp eval, the error outputs the location of the interp eval call, rather than the location of the actual erroneous code being evaluated. This may make sense from the perspective of the caller of interp eval. However, it creates difficulties in the context of implementing something like a plugin system that interp evals scripts, as the writers of the plugin scripts would receive less useful information than might be desired. Some example code and their outputs: Example A: #!/bin/sh # This line continues for Tcl, but is a single line for 'sh' \ exec tclsh "$0" ${1+"$@"} ::safe::interpCreate i i eval {expr {"a" + 1}} Example A Output: ./example.tcl can't use non-numeric string as operand of "+" invoked from within "expr {"a" + 1}" invoked from within "i eval {expr {"a" + 1}}" (file "./example.tcl" line 6) Example B: #!/bin/sh # This line continues for Tcl, but is a single line for 'sh' \ exec tclsh "$0" ${1+"$@"} ::safe::interpCreate i i eval [list expr {"a" + 1}] Example B output: ./example.tcl can't use non-numeric string as operand of "+" while executing "expr {"a" + 1}" invoked from within "i eval [list expr {"a" + 1}]" (file "./example.tcl" line 6) Example C: #!/bin/sh # This line continues for Tcl, but is a single line for 'sh' \ exec tclsh "$0" ${1+"$@"} ::safe::interpCreate i i eval [list expr [list "a" + 1]] Example C output: ./example.tcl invalid bareword "a" in expression "a + 1"; should be "$a" or "{a}" or "a(...)" or ... (parsing expression "a + 1") invoked from within "expr {a + 1}" invoked from within "i eval [list expr [list "a" + 1]]" (file "./example.tcl" line 6) | |||
User Comments: |
sebres added on 2025-03-06 19:24:12:
Fixed now in [5cd276dee1c2a46f], tests pass, thus close. sebres added on 2025-03-06 19:12:06: Found it: the issue has been caused by the bug in Tcl_GetReturnOptions, what sets the errorLine from rethrown error from invokehidden in AliasLoad (so it contains the line number from this proc), but without the errorInfo (which initially empty, but hereafter got filled in Tcl_GetReturnOptions by So ultimately with this 3-way transfer (interp eval -> invocation of alias AliasLoad -> calling invokehidden) it would reach the calling interpreter with non-empty errorInfo (containing the error message only, without the callstack). The wrong line within sebres added on 2025-03-06 16:26:18: Hmm, pity that I did not check the safe.test, but seeing @dgp amend [b756080dc6f8cd05], the whole fix looks a bit weird to me now, because there is no line 59 in code of interp eval (basically the evaluating scripts are single-line scripts). If I do debug-logging from Tcl_TransferResult, it does that 3 times during test safe-10.4.1, for instance:
(where only middle has errorLine = 59, probably some old value that did not reset in-between)... Anyway, this doesn't look correct to me. I'll fix it soon. sebres added on 2025-03-06 14:36:16: Since no objections, merged now in [f1d2397c7c640072]. Ticket closed as resolved. sebres added on 2025-02-27 13:44:44: Already answered on stackoverflow, however hereafter noticed that sometimes it may be indeed interesting, thus here is a fix [497e526e670a9faf] (done in minimalistic way)... Reviews are welcome. If no objections follow I'll merge it at some point later. |
