[2/3,gdb/testsuite] Fix global array leaks

Message ID 20200519162942.GA9014@delia
State New
Headers show
Series
  • [1/3,gdb/testsuite] Fix global array cp_class_table_history leak
Related show

Commit Message

Tom de Vries May 19, 2020, 4:29 p.m.
Hi,

Several test-cases define global arrays, which remain set after the test-case
has run.  This has the potential to cause tcl errors.

Fix this by wrapping each test-case in a namespace.  Add a README entry on how
to do that.

Tested on x86_64-linux.

Any comments?

Thanks,
- Tom

[gdb/testsuite] Fix global array leaks

gdb/testsuite/ChangeLog:

2020-05-18  Tom de Vries  <tdevries@suse.de>

	PR testsuite/25996
	* README: Add "Wrapping test-cases in Tcl namespaces".
	* gdb.ada/info_auto_lang.exp: Wrap in namespace.
	* gdb.arch/amd64-byte.exp: Same.
	* gdb.arch/amd64-dword.exp: Same.
	* gdb.arch/amd64-word.exp: Same.
	* gdb.arch/i386-biarch-core.exp: Same.
	* gdb.arch/i386-byte.exp: Same.
	* gdb.arch/i386-word.exp: Same.
	* gdb.base/charset.exp: Same.
	* gdb.base/consecutive-step-over.exp: Same.
	* gdb.base/coredump-filter.exp: Same.
	* gdb.base/many-completions.exp: Same.
	* gdb.base/savedregs.exp: Same.
	* gdb.base/step-over-syscall.exp: Same.
	* gdb.base/term.exp: Same.
	* gdb.base/watchpoint-unaligned.exp: Same.
	* gdb.cp/cpexprs-debug-types.exp: Same.
	* gdb.cp/cpexprs.exp: Same.
	* gdb.cp/cpexprs.exp.tcl: Same.
	* gdb.cp/meth-typedefs.exp: Same.
	* gdb.cp/ovldbreak.exp: Same.
	* gdb.dwarf2/clztest.exp: Same.
	* gdb.dwarf2/typeddwarf.exp: Same.
	* gdb.linespec/ls-errs.exp: Same.
	* gdb.threads/tls.exp: Same.
	* gdb.xml/tdesc-regs.exp: Same.

---
 gdb/testsuite/README                             | 136 +++++++++++++++++++++++
 gdb/testsuite/gdb.ada/info_auto_lang.exp         |  14 +++
 gdb/testsuite/gdb.arch/amd64-byte.exp            |   7 ++
 gdb/testsuite/gdb.arch/amd64-dword.exp           |   7 ++
 gdb/testsuite/gdb.arch/amd64-word.exp            |   7 ++
 gdb/testsuite/gdb.arch/i386-biarch-core.exp      |   7 ++
 gdb/testsuite/gdb.arch/i386-byte.exp             |   7 ++
 gdb/testsuite/gdb.arch/i386-word.exp             |   7 ++
 gdb/testsuite/gdb.base/charset.exp               |  13 ++-
 gdb/testsuite/gdb.base/consecutive-step-over.exp |   7 ++
 gdb/testsuite/gdb.base/coredump-filter.exp       |  10 +-
 gdb/testsuite/gdb.base/many-completions.exp      |   8 ++
 gdb/testsuite/gdb.base/savedregs.exp             |   9 +-
 gdb/testsuite/gdb.base/step-over-syscall.exp     |  17 ++-
 gdb/testsuite/gdb.base/term.exp                  |   9 ++
 gdb/testsuite/gdb.base/watchpoint-unaligned.exp  |   9 ++
 gdb/testsuite/gdb.cp/cpexprs-debug-types.exp     |   5 +
 gdb/testsuite/gdb.cp/cpexprs.exp                 |   5 +
 gdb/testsuite/gdb.cp/cpexprs.exp.tcl             |  15 ++-
 gdb/testsuite/gdb.cp/meth-typedefs.exp           |   7 ++
 gdb/testsuite/gdb.cp/ovldbreak.exp               |   9 ++
 gdb/testsuite/gdb.dwarf2/clztest.exp             |  16 ++-
 gdb/testsuite/gdb.dwarf2/typeddwarf.exp          |  19 +++-
 gdb/testsuite/gdb.linespec/ls-errs.exp           |  12 +-
 gdb/testsuite/gdb.threads/tls.exp                |   8 ++
 gdb/testsuite/gdb.xml/tdesc-regs.exp             |  13 ++-
 26 files changed, 358 insertions(+), 25 deletions(-)

Comments

Tom Tromey May 22, 2020, 8:13 p.m. | #1
>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:


Tom> Several test-cases define global arrays, which remain set after the test-case
Tom> has run.  This has the potential to cause tcl errors.

Tom> Fix this by wrapping each test-case in a namespace.  Add a README entry on how
Tom> to do that.

Tom> Tested on x86_64-linux.

Tom> Any comments?

This seems fine to me, but doesn't all the code in the namespace{} need
to be reindented?

Tom
Tom de Vries June 2, 2020, 1:07 p.m. | #2
On 22-05-2020 22:13, Tom Tromey wrote:
>>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:

> 

> Tom> Several test-cases define global arrays, which remain set after the test-case

> Tom> has run.  This has the potential to cause tcl errors.

> 

> Tom> Fix this by wrapping each test-case in a namespace.  Add a README entry on how

> Tom> to do that.

> 

> Tom> Tested on x86_64-linux.

> 

> Tom> Any comments?

> 

> This seems fine to me, but doesn't all the code in the namespace{} need

> to be reindented?


I'm not sure.

I based the style on what I saw Pedro doing here (
https://sourceware.org/git/?p=binutils-gdb.git;a=blobdiff;f=gdb/testsuite/gdb.multi/multi-kill.exp;h=03bf8449cf87694c0153e2bbb2ff476cccb1e342;hp=ce6075045fc4a9e99987067bc22e4a86e089f9d5;hb=272c36b87f81fd64e5f4669730da72c39d0716b3;hpb=013707794a67269dd34fd8ae6e354e982c547dc0
).

Thanks,
- Tom
Simon Marchi via Gdb-patches June 2, 2020, 1:24 p.m. | #3
On 6/2/20 2:07 PM, Tom de Vries wrote:
> On 22-05-2020 22:13, Tom Tromey wrote:

>>>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:

>>

>> Tom> Several test-cases define global arrays, which remain set after the test-case

>> Tom> has run.  This has the potential to cause tcl errors.

>>

>> Tom> Fix this by wrapping each test-case in a namespace.  Add a README entry on how

>> Tom> to do that.

>>

>> Tom> Tested on x86_64-linux.

>>

>> Tom> Any comments?

>>

>> This seems fine to me, but doesn't all the code in the namespace{} need

>> to be reindented?

> 

> I'm not sure.

> 

> I based the style on what I saw Pedro doing here (

> https://sourceware.org/git/?p=binutils-gdb.git;a=blobdiff;f=gdb/testsuite/gdb.multi/multi-kill.exp;h=03bf8449cf87694c0153e2bbb2ff476cccb1e342;hp=ce6075045fc4a9e99987067bc22e4a86e089f9d5;hb=272c36b87f81fd64e5f4669730da72c39d0716b3;hpb=013707794a67269dd34fd8ae6e354e982c547dc0

> ).

> 


I was going by:

 - we don't indent within-namespace code in C++.  And I think that's a good thing, since if
   we assume the end goal of everything being inside a namespace, then the indentation is
   just a waste of horizontal space.  TCL's usual practice may be different, I don't know.

 - reindenting everything in preexisting files seems like a lot of churn for little gain.

Thanks,
Pedro Alves

Patch

diff --git a/gdb/testsuite/README b/gdb/testsuite/README
index fae0c339cc..5fb9b8f5fd 100644
--- a/gdb/testsuite/README
+++ b/gdb/testsuite/README
@@ -716,3 +716,139 @@  Use [is_remote target] to check whether the DejaGnu target board is
 remote.  When what you really want to know is whether GDB is using the
 remote protocol, because feature X is only available when GDB debugs
 natively, check gdb_protocol instead.
+
+Wrapping test-cases in Tcl namespaces
+*************************************
+
+We use global variables like f.i. gdb_test_timeout to communicate global
+settings to the test-cases.  OTOH, when setting a variable in a test-case like
+this:
+
+  # test.exp
+  set test "step here and there"
+  gdb_test "step" $test
+
+the variable test is also a global variable, and will be available as such in
+test-cases that are run afterwards.
+
+Furthermore, a variable name cannot be used both as scalar and array without
+an intermediate unset.  Trying to do so will result in tcl errors, for
+example, we get:
+
+  % set var "bla"
+  % set var(1) "bla"
+  can't set "var(1)": variable isn't array
+
+or:
+
+  % set var(1) "bla"
+  % set var "bla"
+  can't set "var": variable is array
+
+So, since a global name in one test-case can leak to another test-case,
+setting a global name in one test-case can result in a tcl error in another
+test-case that reuses the name in a different way:
+
+  # test1.exp
+  set var "bla"
+
+  # test2.exp
+  set var(1) "bla"
+
+One way to fix this is by unsetting the variable after using it:
+
+  # test1.exp
+  set var "bla"
+  unset var
+
+  # test2.exp
+  set var(1) "bla"
+  unset var
+
+But this style requires one to unset all global variables set by all
+test-cases, which seems somewhat labour-intensive.  Another way to fix this is
+to wrap the test-case using the array in a namespace:
+
+  # test2.exp
+  namespace eval test2.exp {
+    variable var
+    set var(1) "bla"
+  }
+
+Note that when running test2.exp without the declaration of var as namespace
+variable using the variable keyword, things appear to work:
+
+  # test2.exp
+  namespace eval test2.exp {
+    set var(1) "bla"
+  }
+
+The problem is that in this case, var is either:
+- a global variable in case the name already exists in global namespace, or
+- a namespace variable.
+So, in case:
+- we run only test2.exp, var will be interpreted as namespace variable, but
+- if we run first test1.exp and then test2.exp, var will be a global variable
+  and we'll have our original error back.
+
+While the namespace-wrapping technique aims to wrap array definitions, for
+practicality we wrap entire test-cases, so also scalar definitions may be
+wrapped, like the one for var2 here:
+
+  # test2.exp
+  namespace eval test2.exp {
+    variable var
+    set var(1) "bla"
+    set var2 "blabla"
+  }
+
+The variable var2 will also be either a global or namespace variable depending
+on the global state, and the question is whether we should do something about
+it.  This does not seem necessary in general, but there's one notable
+exception: if the scalar variable is used in a proc:
+
+  # test2.exp
+  set var(1) "bla"
+  set var2 "blabla"
+
+  proc foo { } {
+    global var2
+    puts $var2
+  }
+
+If we wrap this in a namespace, we need to decide whether var2 is a global or
+a namespace variable.  If we make it a namespace variable, we have:
+
+  # test2.exp
+  namespace eval test2.exp {
+    variable var      
+    set var(1) "bla"
+    variable var2
+    set var2 "blabla"
+
+    proc foo { } {
+      variable var2
+      puts $var2
+    }
+
+    foo
+  }
+
+and if we make it a global variable, we have:
+
+  namespace eval test2.exp {
+    variable var
+    set var(1) "bla"
+    upvar ::var2 var2
+    set var2 "blabla"
+
+    proc foo { } {
+      global var2
+      puts $var2
+    }
+
+    foo
+  }
+
+Note that using plain global instead of the upvar does not work, since that
+one only has effect in a proc body.
diff --git a/gdb/testsuite/gdb.ada/info_auto_lang.exp b/gdb/testsuite/gdb.ada/info_auto_lang.exp
index 4876f3e607..00397888a1 100644
--- a/gdb/testsuite/gdb.ada/info_auto_lang.exp
+++ b/gdb/testsuite/gdb.ada/info_auto_lang.exp
@@ -23,6 +23,19 @@  load_lib "ada.exp"
 # the language mode.
 
 standard_ada_testfile proc_in_ada
+
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable type_in_c
+variable var_in_ada
+variable rbreak_func_in_c
+variable func_in_c
+variable type_in_ada
+variable rbreak_func_in_ada
+variable var_in_c
+variable func_in_ada
+
 set cfile "some_c"
 # gnat normalizes proc_in_ada source file when compiling.
 # As the 'info' commands results are sorted by absolute path names, also normalize
@@ -153,3 +166,4 @@  foreach_with_prefix language_choice { "auto" "ada" "c" } {
     }
 }
 
+}
diff --git a/gdb/testsuite/gdb.arch/amd64-byte.exp b/gdb/testsuite/gdb.arch/amd64-byte.exp
index 0b46d6f9f8..98ffc1a64f 100644
--- a/gdb/testsuite/gdb.arch/amd64-byte.exp
+++ b/gdb/testsuite/gdb.arch/amd64-byte.exp
@@ -26,6 +26,11 @@  if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
 
 standard_testfile amd64-pseudo.c
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable byte_regs
+
 if [get_compiler_info] {
     return -1
 }
@@ -131,3 +136,5 @@  for { set r 7 } { $r <= 14  } { incr r } {
         ".. = $r" \
         "check contents of %$byte_regs($r)"
 }
+
+}
diff --git a/gdb/testsuite/gdb.arch/amd64-dword.exp b/gdb/testsuite/gdb.arch/amd64-dword.exp
index bce411db26..067e49fac4 100644
--- a/gdb/testsuite/gdb.arch/amd64-dword.exp
+++ b/gdb/testsuite/gdb.arch/amd64-dword.exp
@@ -26,6 +26,11 @@  if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
 
 standard_testfile amd64-pseudo.c
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable dword_regs
+
 if [get_compiler_info] {
     return -1
 }
@@ -111,3 +116,5 @@  for { set r 7 } { $r <= $nr_regs  } { incr r } {
         ".. = $r" \
         "check contents of %$dword_regs($r)"
 }
+
+}
diff --git a/gdb/testsuite/gdb.arch/amd64-word.exp b/gdb/testsuite/gdb.arch/amd64-word.exp
index 4ede5482f1..78241569ee 100644
--- a/gdb/testsuite/gdb.arch/amd64-word.exp
+++ b/gdb/testsuite/gdb.arch/amd64-word.exp
@@ -26,6 +26,11 @@  if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
 
 standard_testfile amd64-pseudo.c
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable word_regs
+
 if [get_compiler_info] {
     return -1
 }
@@ -111,3 +116,5 @@  for { set r 7 } { $r <= $nr_regs  } { incr r } {
         ".. = $r" \
         "check contents of %$word_regs($r)"
 }
+
+}
diff --git a/gdb/testsuite/gdb.arch/i386-biarch-core.exp b/gdb/testsuite/gdb.arch/i386-biarch-core.exp
index 43b668aa1b..1ae46449f3 100644
--- a/gdb/testsuite/gdb.arch/i386-biarch-core.exp
+++ b/gdb/testsuite/gdb.arch/i386-biarch-core.exp
@@ -23,6 +23,11 @@ 
 
 standard_testfile
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable corestat
+
 gdb_exit
 gdb_start
 gdb_reinitialize_dir $srcdir/$subdir
@@ -96,3 +101,5 @@  gdb_test_multiple "core-file ${corefile}" $test {
 # Test if at least the core file segments memory has been loaded.
 # https://bugzilla.redhat.com/show_bug.cgi?id=457187
 gdb_test "x/bx $address" "\r\n\[ \t\]*$address:\[ \t\]*0xf4\[ \t\]*" ".text is readable"
+
+}
diff --git a/gdb/testsuite/gdb.arch/i386-byte.exp b/gdb/testsuite/gdb.arch/i386-byte.exp
index aa5b8d7bea..02b3b544f0 100644
--- a/gdb/testsuite/gdb.arch/i386-byte.exp
+++ b/gdb/testsuite/gdb.arch/i386-byte.exp
@@ -26,6 +26,11 @@  if {(![istarget "x86_64-*-*"] && ![istarget "i?86-*-*"])} then {
 
 standard_testfile i386-pseudo.c
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable byte_regs
+
 if [get_compiler_info] {
     return -1
 }
@@ -86,3 +91,5 @@  for { set r 1 } { $r <= 4  } { incr r } {
         ".. = $h" \
         "check contents of %$byte_regs($h)"
 }
+
+}
diff --git a/gdb/testsuite/gdb.arch/i386-word.exp b/gdb/testsuite/gdb.arch/i386-word.exp
index 336ea27a1f..295f57f4a9 100644
--- a/gdb/testsuite/gdb.arch/i386-word.exp
+++ b/gdb/testsuite/gdb.arch/i386-word.exp
@@ -26,6 +26,11 @@  if {(![istarget "x86_64-*-*"] && ![istarget "i?86-*-*"])} then {
 
 standard_testfile i386-pseudo.c
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable word_regs
+
 if [get_compiler_info] {
     return -1
 }
@@ -72,3 +77,5 @@  for { set r 1 } { $r <= 4  } { incr r } {
         ".. = $r" \
         "check contents of %$word_regs($r)"
 }
+
+}
diff --git a/gdb/testsuite/gdb.base/charset.exp b/gdb/testsuite/gdb.base/charset.exp
index a4345faf05..ff8dc02399 100644
--- a/gdb/testsuite/gdb.base/charset.exp
+++ b/gdb/testsuite/gdb.base/charset.exp
@@ -23,6 +23,11 @@ 
 
 standard_testfile .c charset-malloc.c
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable charsets
+
 if { [prepare_for_testing "failed to prepare" ${testfile} [list $srcfile $srcfile2]] } {
     return -1
 }
@@ -108,17 +113,17 @@  gdb_test "set target-charset my_grandma_bonnie" \
 array set charsets {}
 
 proc all_charset_names {} {
-    global charsets
+    variable charsets
     return [array names charsets]
 }
 
 proc valid_host_charset {charset} {
-    global charsets
+    variable charsets
     return [expr {[info exists charsets($charset)] && $charsets($charset)}]
 }
 
 proc valid_target_charset {charset} {
-    global charsets
+    variable charsets
     return [info exists charsets($charset)]
 }
 
@@ -622,3 +627,5 @@  foreach name {short int long} {
 
 
 gdb_exit 
+
+}
diff --git a/gdb/testsuite/gdb.base/consecutive-step-over.exp b/gdb/testsuite/gdb.base/consecutive-step-over.exp
index dde1818ab3..9876b8b434 100644
--- a/gdb/testsuite/gdb.base/consecutive-step-over.exp
+++ b/gdb/testsuite/gdb.base/consecutive-step-over.exp
@@ -20,6 +20,11 @@ 
 #
 standard_testfile
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable bp_addrs
+
 if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} {
     return -1
 }
@@ -68,3 +73,5 @@  for {set i 1} {$i <= $n_insns} {incr i} {
 set lineno [gdb_get_line_number "break here"]
 gdb_breakpoint $lineno
 gdb_continue_to_breakpoint "break here" ".*break here.*"
+
+}
diff --git a/gdb/testsuite/gdb.base/coredump-filter.exp b/gdb/testsuite/gdb.base/coredump-filter.exp
index ff398f2b85..62105f1677 100644
--- a/gdb/testsuite/gdb.base/coredump-filter.exp
+++ b/gdb/testsuite/gdb.base/coredump-filter.exp
@@ -15,6 +15,11 @@ 
 
 standard_testfile
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable coredump_var_addr
+
 # This test is Linux-only.
 if ![istarget *-*-linux*] then {
     untested "coredump-filter.exp"
@@ -53,7 +58,8 @@  proc do_save_core { filter_flag core dump_excluded } {
 }
 
 proc do_load_and_test_core { core var working_var working_value dump_excluded } {
-    global hex decimal coredump_var_addr
+    global hex decimal
+    variable coredump_var_addr
 
     set core_loaded [gdb_core_cmd "$core" "load core"]
     if { $core_loaded == -1 } {
@@ -227,3 +233,5 @@  foreach item $all_anon_corefiles {
 with_test_prefix "loading and testing corefile for non-Private-Shared-Anon-File" {
     test_disasm $non_private_shared_anon_file_core $main_addr 1
 }
+
+}
diff --git a/gdb/testsuite/gdb.base/many-completions.exp b/gdb/testsuite/gdb.base/many-completions.exp
index 9597963abb..05ad5c65e2 100644
--- a/gdb/testsuite/gdb.base/many-completions.exp
+++ b/gdb/testsuite/gdb.base/many-completions.exp
@@ -65,6 +65,12 @@  proc prepare_test_source_file { count } {
 # Build a source file and compile it.
 set filename [prepare_test_source_file 250]
 standard_testfile $filename
+
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable all_funcs
+
 if {[prepare_for_testing "failed to prepare" "$testfile" $srcfile \
 	 { debug }]} {
     return -1
@@ -90,3 +96,5 @@  foreach {-> name} [regexp -all -inline -line {^break (\w+\S*)} $completions] {
     }
 }
 gdb_assert { $duplicates == 0 } "duplicate check"
+
+}
diff --git a/gdb/testsuite/gdb.base/savedregs.exp b/gdb/testsuite/gdb.base/savedregs.exp
index 535009d8be..68a72ddf15 100644
--- a/gdb/testsuite/gdb.base/savedregs.exp
+++ b/gdb/testsuite/gdb.base/savedregs.exp
@@ -32,6 +32,11 @@  if [target_info exists gdb,nosignals] {
 
 standard_testfile .c
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable saved_regs
+
 if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
     untested "failed to compile"
     return -1
@@ -49,7 +54,7 @@  if ![runto_main] then {
 proc process_saved_regs { current inner outer } {
     global gdb_prompt
     global expect_out
-    global saved_regs
+    variable saved_regs
 
     # Skip the CURRENT frame.
 
@@ -149,3 +154,5 @@  process_saved_regs caller { dummy catcher } { sigtramp thrower main }
 # Run to callee, again check everything.
 gdb_test "advance callee" "callee .* at .*"
 process_saved_regs callee { caller } { dummy catcher sigtramp thrower main }
+
+}
diff --git a/gdb/testsuite/gdb.base/step-over-syscall.exp b/gdb/testsuite/gdb.base/step-over-syscall.exp
index 0d0c31abe8..8591355ba9 100644
--- a/gdb/testsuite/gdb.base/step-over-syscall.exp
+++ b/gdb/testsuite/gdb.base/step-over-syscall.exp
@@ -15,6 +15,13 @@ 
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $subdir/$gdb_test_file_name {
+
+variable syscall_number
+variable syscall_insn
+variable syscall_register
+
 set syscall_insn ""
 set syscall_register ""
 array set syscall_number {}
@@ -52,7 +59,8 @@  proc_with_prefix check_pc_after_cross_syscall { syscall syscall_insn_next_addr }
 # Verify the syscall number is the correct one.
 
 proc syscall_number_matches { syscall } {
-  global syscall_register syscall_number
+  variable syscall_register
+  variable syscall_number
 
   if {[gdb_test "p \$$syscall_register" ".*= $syscall_number($syscall)" \
     "syscall number matches"] != 0} {
@@ -68,7 +76,8 @@  proc syscall_number_matches { syscall } {
 # wrong, the two elements of list are -1.
 
 proc setup { syscall } {
-    global gdb_prompt syscall_insn
+    global gdb_prompt
+    variable syscall_insn
 
     global hex
     set next_insn_addr -1
@@ -175,7 +184,7 @@  proc setup { syscall } {
 
 proc step_over_syscall { syscall } {
     with_test_prefix "$syscall" {
-	global syscall_insn
+	variable syscall_insn
 	global gdb_prompt
 
 	set testfile "step-over-$syscall"
@@ -355,3 +364,5 @@  if { $cond_bp_target } {
 	}
     }
 }
+
+}
diff --git a/gdb/testsuite/gdb.base/term.exp b/gdb/testsuite/gdb.base/term.exp
index 21a448c41a..046e6a1e6a 100644
--- a/gdb/testsuite/gdb.base/term.exp
+++ b/gdb/testsuite/gdb.base/term.exp
@@ -16,6 +16,13 @@ 
 # Test that GDB saves and restores terminal settings correctly.  Also check
 # the output of the "info terminal" command.
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $subdir/$gdb_test_file_name {
+
+variable termios1
+variable termios2
+variable termios3
+
 if { [prepare_for_testing "failed to prepare" term term.c] } {
     return -1
 }
@@ -104,3 +111,5 @@  gdb_continue_to_end
 gdb_test "info terminal" \
     "No saved terminal information.*" \
     "test info terminal post-execution"
+
+}
diff --git a/gdb/testsuite/gdb.base/watchpoint-unaligned.exp b/gdb/testsuite/gdb.base/watchpoint-unaligned.exp
index 10824745a6..e3503c5e84 100644
--- a/gdb/testsuite/gdb.base/watchpoint-unaligned.exp
+++ b/gdb/testsuite/gdb.base/watchpoint-unaligned.exp
@@ -22,6 +22,13 @@  if {[skip_hw_watchpoint_tests]} {
 }
 
 standard_testfile
+
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable wpoffset_to_wpnum
+variable alignedend
+
 if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
     return -1
 }
@@ -186,3 +193,5 @@  if {$wpnum} {
     }
     gdb_assert $got_hit "size8twice write"
 }
+
+}
diff --git a/gdb/testsuite/gdb.cp/cpexprs-debug-types.exp b/gdb/testsuite/gdb.cp/cpexprs-debug-types.exp
index ece7bc9acd..68b93f787c 100644
--- a/gdb/testsuite/gdb.cp/cpexprs-debug-types.exp
+++ b/gdb/testsuite/gdb.cp/cpexprs-debug-types.exp
@@ -15,6 +15,11 @@ 
 
 # This file is part of the gdb testsuite.
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $subdir/$gdb_test_file_name {
+
 # Run cpexprs.exp with -fdebug-types-section.
 set flags {additional_flags=-fdebug-types-section}
 source $srcdir/$subdir/cpexprs.exp.tcl
+
+}
diff --git a/gdb/testsuite/gdb.cp/cpexprs.exp b/gdb/testsuite/gdb.cp/cpexprs.exp
index 62f13a38e8..fe19c3e5a4 100644
--- a/gdb/testsuite/gdb.cp/cpexprs.exp
+++ b/gdb/testsuite/gdb.cp/cpexprs.exp
@@ -19,6 +19,11 @@ 
 
 # This file is part of the gdb testsuite.
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $subdir/$gdb_test_file_name {
+
 # Run cpexprs.exp.
 set flags {}
 source $srcdir/$subdir/cpexprs.exp.tcl
+
+}
diff --git a/gdb/testsuite/gdb.cp/cpexprs.exp.tcl b/gdb/testsuite/gdb.cp/cpexprs.exp.tcl
index ef30215735..7e48b84408 100644
--- a/gdb/testsuite/gdb.cp/cpexprs.exp.tcl
+++ b/gdb/testsuite/gdb.cp/cpexprs.exp.tcl
@@ -19,10 +19,15 @@ 
 
 # This file is part of the gdb testsuite.
 
+variable all_functions
+variable DEC
+variable CONVAR
+variable ADDR
+
 # A helper proc which sets a breakpoint at FUNC and attempts to
 # run to the breakpoint.
 proc test_breakpoint {func} {
-    global DEC
+    variable DEC
 
     # Return to the top of the test function every time.
     delete_breakpoints
@@ -55,7 +60,9 @@  proc test_breakpoint {func} {
 # add NAME TYPE PRINT LST
 # add NAME TYPE PRINT -
 proc add_type_regexp {func type print lst} {
-    global all_functions CONVAR ADDR
+    variable all_functions
+    variable CONVAR
+    variable ADDR
 
     set all_functions($func,type) $type
     if {$print == "-"} {
@@ -79,13 +86,13 @@  proc add {func type print lst} {
 }
 
 proc get {func cmd} {
-    global all_functions
+    variable all_functions
     return $all_functions($func,$cmd)
 }
 
 # Returns a list of function names for a given command
 proc get_functions {cmd} {
-    global all_functions
+    variable all_functions
     set result {}
     foreach i [array names all_functions *,$cmd] {
 	if {$all_functions($i) != ""} {
diff --git a/gdb/testsuite/gdb.cp/meth-typedefs.exp b/gdb/testsuite/gdb.cp/meth-typedefs.exp
index 23fe467b35..51cd117169 100644
--- a/gdb/testsuite/gdb.cp/meth-typedefs.exp
+++ b/gdb/testsuite/gdb.cp/meth-typedefs.exp
@@ -35,6 +35,11 @@  if {[skip_cplus_tests]} { continue }
 # Tests for c++/12266 et al
 standard_testfile .cc
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable typedefs
+
 if {[prepare_for_testing "failed to prepare" $testfile $srcfile \
 	 {c++ debug additional_flags=-std=c++11}]} {
     return -1
@@ -189,3 +194,5 @@  foreach f [list "$func" "'$func'"] {
 
 gdb_exit
 return 0
+
+}
diff --git a/gdb/testsuite/gdb.cp/ovldbreak.exp b/gdb/testsuite/gdb.cp/ovldbreak.exp
index 326cacf826..48e04f6182 100644
--- a/gdb/testsuite/gdb.cp/ovldbreak.exp
+++ b/gdb/testsuite/gdb.cp/ovldbreak.exp
@@ -32,6 +32,13 @@  if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable arguments
+variable might_fail
+variable type_map
+
 if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} {
     return -1
 }
@@ -400,3 +407,5 @@  gdb_test "break foo::foofunc" \
 
 unset -nocomplain line types
 gdb_continue_to_end "finish program"
+
+}
diff --git a/gdb/testsuite/gdb.dwarf2/clztest.exp b/gdb/testsuite/gdb.dwarf2/clztest.exp
index b83b4a94e9..64cdf7ae0f 100644
--- a/gdb/testsuite/gdb.dwarf2/clztest.exp
+++ b/gdb/testsuite/gdb.dwarf2/clztest.exp
@@ -16,6 +16,13 @@ 
 load_lib dwarf.exp
 
 standard_testfile .S
+
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable tests
+variable test
+
 set test "clztest"
 
 # This test can only be run on targets which support DWARF-2 and use gas.
@@ -41,19 +48,20 @@  unset -nocomplain tests
 array set tests {}
 
 proc gdb-test {line var value} {
-    global tests
+    variable tests
 
     lappend tests($line) [list $var $value 0]
 }
 
 proc xfail-gdb-test {line var value} {
-    global tests
+    variable tests
 
     lappend tests($line) [list $var $value 1]
 }
 
 proc scan_gdb_tests {} {
-    global srcdir subdir test
+    global srcdir subdir
+    variable test
 
     set file "$srcdir/$subdir/$test.c"
 
@@ -90,3 +98,5 @@  foreach line [lsort [array names tests]] {
 	    "check value of $var at ${test}.c:$line"
     }
 }
+
+}
diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
index d7cc57f323..e442f27603 100644
--- a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
+++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp
@@ -15,13 +15,19 @@ 
 
 load_lib dwarf.exp
 
-set test "typeddwarf"
-
 # This test can only be run on targets which support DWARF-2 and use gas.
 if ![dwarf2_support] {
     return 0  
 }
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $subdir/$gdb_test_file_name {
+
+variable tests
+variable test
+
+set test "typeddwarf"
+
 # This test can only be run on x86 and amd64 targets (and not x32).
 if { [is_x86_like_target] } {
     set sfile ${test}.S
@@ -44,7 +50,7 @@  unset -nocomplain tests
 array set tests {}
 
 proc gdb-test {line var value} {
-    global tests
+    variable tests
 
     lappend tests($line) [list $var $value 0]
 }
@@ -52,7 +58,7 @@  proc gdb-test {line var value} {
 # Add an XFAIL'd test.  If ARCH_PATTERN is given, and does not match
 # the target, then the test is simply added and not XFAIL'd.
 proc xfail-gdb-test {line var value {arch_pattern ""}} {
-    global tests
+    variable tests
 
     set flag 1
     if {$arch_pattern != ""} {
@@ -65,7 +71,8 @@  proc xfail-gdb-test {line var value {arch_pattern ""}} {
 }
 
 proc scan_gdb_tests {} {
-    global srcdir subdir test
+    global srcdir subdir
+    variable test
 
     set file "$srcdir/$subdir/$test.c"
 
@@ -102,3 +109,5 @@  foreach line [lsort [array names tests]] {
 	    "check value of $var at typeddwarf.c:$line"
     }
 }
+
+}
diff --git a/gdb/testsuite/gdb.linespec/ls-errs.exp b/gdb/testsuite/gdb.linespec/ls-errs.exp
index 2b38483115..ef50233e43 100644
--- a/gdb/testsuite/gdb.linespec/ls-errs.exp
+++ b/gdb/testsuite/gdb.linespec/ls-errs.exp
@@ -15,10 +15,16 @@ 
 
 # Tests for linespec errors with C and C++.
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $subdir/$gdb_test_file_name {
+
+variable error_messages
+
 # The test proper.  LANG is either C or C++.
 
 proc do_test {lang} {
-    global testfile srcfile error_messages compiler_info
+    global testfile srcfile compiler_info
+    variable error_messages
 
     standard_testfile
     set exefile $testfile
@@ -88,7 +94,7 @@  proc do_test {lang} {
     # Break at 'linespec' and expect the message in ::error_messages
     # indexed by msg_id with the associated args.
     proc test_break {linespec msg_id args} {
-	global error_messages
+	variable error_messages
 
 	gdb_test "break $linespec" [string_to_regexp \
 				    [eval format \$error_messages($msg_id) \
@@ -271,3 +277,5 @@  proc do_test {lang} {
 foreach_with_prefix lang {"C" "C++"} {
     do_test ${lang}
 }
+
+}
diff --git a/gdb/testsuite/gdb.threads/tls.exp b/gdb/testsuite/gdb.threads/tls.exp
index 8147a6c132..0684b9892a 100644
--- a/gdb/testsuite/gdb.threads/tls.exp
+++ b/gdb/testsuite/gdb.threads/tls.exp
@@ -18,6 +18,12 @@  load_lib gdb-python.exp
 
 standard_testfile tls.c tls2.c
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $testfile {
+
+variable spin_threads_level
+variable spin_threads
+
 if [istarget "*-*-linux"] then {
     set target_cflags "-D_MIT_POSIX_THREADS"
 } else {
@@ -319,3 +325,5 @@  gdb_test "info address a_thread_local" "Symbol \"a_thread_local\" is a thread-lo
 gdb_exit
 
 return 0
+
+}
diff --git a/gdb/testsuite/gdb.xml/tdesc-regs.exp b/gdb/testsuite/gdb.xml/tdesc-regs.exp
index bb04420b24..83fa4eaf34 100644
--- a/gdb/testsuite/gdb.xml/tdesc-regs.exp
+++ b/gdb/testsuite/gdb.xml/tdesc-regs.exp
@@ -18,6 +18,11 @@  if {[gdb_skip_xml_test]} {
     return -1
 }
 
+# Wrap the entire test in a namespace to avoid contaminating other tests.
+namespace eval $subdir/$gdb_test_file_name {
+
+variable remote_filename
+
 gdb_start
 
 # To test adding registers, we need a core set of registers for this
@@ -120,9 +125,9 @@  proc load_description { file errmsg xml_file } {
     global srcdir
     global subdir
     global gdb_prompt
-    global core-regs
-    global architecture
-    global remote_filename
+    variable core-regs
+    variable architecture
+    variable remote_filename
 
     set regs_file [standard_output_file $xml_file]
 
@@ -189,3 +194,5 @@  with_test_prefix "core-only.xml" {
     # The extra register from the previous description should be gone.
     gdb_test "ptype \$extrareg" "type = void"
 }
+
+}