Tcl Source Code

View Ticket
Login
Ticket UUID: 1522803
Title: wrong backtrace on arithmetic error
Type: Bug Version: obsolete: 8.5a4
Submitter: kennykb Created on: 2006-07-14 21:35:09
Subsystem: 45. Parsing and Eval Assigned To: msofer
Priority: 7 High Severity:
Status: Closed Last Modified: 2006-07-21 22:00:35
Resolution: Fixed Closed By: msofer
    Closed on: 2006-07-21 10:48:44
Description:
On an arithmetic error, such as division by zero,
the backtrace in ::errorInfo shows the last previous
error, rather than the current error.

Behold:

% catch {unset foo(bar)}; set c 0; expr {1/$c}
divide by zero
% set errorInfo
can't unset "foo(bar)": no such variable
    while executing
"unset foo(bar)"
    invoked from within
"expr {1/$c}"

I'm looking at this briefly, but don't expect
to solve it quickly, and hope that one of the
other developers that understands the bytecode
engine might have a keener insight.
User Comments: dgp added on 2006-07-21 22:00:35:
Logged In: YES 
user_id=80530


The commit brought in some
unrelated changes to
tclInt.h and tclObj.c.

I took those back out.

msofer added on 2006-07-21 17:48:44:
Logged In: YES 
user_id=148712

Worth recording dgp's explanation in the chat: "the entire
patch is general reform. Do the reset operation in the one
right place, not here, there, and everywhere."

Looks good to me; gets the same 196 failures as unpatched :)
Committed.

dgp added on 2006-07-21 00:17:35:

File Added - 185569: 1522803.patch

Logged In: YES 
user_id=80530


Please test/review this
patch.

dgp added on 2006-07-18 10:16:36:
Logged In: YES 
user_id=80530


Making that same conversion
on core-8-4-branch leads to
the same bug, even though no
ERR_ALREADY_LOGGED reform
was done on that branch.

The real cause is the loss
of several Tcl_ResetResult()
calls in the bytecode execution
engine that had real useful 
flag clearing effects in addition
to initializing an empty result
to append to.

Simple fix is to put them all back.
Better fix might be to find where
one call might go to get the function
done where it's needed.

dgp added on 2006-07-18 10:08:57:
Logged In: YES 
user_id=80530


Between revisions 1.153 and
1.154 of tclExecute.c, there
were several conversions like:

-    Tcl_ResetResult(interp);
-    Tcl_AppendToObj(Tcl_GetObjResult(interp), "divide by
zero", -1);
+    Tcl_SetObjResult(interp, Tcl_NewStringObj("divide by
zero", -1));

The loss of the Tcl_ResetResult()
call means the loss of a clearing
of the ERR_ALREADY_LOGGED flag,
leading to the observed bug.

This may just be the exposing trigger
with the real cause the E_A_L reform
that happened earlier.  still examining...

dgp added on 2006-07-18 02:54:27:
Logged In: YES 
user_id=80530


To demo in a non-interactive
shell, use the script:

  set c 0
  if 1 {
    catch {set foo}
    expr {1/$c}
  }

The interactive / non-interactive
is just a proxy for compiled /
direct evaluation, and its
bytecompilation one must force
to demo the bug.

kennykb added on 2006-07-18 00:41:20:
Logged In: YES 
user_id=99768

I confirm that it fails only in an interactive interpreter.

dgp added on 2006-07-18 00:07:37:
Logged In: YES 
user_id=80530


can someone confirm this
problem only shows up in
an interactive interp?

Attachments: