Thread from comp.lang.tcl (10 replies)

Show argument values in bgerror
Posted by alexandru.dadalau@meshparts.de (alexandru) 2 weeks ago

I have this ::bgerror function to help debug errors in program flow:

proc ::bgerror {message} {
  global errorInfo
  puts "*** START OF ERROR MESSAGE ***\n$message\n$errorInfo\n*** END OF
ERROR MESSAGE ***"
}

The issue is, that the errorInfo does not show the values of the
arguments of called procedures in the stack.
Thus it's often not clear which arguments lead the the error.
Is there a trick how to show the values with which the procedures were
called in the stack prior to the error?

Many thanks
Alexandru

Click on article to view all threads in comp.lang.tcl
Re: Show argument values in bgerror
Posted by et99 <et99@rocketship1.me> 2 weeks ago

On 9/17/2024 2:31 PM, alexandru wrote:
> I have this ::bgerror function to help debug errors in program flow:
> 
> proc ::bgerror {message} {
>   global errorInfo
>   puts "*** START OF ERROR MESSAGE ***\n$message\n$errorInfo\n*** END OF
> ERROR MESSAGE ***"
> }
> 
> The issue is, that the errorInfo does not show the values of the
> arguments of called procedures in the stack.
> Thus it's often not clear which arguments lead the the error.
> Is there a trick how to show the values with which the procedures were
> called in the stack prior to the error?
> 
> Many thanks
> Alexandru


Here's some test code I cobbled together, I think there may be something here that does what you want. The "info level [info level]"  might be just what you need, if issued at the proper uplevel. Note, the outer info has 2 args, the inner info only 1 and that's intentional. You likely would iterate on uplevel's and toss ones that give an error.

	console show
     proc foo {} {foo2 11 22 33}
     
     proc foo2 {a b c} {set x 1; set y 2; foo3}
     
     proc foo3 {} {
         set level [info frame]
         puts "level= |$level| "
         set vars [ \
             uplevel 1 {
                 set _vars  [info vars]
                 puts "_vars= |$_vars| level= [info frame] args= [info level [info level]]"
                 foreach _var $_vars {
                     puts "   _var= |$_var| "
                     lappend _varsx "$_var = [set $_var]"
                 }
                 set _varsx
             }
         ]
         puts  "vars= |$vars| "
         puts [join $vars \n]
     }
     if [catch {
         foo
     } err_code] {
         puts $err_code
     }

output:

level= |9|
_vars= |a b c x y| level= 10 args= foo2 11 22 33
    _var= |a|
    _var= |b|
    _var= |c|
    _var= |x|
    _var= |y|
vars= |{a = 11} {b = 22} {c = 33} {x = 1} {y = 2}|
a = 11
b = 22
c = 33
x = 1
y = 2

Click on article to view all threads in comp.lang.tcl
Re: Show argument values in bgerror
Posted by Harald Oehlmann <wortkarg3@yahoo.com> 2 weeks ago

Am 17.09.2024 um 23:31 schrieb alexandru:
> I have this ::bgerror function to help debug errors in program flow:
> 
> proc ::bgerror {message} {
>   global errorInfo
>   puts "*** START OF ERROR MESSAGE ***\n$message\n$errorInfo\n*** END OF
> ERROR MESSAGE ***"
> }
> 
> The issue is, that the errorInfo does not show the values of the
> arguments of called procedures in the stack.
> Thus it's often not clear which arguments lead the the error.
> Is there a trick how to show the values with which the procedures were
> called in the stack prior to the error?
> 
> Many thanks
> Alexandru

info errorstack ?

% proc e {v} {incr v}
% e a
expected integer but got "a"
% set errorInfo
expected integer but got "a"
     while executing
"incr v"
     (procedure "e" line 1)
     invoked from within
"e a"
% info errorstack
INNER incrScalar1Imm CALL {e a}

Harald

Click on article to view all threads in comp.lang.tcl
Re: Show argument values in bgerror
Posted by alexandru.dadalau@meshparts.de (alexandru) 2 weeks ago

Hi Harald,

I'll use your example with small changes to explain the issue:

proc e {v} {incr v}
set x "a"
e $x
puts $errorInfo

will output:

expected integer but got "a"
    while executing
"incr v"
    (procedure "e" line 1)
    invoked from within
"e $x"
    (file "C:/arbeit/MESHPARTS-Software/test3.tcl" line 4)
    invoked from within
"source -encoding utf-8 C:/arbeit/MESHPARTS-Software/test3.tcl"

As you can see, upstream procedure calls are printed with dollar sign,
unevaluated values.
In more complex nested calls, the information about arguments gets lost
and errorInfo does not show which argument values were used.

Click on article to view all threads in comp.lang.tcl
Re: Show argument values in bgerror
Posted by alexandru.dadalau@meshparts.de (alexandru) 2 weeks ago

Wow, thanks for the input. I'll try to use it to solve the problem.

Regards
Alexandru

Click on article to view all threads in comp.lang.tcl
Re: Show argument values in bgerror
Posted by Harald Oehlmann <wortkarg3@yahoo.com> 2 weeks ago

Am 18.09.2024 um 12:23 schrieb alexandru:
> As you can see, upstream procedure calls are printed with dollar sign,
> unevaluated values.
> In more complex nested calls, the information about arguments gets lost
> and errorInfo does not show which argument values were used.

That is exactly what "info errorstack" is about.
See, that the "a" is substituted as argument "v".
It only works for items putting something on the call stack, so, it will 
not help for your eval example. But you get the values supplied to all 
procedures...

Take care,
Harald

Click on article to view all threads in comp.lang.tcl
Re: Show argument values in bgerror
Posted by alexandru.dadalau@meshparts.de (alexandru) 2 weeks ago

Here is the errorInfo of a true life situation.
The value of "val" is not output.
Maybe it should and it was intended so, but it's not.
So it's a bug then...

*** ERROR ***
Time: Monday, das 16 von September, 2024, um 13:24:37
integer value too large to represent
    while executing
"expr {round($val*(10.0**($decimals+3)))/(10.0**$decimals)}"
    (procedure "NumberReadmm" line 5)
    invoked from within
"NumberReadmm $contact_offset 6"
    (procedure "ContactOffsetFormat" line 7)
    invoked from within
"ContactOffsetFormat $contact_offset_min"
    (procedure "UIRelationApplyContactOffset" line 45)
    invoked from within
"UIRelationApplyContactOffset %W"
    invoked from within
".valid.notebook.f5.buttons.b2 invoke "
    invoked from within
".valid.notebook.f5.buttons.b2 instate !disabled {
valid.notebook.f5.buttons.b2 invoke } "
    invoked from within
".valid.notebook.f5.buttons.b2 instate pressed {
valid.notebook.f5.buttons.b2 state !pressed;
valid.notebook.f5.buttons.b2 instate !disabled { .valid..."
    (command bound to event)

Click on article to view all threads in comp.lang.tcl
Re: Show argument values in bgerror
Posted by Don Porter <donald.porter@nist.gov> 2 weeks ago

The [interp bgerror] command has been available since the release
of Tcl 8.5.0 in 2007.  No one should be continuing to struggle against
the deficits of the [bgerror] facility.

On 9/17/24 17:31, alexandru wrote:
> I have this ::bgerror function to help debug errors in program flow:
> 
> proc ::bgerror {message} {
>   global errorInfo
>   puts "*** START OF ERROR MESSAGE ***\n$message\n$errorInfo\n*** END OF
> ERROR MESSAGE ***"
> }
> 
> The issue is, that the errorInfo does not show the values of the
> arguments of called procedures in the stack.
> Thus it's often not clear which arguments lead the the error.
> Is there a trick how to show the values with which the procedures were
> called in the stack prior to the error?
> 
> Many thanks
> Alexandru

-- 
| Don Porter            Applied and Computational Mathematics Division |
| donald.porter@nist.gov             Information Technology Laboratory |
| http://math.nist.gov/~DPorter/                                  NIST |
|______________________________________________________________________|

Click on article to view all threads in comp.lang.tcl
Re: Show argument values in bgerror
Posted by Harald Oehlmann <wortkarg3@yahoo.com> 2 weeks ago

Am 18.09.2024 um 15:21 schrieb alexandru:
> Here is the errorInfo of a true life situation.
> The value of "val" is not output.
> Maybe it should and it was intended so, but it's not.
> So it's a bug then...

Alexandru,
it is not a bug. I don't speak about $::errorInfo, but "info 
errorstack", or the "-errorstack" component of the error dict.

Here is a complete example as proposed by Don (thanks !):

proc bgerrorhandler {message errordict} {
   puts "*** START OF ERROR MESSAGE ***"
   puts $message
   puts "*** ERROR INFO ***"
   puts [dict get $errordict -errorinfo]
   puts "*** ERROR STACK ***"
   foreach {call arg} [dict get $errordict -errorstack] {
     puts "$call:$arg"
   }
   puts "*** END OF ERROR MESSAGE ***"
}
interp bgerror "" bgerrorhandler
proc e1 {v} {incr v}
proc e2 {v} {e1 $v}
after idle {e2 a}

This gives the output:
*** START OF ERROR MESSAGE ***
expected integer but got "a"
*** ERROR INFO ***
expected integer but got "a"
     while executing
"incr v"
     (procedure "e1" line 1)
     invoked from within
"e1 $v"
     (procedure "e2" line 1)
     invoked from within
"e2 a"
     ("after" script)
*** ERROR STACK ***
INNER:incrScalar1Imm
CALL:e1 a
CALL:e2 a
*** END OF ERROR MESSAGE ***

So, the error info has the variable names ($v in this case), while the 
error stack has the values ("a" in this case).

Might this suit your needs ?

Take care,
Harald

Click on article to view all threads in comp.lang.tcl
Re: Show argument values in bgerror
Posted by alexandru.dadalau@meshparts.de (alexandru) 1 week 5 days ago

Thanks Harald,

This code perfectly solves my problem.

Best regards
Alexandru

Click on article to view all threads in comp.lang.tcl
Re: Show argument values in bgerror
Posted by r.zaumseil@freenet.de (rene) 1 week 1 day ago

Hello Harald,

where did you find the second "errordict" argument of the new bgerror
proc. In the bgerror documentation is only the "message" argument.
May be a documentation error?

Regards
Rene

PS. I will try to answer the oo question later this week.

Click on article to view all threads in comp.lang.tcl