[patch-testcase] Re: RFC: Verify AT_ENTRY before using it

Jan Kratochvil
2010-03-01T21:22:30Z

Hi,

just a patch on top of the in-reply-to one for more sanity checking.

It provides `set verbose' message which already exists for a long time in
LM_ADDR_CHECK (not info_verbose-conditioned until recently):
if (info_verbose)
{
warning (_(".dynamic section for \"%s\" "
"is not at the expected address"), so->so_name);
warning (_("difference appears to be caused by prelink, "
"adjusting expectations"));
}

No regressions on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu.

That quadruplication of `-re "Using PIE ...' block (4x2 similar blocks) is
ugly but AFAIK trying to make it more common faces TCL "uplevel" issues
already being solved complicated way in lib/gdb.exp proc gdb_test_multiple.

Thanks,
Jan

gdb/
2010-03-01 Jan Kratochvil <jan.kratochvil@redhat.com>

* solib-svr4.c (svr4_exec_displacement): Print DISPLACEMENT if
INFO_VERBOSE.

gdb/testsuite/
2010-03-01 Jan Kratochvil <jan.kratochvil@redhat.com>

* gdb.base/break-interp.exp: Create new displacement parameter value
for the test_ld calls.
(reach): New parameter displacement, verify its content. New push of
pf_prefix "reach-$func:".
(test_core): New parameter displacement, verify its content. New push
of pf_prefix "core:". New command "set verbose on".
(test_attach): New parameter displacement, verify its content. New
push of pf_prefix "attach:". New command "set verbose on".
(test_ld): New parameter displacement, pass it to the reach, test_core
and test_attach calls and verify its content in the "ld.so exit" test.

--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1773,6 +1773,18 @@ svr4_exec_displacement (void)
}
}

+ if (info_verbose)
+ {
+ /* It can be printed repeatedly as there is no easy way to check
+ the executable symbols/file has been already relocated to
+ displacement. */
+
+ warning (_("Using PIE (Position Independent Executable) "
+ "displacement %s for \"%s\""),
+ paddress (target_gdbarch, displacement),
+ bfd_get_filename (exec_bfd));
+ }
+
return displacement;
}

--- a/gdb/testsuite/gdb.base/break-interp.exp
+++ b/gdb/testsuite/gdb.base/break-interp.exp
@@ -221,12 +221,40 @@ proc strip_debug {dest} {
}

# `runto' does not check we stopped really at the function we specified.
-proc reach {func command} {
+# DISPLACEMENT can be "NONE", "ZERO" or "NONZERO"
+proc reach {func command displacement} {
global gdb_prompt

+ global pf_prefix
+ set old_ldprefix $pf_prefix
+ lappend pf_prefix "reach-$func:"
+
if [gdb_breakpoint $func allow-pending] {
- set test "reach $func"
+ set test "reach"
+ set test_displacement "seen displacement message as $displacement"
gdb_test_multiple $command $test {
+ -re "Using PIE \\(Position Independent Executable\\) displacement 0x0 " {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$displacement == "ZERO"} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement "FOUND-$displacement"
+ } elseif {$displacement != "FOUND-ZERO"} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
+ -re "Using PIE \\(Position Independent Executable\\) displacement" {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$displacement == "NONZERO"} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement "FOUND-$displacement"
+ } elseif {$displacement != "FOUND-NONZERO"} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
-re "Breakpoint \[0-9\]+, $func \\(.*\\) at .*:\[0-9\]+\r\n.*$gdb_prompt $" {
pass $test
}
@@ -234,10 +262,15 @@ proc reach {func command} {
pass $test
}
}
+ if ![regexp {^(NONE|FOUND-.*)$} $displacement] {
+ fail $test_displacement
+ }
}
+
+ set pf_prefix $old_ldprefix
}

-proc test_core {file} {
+proc test_core {file displacement} {
global srcdir subdir gdb_prompt

set corefile [core_find $file {} "segv"]
@@ -245,6 +278,10 @@ proc test_core {file} {
return
}

+ global pf_prefix
+ set old_ldprefix $pf_prefix
+ lappend pf_prefix "core:"
+
gdb_exit
gdb_start
# Clear it to never find any separate debug infos in $debug_root.
@@ -252,14 +289,50 @@ proc test_core {file} {
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $file

- # Do not check the binary filename as it may be truncated.
- gdb_test "core-file $corefile" "Core was generated by .*\r\n#0 .*" "core loaded"
+ # Print the "PIE (Position Independent Executable) displacement" message.
+ gdb_test "set verbose on"
+
+ set test "core loaded"
+ set test_displacement "seen displacement message"
+ gdb_test_multiple "core-file $corefile" $test {
+ -re "Using PIE \\(Position Independent Executable\\) displacement 0x0 " {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$displacement == "ZERO"} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement "FOUND-$displacement"
+ } elseif {$displacement != "FOUND-ZERO"} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
+ -re "Using PIE \\(Position Independent Executable\\) displacement" {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$displacement == "NONZERO"} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement "FOUND-$displacement"
+ } elseif {$displacement != "FOUND-NONZERO"} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
+ -re "Core was generated by .*\r\n#0 .*$gdb_prompt $" {
+ # Do not check the binary filename as it may be truncated.
+ pass $test
+ }
+ }
+ if ![regexp {^(NONE|FOUND-.*)$} $displacement] {
+ fail $test_displacement
+ }

gdb_test "bt" "#\[0-9\]+ +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#\[0-9\]+ +\[^\r\n\]*\\mmain\\M.*" "core main bt"
+
+ set pf_prefix $old_ldprefix
}

-proc test_attach {file} {
- global board_info
+proc test_attach {file displacement} {
+ global board_info gdb_prompt

gdb_exit

@@ -287,16 +360,66 @@ proc test_attach {file} {
}
}

+ global pf_prefix
+ set old_ldprefix $pf_prefix
+ lappend pf_prefix "attach:"
+
gdb_exit
gdb_start
- gdb_test "attach $pid" "Attaching to process $pid\r\n.*" "attach"
+
+ # Print the "PIE (Position Independent Executable) displacement" message.
+ gdb_test "set verbose on"
+
+ set test "attach"
+ gdb_test_multiple "attach $pid" $test {
+ -re "Attaching to process $pid\r\n" {
+ # Missing "$gdb_prompt $" is intentional.
+ pass $test
+ }
+ }
+
+ set test "attach final prompt"
+ set test_displacement "seen displacement message"
+ gdb_test_multiple "" $test {
+ -re "Using PIE \\(Position Independent Executable\\) displacement 0x0 " {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$displacement == "ZERO"} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement "FOUND-$displacement"
+ } elseif {$displacement != "FOUND-ZERO"} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
+ -re "Using PIE \\(Position Independent Executable\\) displacement" {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$displacement == "NONZERO"} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement "FOUND-$displacement"
+ } elseif {$displacement != "FOUND-NONZERO"} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
+ -re "$gdb_prompt $" {
+ pass $test
+ }
+ }
+ if ![regexp {^(NONE|FOUND-.*)$} $displacement] {
+ fail $test_displacement
+ }
+
gdb_test "bt" "#\[0-9\]+ +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#\[0-9\]+ +\[^\r\n\]*\\mmain\\M.*" "attach main bt"
gdb_exit

remote_exec host "kill -9 $pid"
+
+ set pf_prefix $old_ldprefix
}

-proc test_ld {file ifmain trynosym} {
+proc test_ld {file ifmain trynosym displacement} {
global srcdir subdir gdb_prompt

# First test normal `file'-command loaded $FILE with symbols.
@@ -308,20 +431,25 @@ proc test_ld {file ifmain trynosym} {
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $file

- reach "dl_main" "run segv"
+ # Print the "PIE (Position Independent Executable) displacement" message.
+ gdb_test "set verbose on"
+
+ reach "dl_main" "run segv" $displacement

gdb_test "bt" "#0 +\[^\r\n\]*\\mdl_main\\M.*" "dl bt"

if $ifmain {
- reach "main" continue
+ # Displacement message will be printed the second time on initializing
+ # the linker from svr4_special_symbol_handling.
+ reach "main" continue $displacement

- reach "libfunc" continue
+ reach "libfunc" continue "NONE"

gdb_test "bt" "#0 +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#1 +\[^\r\n\]*\\mmain\\M.*" "main bt"

- test_core $file
+ test_core $file $displacement

- test_attach $file
+ test_attach $file $displacement
}

if !$trynosym {
@@ -341,12 +469,15 @@ proc test_ld {file ifmain trynosym} {
gdb_test "set debug-file-directory"
gdb_reinitialize_dir $srcdir/$subdir

+ # Print the "PIE (Position Independent Executable) displacement" message.
+ gdb_test "set verbose on"
+
# Test no (error) message has been printed by `exec-file'.
set escapedfile [string_to_regexp $file]
gdb_test "exec-file $file" "exec-file $escapedfile" "load"

if $ifmain {
- reach "dl_main" run
+ reach "dl_main" run $displacement

set test "info files"
set entrynohex ""
@@ -363,7 +494,40 @@ proc test_ld {file ifmain trynosym} {
} else {
# There is no symbol to break at ld.so. Moreover it can exit with an
# error code.
- gdb_test "run" "Program exited (normally|with code \[0-9\]+)\\." "ld.so exit"
+
+ set test "ld.so exit"
+ set test_displacement "seen displacement message"
+ gdb_test_multiple "run" $test {
+ -re "Using PIE \\(Position Independent Executable\\) displacement 0x0 " {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$displacement == "ZERO"} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement "FOUND-$displacement"
+ } elseif {$displacement != "FOUND-ZERO"} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
+ -re "Using PIE \\(Position Independent Executable\\) displacement" {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$displacement == "NONZERO"} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement "FOUND-$displacement"
+ } elseif {$displacement != "FOUND-NONZERO"} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
+ -re "Program exited (normally|with code \[0-9\]+)\\.\r\n$gdb_prompt $" {
+ # Do not check the binary filename as it may be truncated.
+ pass $test
+ }
+ }
+ if ![regexp {^(NONE|FOUND-.*)$} $displacement] {
+ fail $test_displacement
+ }
}

set pf_prefix $old_ldprefix
@@ -450,7 +614,12 @@ foreach ldprelink {NO YES} {
if ![prelink$ldprelink $interp] {
continue
}
- test_ld $interp 0 [expr {$ldsepdebug == "NO"}]
+ if {$ldprelink == "NO"} {
+ set displacement "NONZERO"
+ } else {
+ set displacement "ZERO"
+ }
+ test_ld $interp 0 [expr {$ldsepdebug == "NO"}] $displacement

if ![copy $interp $interp_saved] {
continue
@@ -531,7 +700,14 @@ foreach ldprelink {NO YES} {

if {[prelink$binprelink "--dynamic-linker=$interp --ld-library-path=$dir $exec $interp [concat $dests]" [file tail $exec]]
&& [copy $interp_saved $interp]} {
- test_ld $exec 1 [expr {$binsepdebug == "NO"}]
+ if {$binpie == "NO"} {
+ set displacement "NONE"
+ } elseif {$binprelink == "NO"} {
+ set displacement "NONZERO"
+ } else {
+ set displacement "ZERO"
+ }
+ test_ld $exec 1 [expr {$binsepdebug == "NO"}] $displacement
}
}
}