From 0f575925b6ff89def089e6b6ba810ee547d3978d Mon Sep 17 00:00:00 2001 From: Tom de Vries Date: Tue, 30 Jul 2019 16:15:46 +0200 Subject: [PATCH] [gdb/testsuite] Work around tcl bug in libsegfault.exp with check-read1 When running libsegfault.exp with check-read1, I get: ... Running gdb/testsuite/gdb.base/libsegfault.exp ... ERROR: tcl error sourcing gdb/testsuite/gdb.base/libsegfault.exp. ERROR: no such variable (read trace on "env(LD_PRELOAD)") invoked from within "set env(LD_PRELOAD)" ("uplevel" body line 1) invoked from within "uplevel 1 [list set $var]" invoked from within "if [uplevel 1 [list array exists $var]] { set saved_arrays($var) [uplevel 1 [list array get $var]] } else { set saved_scalars($var) [uplevel ..." invoked from within "if [uplevel 1 [list info exists $var]] { if [uplevel 1 [list array exists $var]] { set saved_arrays($var) [uplevel 1 [list array get $var]] ..." (procedure "save_vars" line 11) invoked from within "save_vars { env(LD_PRELOAD) } { if { ![info exists env(LD_PRELOAD) ] || $env(LD_PRELOAD) == "" } { set env(LD_PRELOAD) "$lib" } else { ..." (procedure "gdb_spawn_with_ld_preload" line 4) invoked from within "gdb_spawn_with_ld_preload $libsegfault """ ... There are several things here interacting with environment variable LD_PRELOAD: - the expect "binary" build/gdb/testsuite/expect-read1 with does export LD_PRELOAD=build/gdb/testsuite/read1.so before calling native expect - read1.so which does unsetenv ("LD_PRELOAD") upon first call to read - the test-case, which wants to set or append libSegFault.so to LD_PRELOAD The error occurs when accessing $env(LD_PRELOAD), in a branch where "info exists env(LD_PRELOAD)" returns true. AFAIU, this is https://core.tcl-lang.org/tcl/tktview?name=67fd4f973a "incorrect results of 'info exists' when unset env var in one interp and check for existence from another interp". Work around the tcl bug by not unsetting the variable, but setting it to "" instead: ... - unsetenv ("LD_PRELOAD"); + setenv ("LD_PRELOAD", "", 1); ... Verified that reverting commit de28a3b72e "[gdb/testsuite, 2/2] Fix gdb.linespec/explicit.exp with check-read1" reintroduced the check-read1 failure in gdb.linespec/explicit.exp. This fixes a similar error in attach-slow-waitpid.exp, which also sets LD_PRELOAD. Tested on x86_64-linux with check-read1. gdb/testsuite/ChangeLog: 2019-07-30 Tom de Vries * lib/read1.c (read): Don't use unsetenv (v), use setenv (v, "", 1) instead. --- gdb/testsuite/ChangeLog | 5 +++++ gdb/testsuite/lib/read1.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 3476d7f46f2..0bf6be994e4 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-07-30 Tom de Vries + + * lib/read1.c (read): Don't use unsetenv (v), use setenv (v, "", 1) + instead. + 2019-07-30 Tom de Vries PR testsuite/24834 diff --git a/gdb/testsuite/lib/read1.c b/gdb/testsuite/lib/read1.c index 05476613469..bee0945543e 100644 --- a/gdb/testsuite/lib/read1.c +++ b/gdb/testsuite/lib/read1.c @@ -31,7 +31,11 @@ read (int fd, void *buf, size_t count) static ssize_t (*read2) (int fd, void *buf, size_t count) = NULL; if (read2 == NULL) { - unsetenv ("LD_PRELOAD"); + /* Use setenv (v, "", 1) rather than unsetenv (v) to work around + https://core.tcl-lang.org/tcl/tktview?name=67fd4f973a "incorrect + results of 'info exists' when unset env var in one interp and check + for existence from another interp". */ + setenv ("LD_PRELOAD", "", 1); read2 = dlsym (RTLD_NEXT, "read"); } if (count > 1 && isatty (fd) >= 1) -- 2.30.2