This is an automated email from Gerrit.

Antonio Borneo ([email protected]) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/4731

-- gerrit

commit 285f03389f78b1a1b9b93de94dbd63da319b9cf0
Author: Antonio Borneo <[email protected]>
Date:   Mon Oct 22 09:06:50 2018 +0200

    helper/startup.tcl: fix execution stack frame of wrapped commands
    
    The OpenOCD commands that have been wrapped with 'ocd_bouncer' are
    executed within two levels of nested proc's:
        # see register_command_handler() in src/helper/command.c
        proc my_command {args} {eval ocd_bouncer my_command $args}
    
        # see ocd_bouncer in src/helper/startup.tcl
        proc ocd_bouncer {name args} {
                ... [eval ocd_my_command $args] ...
        }
    This causes the stack frame of 'ocd_my_command' to be the same one
    of proc 'ocd_bouncer', thus two levels below the stack frame of the
    caller of 'my_command'. This is an issue with commands that receive
    a variable by name and have to resolve them to access the value.
    
    E.g. the command
        <target> mem2array arrayname bitwidth address count
    is wrapped; it receives the name of the array but fails to resolve
    it in the current stack frame. Instead, the commands
        mem2array arrayname bitwidth address count
        ocd_<target> mem2array arrayname bitwidth address count
    are not wrapped and can directly access the array because they share
    the same stack frame of the caller.
    Same situation with the symmetric commands 'array2mem'.
    
    How to test:
    within a telnet connection, run the following set of commands,
    eventually replacing the address 0x08000000 with a valid readable
    address of your <target>,
        unset -nocomplain v1 v2 v3
        info vars v?
        mem2array v1 32 0x08000000 1
        <target> mem2array v2 32 0x08000000 1
        ocd_<target> mem2array v3 32 0x08000000 1
        info vars v?
    and notice that only v1 and v3 are now allocated. The array v2 has
    been allocated in the temporarily stack frame of proc ocd_bouncer,
    together with its local variables, and then lost when proc ended.
    
    Fixed by executing the wrapped commands with the command 'uplevel'
    instead of 'eval'. The amount of levels to skip is checked to avoid
    errors in the unusual case 'ocd_bouncer' is called directly without
    the first level of wrapper.
    
    Change-Id: Iff90fb8921faf9b5ab04f61062a530578cc20d78
    Signed-off-by: Antonio Borneo <[email protected]>

diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl
index 4ca2cab..2578de9 100644
--- a/src/helper/startup.tcl
+++ b/src/helper/startup.tcl
@@ -12,15 +12,18 @@ proc exit {} {
 
 # All commands are registered with an 'ocd_' prefix, while the "real"
 # command is a wrapper that calls this function.  Its primary purpose is
-# to discard 'handler' command output,
+# to discard 'handler' command output.
+# Due to the two nested proc calls, this wrapper has to explicitly run
+# the wrapped command in the stack frame two levels above.
 proc ocd_bouncer {name args} {
        set cmd [format "ocd_%s" $name]
        set type [eval ocd_command type $cmd $args]
        set errcode error
+       set skiplevel [expr [eval info level] > 1 ? 2 : 1]
        if {$type == "native"} {
-               return [eval $cmd $args]
+               return [uplevel $skiplevel $cmd $args]
        } else {if {$type == "simple"} {
-               set errcode [catch {eval $cmd $args}]
+               set errcode [catch {uplevel $skiplevel $cmd $args}]
                if {$errcode == 0} {
                        return ""
                } else {

-- 


_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to