Make print-file-var.exp test attribute visibility hidden, dlopen, and main symbol

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
  - C++

gdb/testsuite/ChangeLog
2019-10-02  Pedro Alves  <palves@redhat.com>
	    Andrew Burgess  <andrew.burgess@embecosm.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.
	Add extern "C" wrappers around interface functions.
	* 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.
	Add extern "C" wrappers around interface functions.
	* gdb.base/print-file-var-main.c: Include <dlfcn.h>, <assert.h>,
	<stddef.h> and "print-file-var.h".
	Add extern "C" wrappers around interface functions.
	[VERSION_ID_MAIN] (this_version_id): Define.
	(main): Define v0.  Use dlopen if SHLIB_NAME is defined.
	* gdb.base/print-file-var.h: Add some #defines to simplify setting
	up extern "C" blocks.
	* 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.
	Compile tests as both C++ and C, make test names unique.
This commit is contained in:
Pedro Alves 2019-07-20 01:20:35 +01:00 committed by Tom Tromey
parent 4b610737f0
commit 1d58d6a26c
6 changed files with 242 additions and 74 deletions

View File

@ -1,3 +1,29 @@
2019-10-02 Pedro Alves <palves@redhat.com>
Andrew Burgess <andrew.burgess@embecosm.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.
Add extern "C" wrappers around interface functions.
* 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.
Add extern "C" wrappers around interface functions.
* gdb.base/print-file-var-main.c: Include <dlfcn.h>, <assert.h>,
<stddef.h> and "print-file-var.h".
Add extern "C" wrappers around interface functions.
[VERSION_ID_MAIN] (this_version_id): Define.
(main): Define v0. Use dlopen if SHLIB_NAME is defined.
* gdb.base/print-file-var.h: Add some #defines to simplify setting
up extern "C" blocks.
* 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.
Compile tests as both C++ and C, make test names unique.
2019-10-01 Tom Tromey <tom@tromey.com>
* gdb.base/style.exp: Test "show logging filename".

View File

@ -14,10 +14,19 @@
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;
START_EXTERN_C
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;
}
END_EXTERN_C

View File

@ -14,10 +14,18 @@
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;
START_EXTERN_C
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;
}
END_EXTERN_C

View File

@ -14,21 +14,49 @@
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"
START_EXTERN_C
extern int get_version_1 (void);
extern int get_version_2 (void);
END_EXTERN_C
#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 */
}

View File

@ -17,76 +17,139 @@ if {[skip_shlib_tests]} {
return -1
}
set executable print-file-var-main
proc test {hidden dlopen version_id_main lang} {
global srcdir subdir
set lib1 "print-file-var-lib1"
set lib2 "print-file-var-lib2"
set main "print-file-var-main"
set libobj1 [standard_output_file ${lib1}.so]
set libobj2 [standard_output_file ${lib2}.so]
set suffix "-hidden$hidden-dlopen$dlopen-version_id_main$version_id_main"
set lib_opts { debug additional_flags=-fPIC }
# Normally we place different builds (C/C++) of a test into
# subdirectories within the test build directory, however, using
# gdb_load_shlib doesn't work well with this approach, so instead
# add a language specific suffix to the binary and library names.
if { $lang == "c" } {
set suffix "${suffix}_c"
} else {
set suffix "${suffix}_cpp"
}
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
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 $lang }
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} $lang]
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} {
with_test_prefix "sym1=$sym1,sym2=$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"
}
clean_restart $executable
gdb_load_shlib $libobj1
gdb_load_shlib $libobj2
if ![runto_main] {
untested "could not run to main"
return -1
# Only test C++ if we are able. Always use C.
if { [skip_cplus_tests] || [get_compiler_info "c++"] } {
set lang_list {c}
} else {
set lang_list {c c++}
}
# 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"
foreach_with_prefix lang $lang_list {
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 $lang
}
}
}
}

View File

@ -0,0 +1,34 @@
/* 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
#ifdef __cplusplus
# define START_EXTERN_C extern "C" {
# define END_EXTERN_C }
#else
# define START_EXTERN_C
# define END_EXTERN_C
#endif
#endif /* PRINT_FILE_VAR_H */