Ticket UUID: | a8579d906a28127d541ba23f7c1223259f97b123 | |||
Title: | 'argument with no name' calling proc with args built in different frame | |||
Type: | Bug | Version: | tcl8.6.9+ | |
Submitter: | russell-tcl | Created on: | 2021-10-06 21:57:42 | |
Subsystem: | 18. Commands M-Z | Assigned To: | pooryorick | |
Priority: | 5 Medium | Severity: | Important | |
Status: | Closed | Last Modified: | 2021-10-11 14:35:43 | |
Resolution: | Fixed | Closed By: | jan.nijtmans | |
Closed on: | 2021-10-11 14:35:43 | |||
Description: |
The bug will probably not show up if the args list is constructed in a single frame. The code below uses an external proc to create each arg which are then lappended to the final list used, with or without a default value. The first version of tcl where this shows up is 8.6.9, when the trampoline code started to be used. I've tested every released version of tcl since, compiling from source. The error occurs in 8.6.9,10,11 8.7a5 and 9.0a3. The error does not occur in 8.6.8,7,6,5 8.5.19 or 8.4.20. The main platform is Ubuntu: uname -a 5.11.0-37-generic #41-Ubuntu SMP x86_64 x86_64 x86_64 GNU/Linux I tried following the process with gdb/VS Code and in working and non-working versions, the objv bytes is 0x0 when the proc commands starts. Here's what makes the bug go away: In the helper proc or in the main proc call: llength $argName on each arg. In the main proc: puts $argsList If you catch the error with proc, you can still make the bug go away using the above calls. If you just repeat the same call the bug is still there. I have not found a way to repeat the bug without a helper proc. Here's the simplified code which shows the bug: proc splitArg {argSpec {splitChar !} {ArrayName ""}} { set firstPart [lindex $argSpec 0] set first [string first $splitChar $firstPart] if {$first > -1} { set argName [string range $firstPart 0 [expr {$first - 1}]] set extra [string range $firstPart [expr {$first + 1}] end] } if {$ArrayName eq ""} { set ArrayName $argName } upvar $ArrayName ArgNameArray array set ArgNameArray [lindex $argSpec 1] return $argName } proc testProc {procName argSpecs body} { set argList [list] foreach argSpec $argSpecs { if {[array exists specArray]} { array unset specArray } set argName [splitArg $argSpec ! specArray] if {[info exists specArray(default)]} { lappend argList [list $argName $specArray(default)] } else { lappend argList [list $argName] } } proc $procName $argList $body } testProc myproc {{arg1!type1 {default "It Works, no bug in "}}}\ {puts -nonewline $arg1;puts tcl[info patchlevel]} myproc | |||
User Comments: |
jan.nijtmans added on 2021-10-11 14:35:43:
Fix is now merged to 8.7 and 9.0 branches as well. pooryorick added on 2021-10-08 19:51:39: A more concise script to reproduce the issue is:
The issue is that to determine the length of the string,
Fixed in [75a9777184741e05] dgp added on 2021-10-07 20:25:55: Bisecting locates the behavior change of this script to https://core.tcl-lang.org/tcl/info/c9251294d9b8b14d Assigning for further review. |
