[v2,8/8] Make print-file-var.exp test attribute visibility hidden, dlopen, and main symbol

Message ID 20190801170412.5553-9-tromey@adacore.com
State Superseded
Headers show
Series
  • Handle copy relocations and add $_ada_exception
Related show

Commit Message

Tom Tromey Aug. 1, 2019, 5:04 p.m.
From: Pedro Alves <palves@redhat.com>


Make gdb.base/print-file-var.exp test all combinations of:

  - attribute hidden in the this_version_id symbols or not
  - dlopen or not
  - this_version_id symbol in main file or not

2019-08-01  Pedro Alves  <palves@redhat.com>

	* gdb.base/print-file-var-lib1.c: Include <stdio.h> and
	"print-file-var.h".
	(this_version_id) Use ATTRIBUTE_VISIBILITY.
	(get_version_1): Print this_version_id and its address.
	* gdb.base/print-file-var-lib2.c: Include <stdio.h> and
	"print-file-var.h".
	(this_version_id) Use ATTRIBUTE_VISIBILITY.
	(get_version_2): Print this_version_id and its address.
	* gdb.base/print-file-var-main.c: Include <dlfcn.h>, <assert.h>,
	<stddef.h> and "print-file-var.h".
	[VERSION_ID_MAIN] (this_version_id): Define.
	(main): Define v0.  Use dlopen if SHLIB_NAME is defined.
	* gdb.base/print-file-var.exp (test): New, factored out from top
	level.
	(top level): Test all combinations of attribute hidden or not,
	dlopen or not, and this_version_id symbol in main file or not.
---
 gdb/testsuite/ChangeLog                      |  19 ++
 gdb/testsuite/gdb.base/print-file-var-lib1.c |   7 +-
 gdb/testsuite/gdb.base/print-file-var-lib2.c |   6 +-
 gdb/testsuite/gdb.base/print-file-var-main.c |  38 +++-
 gdb/testsuite/gdb.base/print-file-var.exp    | 181 ++++++++++++-------
 gdb/testsuite/gdb.base/print-file-var.h      |  26 +++
 6 files changed, 199 insertions(+), 78 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/print-file-var.h

-- 
2.20.1

Comments

Andrew Burgess Aug. 20, 2019, 1:41 p.m. | #1
* Tom Tromey <tromey@adacore.com> [2019-08-01 11:04:12 -0600]:

> From: Pedro Alves <palves@redhat.com>

> 

> Make gdb.base/print-file-var.exp test all combinations of:

> 

>   - attribute hidden in the this_version_id symbols or not

>   - dlopen or not

>   - this_version_id symbol in main file or not

> 

> 2019-08-01  Pedro Alves  <palves@redhat.com>

> 

> 	* gdb.base/print-file-var-lib1.c: Include <stdio.h> and

> 	"print-file-var.h".

> 	(this_version_id) Use ATTRIBUTE_VISIBILITY.

> 	(get_version_1): Print this_version_id and its address.

> 	* gdb.base/print-file-var-lib2.c: Include <stdio.h> and

> 	"print-file-var.h".

> 	(this_version_id) Use ATTRIBUTE_VISIBILITY.

> 	(get_version_2): Print this_version_id and its address.

> 	* gdb.base/print-file-var-main.c: Include <dlfcn.h>, <assert.h>,

> 	<stddef.h> and "print-file-var.h".

> 	[VERSION_ID_MAIN] (this_version_id): Define.

> 	(main): Define v0.  Use dlopen if SHLIB_NAME is defined.

> 	* gdb.base/print-file-var.exp (test): New, factored out from top

> 	level.

> 	(top level): Test all combinations of attribute hidden or not,

> 	dlopen or not, and this_version_id symbol in main file or not.


With this patch series applied to current(ish) HEAD (ac533243bea) I
see the following failures:

    FAIL: gdb.base/print-file-var.exp: hidden=0: dlopen=0: version_id_main=0: 'print-file-var-lib2.c'::this_version_id == v2
    FAIL: gdb.base/print-file-var.exp: hidden=0: dlopen=1: version_id_main=0: 'print-file-var-lib2.c'::this_version_id == v2
    FAIL: gdb.base/print-file-var.exp: hidden=1: dlopen=0: version_id_main=1: 'print-file-var-lib1.c'::this_version_id == v1
    FAIL: gdb.base/print-file-var.exp: hidden=1: dlopen=0: version_id_main=1: 'print-file-var-lib2.c'::this_version_id == v2
    FAIL: gdb.base/print-file-var.exp: hidden=1: dlopen=1: version_id_main=1: 'print-file-var-lib1.c'::this_version_id == v1
    FAIL: gdb.base/print-file-var.exp: hidden=1: dlopen=1: version_id_main=1: 'print-file-var-lib2.c'::this_version_id == v2

This is using GCC versions:

  * gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-6), and
  * gcc (GCC) 9.2.0

Thanks,

Andrew



> ---

>  gdb/testsuite/ChangeLog                      |  19 ++

>  gdb/testsuite/gdb.base/print-file-var-lib1.c |   7 +-

>  gdb/testsuite/gdb.base/print-file-var-lib2.c |   6 +-

>  gdb/testsuite/gdb.base/print-file-var-main.c |  38 +++-

>  gdb/testsuite/gdb.base/print-file-var.exp    | 181 ++++++++++++-------

>  gdb/testsuite/gdb.base/print-file-var.h      |  26 +++

>  6 files changed, 199 insertions(+), 78 deletions(-)

>  create mode 100644 gdb/testsuite/gdb.base/print-file-var.h

> 

> diff --git a/gdb/testsuite/gdb.base/print-file-var-lib1.c b/gdb/testsuite/gdb.base/print-file-var-lib1.c

> index b5f4fb90b39..aec04a9b02b 100644

> --- a/gdb/testsuite/gdb.base/print-file-var-lib1.c

> +++ b/gdb/testsuite/gdb.base/print-file-var-lib1.c

> @@ -14,10 +14,15 @@

>     You should have received a copy of the GNU General Public License

>     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

>  

> -int this_version_id = 104;

> +#include <stdio.h>

> +#include "print-file-var.h"

> +

> +ATTRIBUTE_VISIBILITY int this_version_id = 104;

>  

>  int

>  get_version_1 (void)

>  {

> +  printf ("get_version_1: &this_version_id=%p, this_version_id=%d\n", &this_version_id, this_version_id);

> +

>    return this_version_id;

>  }

> diff --git a/gdb/testsuite/gdb.base/print-file-var-lib2.c b/gdb/testsuite/gdb.base/print-file-var-lib2.c

> index 28bd1acb17f..4dfdfa04c99 100644

> --- a/gdb/testsuite/gdb.base/print-file-var-lib2.c

> +++ b/gdb/testsuite/gdb.base/print-file-var-lib2.c

> @@ -14,10 +14,14 @@

>     You should have received a copy of the GNU General Public License

>     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

>  

> -int this_version_id = 203;

> +#include <stdio.h>

> +#include "print-file-var.h"

> +

> +ATTRIBUTE_VISIBILITY int this_version_id = 203;

>  

>  int

>  get_version_2 (void)

>  {

> +  printf ("get_version_2: &this_version_id=%p, this_version_id=%d\n", &this_version_id, this_version_id);

>    return this_version_id;

>  }

> diff --git a/gdb/testsuite/gdb.base/print-file-var-main.c b/gdb/testsuite/gdb.base/print-file-var-main.c

> index ddc54f14d98..29d4fed22d1 100644

> --- a/gdb/testsuite/gdb.base/print-file-var-main.c

> +++ b/gdb/testsuite/gdb.base/print-file-var-main.c

> @@ -14,21 +14,45 @@

>     You should have received a copy of the GNU General Public License

>     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

>  

> +#ifdef SHLIB_NAME

> +# include <dlfcn.h>

> +#endif

> +

> +#include <assert.h>

> +#include <stddef.h>

> +

> +#include "print-file-var.h"

> +

>  extern int get_version_1 (void);

>  extern int get_version_2 (void);

>  

> +#if VERSION_ID_MAIN

> +ATTRIBUTE_VISIBILITY int this_version_id = 55;

> +#endif

> +

>  int

>  main (void)

>  {

> +#if VERSION_ID_MAIN

> +  int vm = this_version_id;

> +#endif

>    int v1 = get_version_1 ();

> -  int v2 = get_version_2 ();

> +  int v2;

>  

> -  if (v1 != 104)

> -    return 1;

> -  /* The value returned by get_version_2 depends on the target system.  */

> -  if (v2 != 104 && v2 != 203)

> -    return 2;

> +#ifdef SHLIB_NAME

> +  {

> +    void *handle = dlopen (SHLIB_NAME, RTLD_LAZY);

> +    int (*getver2) (void);

> +

> +    assert (handle != NULL);

> +

> +    getver2 = (int (*)(void)) dlsym (handle, "get_version_2");

> +

> +    v2 = getver2 ();

> +  }

> +#else

> +  v2 = get_version_2 ();

> +#endif

>  

>    return 0; /* STOP */

>  }

> -

> diff --git a/gdb/testsuite/gdb.base/print-file-var.exp b/gdb/testsuite/gdb.base/print-file-var.exp

> index 1f733fb4dee..a37cca70de6 100644

> --- a/gdb/testsuite/gdb.base/print-file-var.exp

> +++ b/gdb/testsuite/gdb.base/print-file-var.exp

> @@ -17,76 +17,119 @@ if {[skip_shlib_tests]} {

>      return -1

>  }

>  

> -set executable print-file-var-main

> +proc test {hidden dlopen version_id_main} {

> +    global srcdir subdir

> +

> +    set main "print-file-var-main"

> +

> +    set suffix "-hidden$hidden-dlopen$dlopen-version_id_main$version_id_main"

> +

> +    set executable $main$suffix

> +

> +    set lib1 "print-file-var-lib1"

> +    set lib2 "print-file-var-lib2"

> +

> +    set libobj1 [standard_output_file ${lib1}$suffix.so]

> +    set libobj2 [standard_output_file ${lib2}$suffix.so]

> +

> +    set lib_opts { debug additional_flags=-fPIC }

> +    lappend lib_opts "additional_flags=-DHIDDEN=$hidden"

> +

> +    if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib1}.c \

> +	      ${libobj1} \

> +	      ${lib_opts} ] != "" } {

> +	return -1

> +    }

> +    if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib2}.c \

> +	      ${libobj2} \

> +	      ${lib_opts} ] != "" } {

> +	return -1

> +    }

> +

> +    set main_opts [list debug shlib=${libobj1}]

> +

> +    if {$dlopen} {

> +	lappend main_opts "shlib_load" \

> +	    "additional_flags=-DSHLIB_NAME=\"$libobj2\""

> +    } else {

> +	lappend main_opts "shlib=${libobj2}"

> +    }

> +

> +    lappend main_opts "additional_flags=-DVERSION_ID_MAIN=$version_id_main"

> +

> +    if { [gdb_compile "${srcdir}/${subdir}/${main}.c" \

> +	      [standard_output_file ${executable}] \

> +	      executable \

> +	      $main_opts]

> +	 != ""} {

> +	return -1

> +    }

> +

> +    clean_restart $executable

> +    gdb_load_shlib $libobj1

> +    gdb_load_shlib $libobj2

> +

> +    if ![runto_main] {

> +	untested "could not run to main"

> +	return -1

> +    }

> +

> +    # Try printing "this_version_num" qualified with the name of the file

> +    # where the variables are defined.  There are three global variables

> +    # with that name, and some systems such as GNU/Linux merge them

> +    # into one single entity, while some other systems such as Windows

> +    # keep them separate.  In the first situation, we have to verify

> +    # that GDB does not randomly select the wrong instance, even when

> +    # a specific filename is used to qualified the lookup.  And in the

> +    # second case, we have to verify that GDB does select the instance

> +    # defined in the given filename.

> +    #

> +    # To avoid adding target-specific code in this testcase, the program

> +    # sets three local variables named 'vm', 'v1' and 'v2' with the value of

> +    # our global variables.  This allows us to compare the value that

> +    # GDB returns for each query against the actual value seen by

> +    # the program itself.

> +

> +    # Get past the initialization of the v* variables.

> +

> +    set bp_location \

> +	[gdb_get_line_number "STOP" "${main}.c"]

> +    gdb_test "break $main.c:$bp_location" \

> +	"Breakpoint \[0-9\]+ at 0x\[0-9a-fA-F\]+: .*" \

> +	"breapoint at STOP marker"

> +

> +    gdb_test "continue" \

> +	"Breakpoint \[0-9\]+, main \\(\\) at.*STOP.*" \

> +	"continue to STOP marker"

> +

> +    # Now check the value of this_version_id in all of

> +    # print-file-var-main.c, print-file-var-lib1.c and

> +    # print-file-var-lib2.c.

> +

> +    # Compare the values of $sym1 and $sym2.

> +    proc compare {sym1 sym2} {

> +	# Done this way instead of comparing the symbols with "print $sym1

> +	# == sym2" in GDB directly so that the values of the symbols end

> +	# up visible in the logs, for debug purposes.

> +	set vsym1 [get_integer_valueof $sym1 -1]

> +	set vsym2 [get_integer_valueof $sym2 -1]

> +	gdb_assert {$vsym1 == $vsym2} "$sym1 == $sym2"

> +    }

> +

> +    if $version_id_main {

> +	compare "'print-file-var-main.c'::this_version_id" "vm"

> +	compare "this_version_id" "vm"

> +    }

> +

> +    compare "'print-file-var-lib1.c'::this_version_id" "v1"

> +    compare "'print-file-var-lib2.c'::this_version_id" "v2"

>  

> -set lib1 "print-file-var-lib1"

> -set lib2 "print-file-var-lib2"

> -

> -set libobj1 [standard_output_file ${lib1}.so]

> -set libobj2 [standard_output_file ${lib2}.so]

> -

> -set lib_opts { debug additional_flags=-fPIC }

> -

> -if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib1}.c \

> -                        ${libobj1} \

> -                        ${lib_opts} ] != "" } {

> -    return -1

>  }

> -if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib2}.c \

> -                        ${libobj2} \

> -                        ${lib_opts} ] != "" } {

> -    return -1

> -}

> -if { [gdb_compile "${srcdir}/${subdir}/${executable}.c" \

> -                  [standard_output_file ${executable}] \

> -                  executable \

> -                  [list debug shlib=${libobj1} shlib=${libobj2}]]

> -     != ""} {

> -    return -1

> -}

> -

> -clean_restart $executable

> -gdb_load_shlib $libobj1

> -gdb_load_shlib $libobj2

>  

> -if ![runto_main] {

> -    untested "could not run to main"

> -    return -1

> +foreach_with_prefix hidden {0 1} {

> +    foreach_with_prefix dlopen {0 1} {

> +	foreach_with_prefix version_id_main {0 1} {

> +	    test $hidden $dlopen $version_id_main

> +	}

> +    }

>  }

> -

> -# Try printing "this_version_num" qualified with the name of the file

> -# where the variables are defined.  There are two global variables

> -# with that name, and some systems such as GNU/Linux merge them

> -# into one single entity, while some other systems such as Windows

> -# keep them separate.  In the first situation, we have to verify

> -# that GDB does not randomly select the wrong instance, even when

> -# a specific filename is used to qualified the lookup.  And in the

> -# second case, we have to verify that GDB does select the instance

> -# defined in the given filename.

> -#

> -# To avoid adding target-specific code in this testcase, the program

> -# sets two local variable named 'v1' and 'v2' with the value of

> -# our global variables.  This allows us to compare the value that

> -# GDB returns for each query against the actual value seen by

> -# the program itself.

> -

> -# Get past the initialization of variables 'v1' and 'v2'.

> -

> -set bp_location \

> -    [gdb_get_line_number "STOP" "${executable}.c"]

> -gdb_test "break $executable.c:$bp_location" \

> -         "Breakpoint \[0-9\]+ at 0x\[0-9a-fA-F\]+: .*" \

> -         "breapoint past v1 & v2 initialization"

> -

> -gdb_test "continue" \

> -         "Breakpoint \[0-9\]+, main \\(\\) at.*STOP.*" \

> -         "continue to STOP marker"

> -

> -# Now check the value of this_version_id in both print-file-var-lib1.c

> -# and print-file-var-lib2.c.

> -

> -gdb_test "print 'print-file-var-lib1.c'::this_version_id == v1" \

> -         " = 1"

> -

> -gdb_test "print 'print-file-var-lib2.c'::this_version_id == v2" \

> -         " = 1"

> diff --git a/gdb/testsuite/gdb.base/print-file-var.h b/gdb/testsuite/gdb.base/print-file-var.h

> new file mode 100644

> index 00000000000..fe7a3460edb

> --- /dev/null

> +++ b/gdb/testsuite/gdb.base/print-file-var.h

> @@ -0,0 +1,26 @@

> +/* This testcase is part of GDB, the GNU debugger.

> +   Copyright 2019 Free Software Foundation, Inc.

> +

> +   This program is free software; you can redistribute it and/or modify

> +   it under the terms of the GNU General Public License as published by

> +   the Free Software Foundation; either version 3 of the License, or

> +   (at your option) any later version.

> +

> +   This program is distributed in the hope that it will be useful,

> +   but WITHOUT ANY WARRANTY; without even the implied warranty of

> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

> +   GNU General Public License for more details.

> +

> +   You should have received a copy of the GNU General Public License

> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

> +

> +#ifndef PRINT_FILE_VAR_H

> +#define PRINT_FILE_VAR_H

> +

> +#if HIDDEN

> +# define ATTRIBUTE_VISIBILITY __attribute__((visibility ("hidden")))

> +#else

> +# define ATTRIBUTE_VISIBILITY

> +#endif

> +

> +#endif /* PRINT_FILE_VAR_H */

> -- 

> 2.20.1

>
Andrew Burgess Aug. 21, 2019, 2:35 p.m. | #2
* Andrew Burgess <andrew.burgess@embecosm.com> [2019-08-20 14:41:18 +0100]:

> * Tom Tromey <tromey@adacore.com> [2019-08-01 11:04:12 -0600]:

> 

> > From: Pedro Alves <palves@redhat.com>

> > 

> > Make gdb.base/print-file-var.exp test all combinations of:

> > 

> >   - attribute hidden in the this_version_id symbols or not

> >   - dlopen or not

> >   - this_version_id symbol in main file or not

> > 

> > 2019-08-01  Pedro Alves  <palves@redhat.com>

> > 

> > 	* gdb.base/print-file-var-lib1.c: Include <stdio.h> and

> > 	"print-file-var.h".

> > 	(this_version_id) Use ATTRIBUTE_VISIBILITY.

> > 	(get_version_1): Print this_version_id and its address.

> > 	* gdb.base/print-file-var-lib2.c: Include <stdio.h> and

> > 	"print-file-var.h".

> > 	(this_version_id) Use ATTRIBUTE_VISIBILITY.

> > 	(get_version_2): Print this_version_id and its address.

> > 	* gdb.base/print-file-var-main.c: Include <dlfcn.h>, <assert.h>,

> > 	<stddef.h> and "print-file-var.h".

> > 	[VERSION_ID_MAIN] (this_version_id): Define.

> > 	(main): Define v0.  Use dlopen if SHLIB_NAME is defined.

> > 	* gdb.base/print-file-var.exp (test): New, factored out from top

> > 	level.

> > 	(top level): Test all combinations of attribute hidden or not,

> > 	dlopen or not, and this_version_id symbol in main file or not.

> 

> With this patch series applied to current(ish) HEAD (ac533243bea) I

> see the following failures:

> 

>     FAIL: gdb.base/print-file-var.exp: hidden=0: dlopen=0: version_id_main=0: 'print-file-var-lib2.c'::this_version_id == v2

>     FAIL: gdb.base/print-file-var.exp: hidden=0: dlopen=1: version_id_main=0: 'print-file-var-lib2.c'::this_version_id == v2

>     FAIL: gdb.base/print-file-var.exp: hidden=1: dlopen=0: version_id_main=1: 'print-file-var-lib1.c'::this_version_id == v1

>     FAIL: gdb.base/print-file-var.exp: hidden=1: dlopen=0: version_id_main=1: 'print-file-var-lib2.c'::this_version_id == v2

>     FAIL: gdb.base/print-file-var.exp: hidden=1: dlopen=1: version_id_main=1: 'print-file-var-lib1.c'::this_version_id == v1

>     FAIL: gdb.base/print-file-var.exp: hidden=1: dlopen=1: version_id_main=1: 'print-file-var-lib2.c'::this_version_id == v2

> 

> This is using GCC versions:

> 

>   * gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-6), and

>   * gcc (GCC) 9.2.0


Turns out this is operator error - if turns out I have to apply the
patches _correctly_ in order to not see any errors - who'd have
thought it!

Sorry for the noise.

Andrew




> 

> Thanks,

> 

> Andrew

> 

> 

> 

> > ---

> >  gdb/testsuite/ChangeLog                      |  19 ++

> >  gdb/testsuite/gdb.base/print-file-var-lib1.c |   7 +-

> >  gdb/testsuite/gdb.base/print-file-var-lib2.c |   6 +-

> >  gdb/testsuite/gdb.base/print-file-var-main.c |  38 +++-

> >  gdb/testsuite/gdb.base/print-file-var.exp    | 181 ++++++++++++-------

> >  gdb/testsuite/gdb.base/print-file-var.h      |  26 +++

> >  6 files changed, 199 insertions(+), 78 deletions(-)

> >  create mode 100644 gdb/testsuite/gdb.base/print-file-var.h

> > 

> > diff --git a/gdb/testsuite/gdb.base/print-file-var-lib1.c b/gdb/testsuite/gdb.base/print-file-var-lib1.c

> > index b5f4fb90b39..aec04a9b02b 100644

> > --- a/gdb/testsuite/gdb.base/print-file-var-lib1.c

> > +++ b/gdb/testsuite/gdb.base/print-file-var-lib1.c

> > @@ -14,10 +14,15 @@

> >     You should have received a copy of the GNU General Public License

> >     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

> >  

> > -int this_version_id = 104;

> > +#include <stdio.h>

> > +#include "print-file-var.h"

> > +

> > +ATTRIBUTE_VISIBILITY int this_version_id = 104;

> >  

> >  int

> >  get_version_1 (void)

> >  {

> > +  printf ("get_version_1: &this_version_id=%p, this_version_id=%d\n", &this_version_id, this_version_id);

> > +

> >    return this_version_id;

> >  }

> > diff --git a/gdb/testsuite/gdb.base/print-file-var-lib2.c b/gdb/testsuite/gdb.base/print-file-var-lib2.c

> > index 28bd1acb17f..4dfdfa04c99 100644

> > --- a/gdb/testsuite/gdb.base/print-file-var-lib2.c

> > +++ b/gdb/testsuite/gdb.base/print-file-var-lib2.c

> > @@ -14,10 +14,14 @@

> >     You should have received a copy of the GNU General Public License

> >     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

> >  

> > -int this_version_id = 203;

> > +#include <stdio.h>

> > +#include "print-file-var.h"

> > +

> > +ATTRIBUTE_VISIBILITY int this_version_id = 203;

> >  

> >  int

> >  get_version_2 (void)

> >  {

> > +  printf ("get_version_2: &this_version_id=%p, this_version_id=%d\n", &this_version_id, this_version_id);

> >    return this_version_id;

> >  }

> > diff --git a/gdb/testsuite/gdb.base/print-file-var-main.c b/gdb/testsuite/gdb.base/print-file-var-main.c

> > index ddc54f14d98..29d4fed22d1 100644

> > --- a/gdb/testsuite/gdb.base/print-file-var-main.c

> > +++ b/gdb/testsuite/gdb.base/print-file-var-main.c

> > @@ -14,21 +14,45 @@

> >     You should have received a copy of the GNU General Public License

> >     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

> >  

> > +#ifdef SHLIB_NAME

> > +# include <dlfcn.h>

> > +#endif

> > +

> > +#include <assert.h>

> > +#include <stddef.h>

> > +

> > +#include "print-file-var.h"

> > +

> >  extern int get_version_1 (void);

> >  extern int get_version_2 (void);

> >  

> > +#if VERSION_ID_MAIN

> > +ATTRIBUTE_VISIBILITY int this_version_id = 55;

> > +#endif

> > +

> >  int

> >  main (void)

> >  {

> > +#if VERSION_ID_MAIN

> > +  int vm = this_version_id;

> > +#endif

> >    int v1 = get_version_1 ();

> > -  int v2 = get_version_2 ();

> > +  int v2;

> >  

> > -  if (v1 != 104)

> > -    return 1;

> > -  /* The value returned by get_version_2 depends on the target system.  */

> > -  if (v2 != 104 && v2 != 203)

> > -    return 2;

> > +#ifdef SHLIB_NAME

> > +  {

> > +    void *handle = dlopen (SHLIB_NAME, RTLD_LAZY);

> > +    int (*getver2) (void);

> > +

> > +    assert (handle != NULL);

> > +

> > +    getver2 = (int (*)(void)) dlsym (handle, "get_version_2");

> > +

> > +    v2 = getver2 ();

> > +  }

> > +#else

> > +  v2 = get_version_2 ();

> > +#endif

> >  

> >    return 0; /* STOP */

> >  }

> > -

> > diff --git a/gdb/testsuite/gdb.base/print-file-var.exp b/gdb/testsuite/gdb.base/print-file-var.exp

> > index 1f733fb4dee..a37cca70de6 100644

> > --- a/gdb/testsuite/gdb.base/print-file-var.exp

> > +++ b/gdb/testsuite/gdb.base/print-file-var.exp

> > @@ -17,76 +17,119 @@ if {[skip_shlib_tests]} {

> >      return -1

> >  }

> >  

> > -set executable print-file-var-main

> > +proc test {hidden dlopen version_id_main} {

> > +    global srcdir subdir

> > +

> > +    set main "print-file-var-main"

> > +

> > +    set suffix "-hidden$hidden-dlopen$dlopen-version_id_main$version_id_main"

> > +

> > +    set executable $main$suffix

> > +

> > +    set lib1 "print-file-var-lib1"

> > +    set lib2 "print-file-var-lib2"

> > +

> > +    set libobj1 [standard_output_file ${lib1}$suffix.so]

> > +    set libobj2 [standard_output_file ${lib2}$suffix.so]

> > +

> > +    set lib_opts { debug additional_flags=-fPIC }

> > +    lappend lib_opts "additional_flags=-DHIDDEN=$hidden"

> > +

> > +    if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib1}.c \

> > +	      ${libobj1} \

> > +	      ${lib_opts} ] != "" } {

> > +	return -1

> > +    }

> > +    if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib2}.c \

> > +	      ${libobj2} \

> > +	      ${lib_opts} ] != "" } {

> > +	return -1

> > +    }

> > +

> > +    set main_opts [list debug shlib=${libobj1}]

> > +

> > +    if {$dlopen} {

> > +	lappend main_opts "shlib_load" \

> > +	    "additional_flags=-DSHLIB_NAME=\"$libobj2\""

> > +    } else {

> > +	lappend main_opts "shlib=${libobj2}"

> > +    }

> > +

> > +    lappend main_opts "additional_flags=-DVERSION_ID_MAIN=$version_id_main"

> > +

> > +    if { [gdb_compile "${srcdir}/${subdir}/${main}.c" \

> > +	      [standard_output_file ${executable}] \

> > +	      executable \

> > +	      $main_opts]

> > +	 != ""} {

> > +	return -1

> > +    }

> > +

> > +    clean_restart $executable

> > +    gdb_load_shlib $libobj1

> > +    gdb_load_shlib $libobj2

> > +

> > +    if ![runto_main] {

> > +	untested "could not run to main"

> > +	return -1

> > +    }

> > +

> > +    # Try printing "this_version_num" qualified with the name of the file

> > +    # where the variables are defined.  There are three global variables

> > +    # with that name, and some systems such as GNU/Linux merge them

> > +    # into one single entity, while some other systems such as Windows

> > +    # keep them separate.  In the first situation, we have to verify

> > +    # that GDB does not randomly select the wrong instance, even when

> > +    # a specific filename is used to qualified the lookup.  And in the

> > +    # second case, we have to verify that GDB does select the instance

> > +    # defined in the given filename.

> > +    #

> > +    # To avoid adding target-specific code in this testcase, the program

> > +    # sets three local variables named 'vm', 'v1' and 'v2' with the value of

> > +    # our global variables.  This allows us to compare the value that

> > +    # GDB returns for each query against the actual value seen by

> > +    # the program itself.

> > +

> > +    # Get past the initialization of the v* variables.

> > +

> > +    set bp_location \

> > +	[gdb_get_line_number "STOP" "${main}.c"]

> > +    gdb_test "break $main.c:$bp_location" \

> > +	"Breakpoint \[0-9\]+ at 0x\[0-9a-fA-F\]+: .*" \

> > +	"breapoint at STOP marker"

> > +

> > +    gdb_test "continue" \

> > +	"Breakpoint \[0-9\]+, main \\(\\) at.*STOP.*" \

> > +	"continue to STOP marker"

> > +

> > +    # Now check the value of this_version_id in all of

> > +    # print-file-var-main.c, print-file-var-lib1.c and

> > +    # print-file-var-lib2.c.

> > +

> > +    # Compare the values of $sym1 and $sym2.

> > +    proc compare {sym1 sym2} {

> > +	# Done this way instead of comparing the symbols with "print $sym1

> > +	# == sym2" in GDB directly so that the values of the symbols end

> > +	# up visible in the logs, for debug purposes.

> > +	set vsym1 [get_integer_valueof $sym1 -1]

> > +	set vsym2 [get_integer_valueof $sym2 -1]

> > +	gdb_assert {$vsym1 == $vsym2} "$sym1 == $sym2"

> > +    }

> > +

> > +    if $version_id_main {

> > +	compare "'print-file-var-main.c'::this_version_id" "vm"

> > +	compare "this_version_id" "vm"

> > +    }

> > +

> > +    compare "'print-file-var-lib1.c'::this_version_id" "v1"

> > +    compare "'print-file-var-lib2.c'::this_version_id" "v2"

> >  

> > -set lib1 "print-file-var-lib1"

> > -set lib2 "print-file-var-lib2"

> > -

> > -set libobj1 [standard_output_file ${lib1}.so]

> > -set libobj2 [standard_output_file ${lib2}.so]

> > -

> > -set lib_opts { debug additional_flags=-fPIC }

> > -

> > -if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib1}.c \

> > -                        ${libobj1} \

> > -                        ${lib_opts} ] != "" } {

> > -    return -1

> >  }

> > -if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib2}.c \

> > -                        ${libobj2} \

> > -                        ${lib_opts} ] != "" } {

> > -    return -1

> > -}

> > -if { [gdb_compile "${srcdir}/${subdir}/${executable}.c" \

> > -                  [standard_output_file ${executable}] \

> > -                  executable \

> > -                  [list debug shlib=${libobj1} shlib=${libobj2}]]

> > -     != ""} {

> > -    return -1

> > -}

> > -

> > -clean_restart $executable

> > -gdb_load_shlib $libobj1

> > -gdb_load_shlib $libobj2

> >  

> > -if ![runto_main] {

> > -    untested "could not run to main"

> > -    return -1

> > +foreach_with_prefix hidden {0 1} {

> > +    foreach_with_prefix dlopen {0 1} {

> > +	foreach_with_prefix version_id_main {0 1} {

> > +	    test $hidden $dlopen $version_id_main

> > +	}

> > +    }

> >  }

> > -

> > -# Try printing "this_version_num" qualified with the name of the file

> > -# where the variables are defined.  There are two global variables

> > -# with that name, and some systems such as GNU/Linux merge them

> > -# into one single entity, while some other systems such as Windows

> > -# keep them separate.  In the first situation, we have to verify

> > -# that GDB does not randomly select the wrong instance, even when

> > -# a specific filename is used to qualified the lookup.  And in the

> > -# second case, we have to verify that GDB does select the instance

> > -# defined in the given filename.

> > -#

> > -# To avoid adding target-specific code in this testcase, the program

> > -# sets two local variable named 'v1' and 'v2' with the value of

> > -# our global variables.  This allows us to compare the value that

> > -# GDB returns for each query against the actual value seen by

> > -# the program itself.

> > -

> > -# Get past the initialization of variables 'v1' and 'v2'.

> > -

> > -set bp_location \

> > -    [gdb_get_line_number "STOP" "${executable}.c"]

> > -gdb_test "break $executable.c:$bp_location" \

> > -         "Breakpoint \[0-9\]+ at 0x\[0-9a-fA-F\]+: .*" \

> > -         "breapoint past v1 & v2 initialization"

> > -

> > -gdb_test "continue" \

> > -         "Breakpoint \[0-9\]+, main \\(\\) at.*STOP.*" \

> > -         "continue to STOP marker"

> > -

> > -# Now check the value of this_version_id in both print-file-var-lib1.c

> > -# and print-file-var-lib2.c.

> > -

> > -gdb_test "print 'print-file-var-lib1.c'::this_version_id == v1" \

> > -         " = 1"

> > -

> > -gdb_test "print 'print-file-var-lib2.c'::this_version_id == v2" \

> > -         " = 1"

> > diff --git a/gdb/testsuite/gdb.base/print-file-var.h b/gdb/testsuite/gdb.base/print-file-var.h

> > new file mode 100644

> > index 00000000000..fe7a3460edb

> > --- /dev/null

> > +++ b/gdb/testsuite/gdb.base/print-file-var.h

> > @@ -0,0 +1,26 @@

> > +/* This testcase is part of GDB, the GNU debugger.

> > +   Copyright 2019 Free Software Foundation, Inc.

> > +

> > +   This program is free software; you can redistribute it and/or modify

> > +   it under the terms of the GNU General Public License as published by

> > +   the Free Software Foundation; either version 3 of the License, or

> > +   (at your option) any later version.

> > +

> > +   This program is distributed in the hope that it will be useful,

> > +   but WITHOUT ANY WARRANTY; without even the implied warranty of

> > +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

> > +   GNU General Public License for more details.

> > +

> > +   You should have received a copy of the GNU General Public License

> > +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

> > +

> > +#ifndef PRINT_FILE_VAR_H

> > +#define PRINT_FILE_VAR_H

> > +

> > +#if HIDDEN

> > +# define ATTRIBUTE_VISIBILITY __attribute__((visibility ("hidden")))

> > +#else

> > +# define ATTRIBUTE_VISIBILITY

> > +#endif

> > +

> > +#endif /* PRINT_FILE_VAR_H */

> > -- 

> > 2.20.1

> >

Patch

diff --git a/gdb/testsuite/gdb.base/print-file-var-lib1.c b/gdb/testsuite/gdb.base/print-file-var-lib1.c
index b5f4fb90b39..aec04a9b02b 100644
--- a/gdb/testsuite/gdb.base/print-file-var-lib1.c
+++ b/gdb/testsuite/gdb.base/print-file-var-lib1.c
@@ -14,10 +14,15 @@ 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-int this_version_id = 104;
+#include <stdio.h>
+#include "print-file-var.h"
+
+ATTRIBUTE_VISIBILITY int this_version_id = 104;
 
 int
 get_version_1 (void)
 {
+  printf ("get_version_1: &this_version_id=%p, this_version_id=%d\n", &this_version_id, this_version_id);
+
   return this_version_id;
 }
diff --git a/gdb/testsuite/gdb.base/print-file-var-lib2.c b/gdb/testsuite/gdb.base/print-file-var-lib2.c
index 28bd1acb17f..4dfdfa04c99 100644
--- a/gdb/testsuite/gdb.base/print-file-var-lib2.c
+++ b/gdb/testsuite/gdb.base/print-file-var-lib2.c
@@ -14,10 +14,14 @@ 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-int this_version_id = 203;
+#include <stdio.h>
+#include "print-file-var.h"
+
+ATTRIBUTE_VISIBILITY int this_version_id = 203;
 
 int
 get_version_2 (void)
 {
+  printf ("get_version_2: &this_version_id=%p, this_version_id=%d\n", &this_version_id, this_version_id);
   return this_version_id;
 }
diff --git a/gdb/testsuite/gdb.base/print-file-var-main.c b/gdb/testsuite/gdb.base/print-file-var-main.c
index ddc54f14d98..29d4fed22d1 100644
--- a/gdb/testsuite/gdb.base/print-file-var-main.c
+++ b/gdb/testsuite/gdb.base/print-file-var-main.c
@@ -14,21 +14,45 @@ 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#ifdef SHLIB_NAME
+# include <dlfcn.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+
+#include "print-file-var.h"
+
 extern int get_version_1 (void);
 extern int get_version_2 (void);
 
+#if VERSION_ID_MAIN
+ATTRIBUTE_VISIBILITY int this_version_id = 55;
+#endif
+
 int
 main (void)
 {
+#if VERSION_ID_MAIN
+  int vm = this_version_id;
+#endif
   int v1 = get_version_1 ();
-  int v2 = get_version_2 ();
+  int v2;
 
-  if (v1 != 104)
-    return 1;
-  /* The value returned by get_version_2 depends on the target system.  */
-  if (v2 != 104 && v2 != 203)
-    return 2;
+#ifdef SHLIB_NAME
+  {
+    void *handle = dlopen (SHLIB_NAME, RTLD_LAZY);
+    int (*getver2) (void);
+
+    assert (handle != NULL);
+
+    getver2 = (int (*)(void)) dlsym (handle, "get_version_2");
+
+    v2 = getver2 ();
+  }
+#else
+  v2 = get_version_2 ();
+#endif
 
   return 0; /* STOP */
 }
-
diff --git a/gdb/testsuite/gdb.base/print-file-var.exp b/gdb/testsuite/gdb.base/print-file-var.exp
index 1f733fb4dee..a37cca70de6 100644
--- a/gdb/testsuite/gdb.base/print-file-var.exp
+++ b/gdb/testsuite/gdb.base/print-file-var.exp
@@ -17,76 +17,119 @@  if {[skip_shlib_tests]} {
     return -1
 }
 
-set executable print-file-var-main
+proc test {hidden dlopen version_id_main} {
+    global srcdir subdir
+
+    set main "print-file-var-main"
+
+    set suffix "-hidden$hidden-dlopen$dlopen-version_id_main$version_id_main"
+
+    set executable $main$suffix
+
+    set lib1 "print-file-var-lib1"
+    set lib2 "print-file-var-lib2"
+
+    set libobj1 [standard_output_file ${lib1}$suffix.so]
+    set libobj2 [standard_output_file ${lib2}$suffix.so]
+
+    set lib_opts { debug additional_flags=-fPIC }
+    lappend lib_opts "additional_flags=-DHIDDEN=$hidden"
+
+    if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib1}.c \
+	      ${libobj1} \
+	      ${lib_opts} ] != "" } {
+	return -1
+    }
+    if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib2}.c \
+	      ${libobj2} \
+	      ${lib_opts} ] != "" } {
+	return -1
+    }
+
+    set main_opts [list debug shlib=${libobj1}]
+
+    if {$dlopen} {
+	lappend main_opts "shlib_load" \
+	    "additional_flags=-DSHLIB_NAME=\"$libobj2\""
+    } else {
+	lappend main_opts "shlib=${libobj2}"
+    }
+
+    lappend main_opts "additional_flags=-DVERSION_ID_MAIN=$version_id_main"
+
+    if { [gdb_compile "${srcdir}/${subdir}/${main}.c" \
+	      [standard_output_file ${executable}] \
+	      executable \
+	      $main_opts]
+	 != ""} {
+	return -1
+    }
+
+    clean_restart $executable
+    gdb_load_shlib $libobj1
+    gdb_load_shlib $libobj2
+
+    if ![runto_main] {
+	untested "could not run to main"
+	return -1
+    }
+
+    # Try printing "this_version_num" qualified with the name of the file
+    # where the variables are defined.  There are three global variables
+    # with that name, and some systems such as GNU/Linux merge them
+    # into one single entity, while some other systems such as Windows
+    # keep them separate.  In the first situation, we have to verify
+    # that GDB does not randomly select the wrong instance, even when
+    # a specific filename is used to qualified the lookup.  And in the
+    # second case, we have to verify that GDB does select the instance
+    # defined in the given filename.
+    #
+    # To avoid adding target-specific code in this testcase, the program
+    # sets three local variables named 'vm', 'v1' and 'v2' with the value of
+    # our global variables.  This allows us to compare the value that
+    # GDB returns for each query against the actual value seen by
+    # the program itself.
+
+    # Get past the initialization of the v* variables.
+
+    set bp_location \
+	[gdb_get_line_number "STOP" "${main}.c"]
+    gdb_test "break $main.c:$bp_location" \
+	"Breakpoint \[0-9\]+ at 0x\[0-9a-fA-F\]+: .*" \
+	"breapoint at STOP marker"
+
+    gdb_test "continue" \
+	"Breakpoint \[0-9\]+, main \\(\\) at.*STOP.*" \
+	"continue to STOP marker"
+
+    # Now check the value of this_version_id in all of
+    # print-file-var-main.c, print-file-var-lib1.c and
+    # print-file-var-lib2.c.
+
+    # Compare the values of $sym1 and $sym2.
+    proc compare {sym1 sym2} {
+	# Done this way instead of comparing the symbols with "print $sym1
+	# == sym2" in GDB directly so that the values of the symbols end
+	# up visible in the logs, for debug purposes.
+	set vsym1 [get_integer_valueof $sym1 -1]
+	set vsym2 [get_integer_valueof $sym2 -1]
+	gdb_assert {$vsym1 == $vsym2} "$sym1 == $sym2"
+    }
+
+    if $version_id_main {
+	compare "'print-file-var-main.c'::this_version_id" "vm"
+	compare "this_version_id" "vm"
+    }
+
+    compare "'print-file-var-lib1.c'::this_version_id" "v1"
+    compare "'print-file-var-lib2.c'::this_version_id" "v2"
 
-set lib1 "print-file-var-lib1"
-set lib2 "print-file-var-lib2"
-
-set libobj1 [standard_output_file ${lib1}.so]
-set libobj2 [standard_output_file ${lib2}.so]
-
-set lib_opts { debug additional_flags=-fPIC }
-
-if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib1}.c \
-                        ${libobj1} \
-                        ${lib_opts} ] != "" } {
-    return -1
 }
-if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib2}.c \
-                        ${libobj2} \
-                        ${lib_opts} ] != "" } {
-    return -1
-}
-if { [gdb_compile "${srcdir}/${subdir}/${executable}.c" \
-                  [standard_output_file ${executable}] \
-                  executable \
-                  [list debug shlib=${libobj1} shlib=${libobj2}]]
-     != ""} {
-    return -1
-}
-
-clean_restart $executable
-gdb_load_shlib $libobj1
-gdb_load_shlib $libobj2
 
-if ![runto_main] {
-    untested "could not run to main"
-    return -1
+foreach_with_prefix hidden {0 1} {
+    foreach_with_prefix dlopen {0 1} {
+	foreach_with_prefix version_id_main {0 1} {
+	    test $hidden $dlopen $version_id_main
+	}
+    }
 }
-
-# Try printing "this_version_num" qualified with the name of the file
-# where the variables are defined.  There are two global variables
-# with that name, and some systems such as GNU/Linux merge them
-# into one single entity, while some other systems such as Windows
-# keep them separate.  In the first situation, we have to verify
-# that GDB does not randomly select the wrong instance, even when
-# a specific filename is used to qualified the lookup.  And in the
-# second case, we have to verify that GDB does select the instance
-# defined in the given filename.
-#
-# To avoid adding target-specific code in this testcase, the program
-# sets two local variable named 'v1' and 'v2' with the value of
-# our global variables.  This allows us to compare the value that
-# GDB returns for each query against the actual value seen by
-# the program itself.
-
-# Get past the initialization of variables 'v1' and 'v2'.
-
-set bp_location \
-    [gdb_get_line_number "STOP" "${executable}.c"]
-gdb_test "break $executable.c:$bp_location" \
-         "Breakpoint \[0-9\]+ at 0x\[0-9a-fA-F\]+: .*" \
-         "breapoint past v1 & v2 initialization"
-
-gdb_test "continue" \
-         "Breakpoint \[0-9\]+, main \\(\\) at.*STOP.*" \
-         "continue to STOP marker"
-
-# Now check the value of this_version_id in both print-file-var-lib1.c
-# and print-file-var-lib2.c.
-
-gdb_test "print 'print-file-var-lib1.c'::this_version_id == v1" \
-         " = 1"
-
-gdb_test "print 'print-file-var-lib2.c'::this_version_id == v2" \
-         " = 1"
diff --git a/gdb/testsuite/gdb.base/print-file-var.h b/gdb/testsuite/gdb.base/print-file-var.h
new file mode 100644
index 00000000000..fe7a3460edb
--- /dev/null
+++ b/gdb/testsuite/gdb.base/print-file-var.h
@@ -0,0 +1,26 @@ 
+/* This testcase is part of GDB, the GNU debugger.
+   Copyright 2019 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef PRINT_FILE_VAR_H
+#define PRINT_FILE_VAR_H
+
+#if HIDDEN
+# define ATTRIBUTE_VISIBILITY __attribute__((visibility ("hidden")))
+#else
+# define ATTRIBUTE_VISIBILITY
+#endif
+
+#endif /* PRINT_FILE_VAR_H */