forked from Imagelibrary/binutils-gdb
[gdb/testsuite] Handle ptrace operation not permitted in can_spawn_for_attach
When running the testsuite on a system with kernel.yama.ptrace_scope set to 1, we run into attach failures. Fix this by recognizing "ptrace: Operation not permitted" in can_spawn_for_attach. Tested on aarch64-linux and x86_64-linux. Approved-By: Pedro Alves <pedro@palves.net>
This commit is contained in:
@@ -318,6 +318,10 @@ proc test_attach_gdb {file pid displacement prefix} {
|
||||
}
|
||||
|
||||
proc test_attach {file displacement {relink_args ""}} {
|
||||
if { ![can_spawn_for_attach] } {
|
||||
return
|
||||
}
|
||||
|
||||
global board_info
|
||||
global exec
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
load_lib gdbserver-support.exp
|
||||
|
||||
# The test relies on "detach/attach".
|
||||
require !use_gdb_stub
|
||||
require can_spawn_for_attach
|
||||
|
||||
standard_testfile
|
||||
set escapedbinfile [string_to_regexp ${binfile}]
|
||||
|
||||
@@ -110,6 +110,9 @@ proc do_test { action1 action2 } {
|
||||
|
||||
foreach_with_prefix action1 { kill detach add none } {
|
||||
foreach_with_prefix action2 { start run attach } {
|
||||
if { $action2 == "attach" && ![can_spawn_for_attach] } {
|
||||
continue
|
||||
}
|
||||
do_test $action1 $action2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
standard_testfile
|
||||
|
||||
require !use_gdb_stub
|
||||
require can_spawn_for_attach
|
||||
|
||||
if { [build_executable "failed to prepare" ${testfile} ${srcfile}] } {
|
||||
return
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# This file was created by Jan Kratochvil <jan.kratochvil@redhat.com>.
|
||||
|
||||
# This test only works on Linux
|
||||
require !use_gdb_stub isnative
|
||||
require can_spawn_for_attach
|
||||
require isnative
|
||||
require {!is_remote host}
|
||||
require {istarget *-linux*}
|
||||
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
# during the attach phase.
|
||||
|
||||
# This test only works on Linux
|
||||
require !use_gdb_stub isnative
|
||||
require can_spawn_for_attach
|
||||
require isnative
|
||||
require {!is_remote host}
|
||||
require {istarget *-linux*}
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
# This file was updated by Jan Kratochvil <jan.kratochvil@redhat.com>.
|
||||
|
||||
# This test only works on Linux
|
||||
require !use_gdb_stub isnative
|
||||
require can_spawn_for_attach
|
||||
require isnative
|
||||
require {!is_remote host}
|
||||
require {istarget *-linux*}
|
||||
|
||||
|
||||
@@ -102,25 +102,27 @@ with_test_prefix "automated load-time check" {
|
||||
}
|
||||
|
||||
# Automated load-time check with NPTL fully operational.
|
||||
with_test_prefix "libpthread.so fully initialized" {
|
||||
clean_restart ${binfile}
|
||||
if { [can_spawn_for_attach] } {
|
||||
with_test_prefix "libpthread.so fully initialized" {
|
||||
clean_restart ${binfile}
|
||||
|
||||
gdb_test_no_output "maint set check-libthread-db 1"
|
||||
gdb_test_no_output "set debug libthread-db 1"
|
||||
gdb_test_no_output "maint set check-libthread-db 1"
|
||||
gdb_test_no_output "set debug libthread-db 1"
|
||||
|
||||
set test_spawn_id [spawn_wait_for_attach $binfile]
|
||||
set testpid [spawn_id_get_pid $test_spawn_id]
|
||||
set test_spawn_id [spawn_wait_for_attach $binfile]
|
||||
set testpid [spawn_id_get_pid $test_spawn_id]
|
||||
|
||||
gdb_test_sequence "attach $testpid" \
|
||||
"check debug libthread-db output" {
|
||||
"\[\r\n\]+Running libthread_db integrity checks:"
|
||||
"\[\r\n\]+\[ \]+Got thread 0x\[1-9a-f\]\[0-9a-f\]+ => \[0-9\]+ => 0x\[1-9a-f\]\[0-9a-f\]+ ... OK"
|
||||
"\[\r\n\]+\[ \]+Got thread 0x\[1-9a-f\]\[0-9a-f\]+ => \[0-9\]+ => 0x\[1-9a-f\]\[0-9a-f\]+ ... OK"
|
||||
"\[\r\n\]+libthread_db integrity checks passed."
|
||||
"\[\r\n\]+[Thread debugging using libthread_db enabled]"
|
||||
}
|
||||
gdb_test_sequence "attach $testpid" \
|
||||
"check debug libthread-db output" {
|
||||
"\[\r\n\]+Running libthread_db integrity checks:"
|
||||
"\[\r\n\]+\[ \]+Got thread 0x\[1-9a-f\]\[0-9a-f\]+ => \[0-9\]+ => 0x\[1-9a-f\]\[0-9a-f\]+ ... OK"
|
||||
"\[\r\n\]+\[ \]+Got thread 0x\[1-9a-f\]\[0-9a-f\]+ => \[0-9\]+ => 0x\[1-9a-f\]\[0-9a-f\]+ ... OK"
|
||||
"\[\r\n\]+libthread_db integrity checks passed."
|
||||
"\[\r\n\]+[Thread debugging using libthread_db enabled]"
|
||||
}
|
||||
|
||||
gdb_exit
|
||||
kill_wait_spawned_process $test_spawn_id
|
||||
gdb_exit
|
||||
kill_wait_spawned_process $test_spawn_id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6153,8 +6153,54 @@ proc gdb_exit { } {
|
||||
catch default_gdb_exit
|
||||
}
|
||||
|
||||
# Helper function for can_spawn_for_attach. Try to spawn and attach, and
|
||||
# return 0 only if we cannot attach because it's unsupported.
|
||||
|
||||
gdb_caching_proc can_spawn_for_attach_1 {} {
|
||||
# Assume yes.
|
||||
set res 1
|
||||
|
||||
set me "can_spawn_for_attach"
|
||||
set src {
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
sleep (600);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if {![gdb_simple_compile $me $src executable]} {
|
||||
return $res
|
||||
}
|
||||
|
||||
set test_spawn_id [spawn_wait_for_attach_1 $obj]
|
||||
remote_file build delete $obj
|
||||
|
||||
gdb_start
|
||||
|
||||
set test_pid [spawn_id_get_pid $test_spawn_id]
|
||||
set attaching_re "Attaching to process $test_pid"
|
||||
gdb_test_multiple "attach $test_pid" "can spawn for attach" {
|
||||
-re -wrap "$attaching_re\r\n.*ptrace: Operation not permitted\\." {
|
||||
# Not permitted.
|
||||
set res 0
|
||||
}
|
||||
-re -wrap "" {
|
||||
# Don't know, keep assuming yes.
|
||||
}
|
||||
}
|
||||
|
||||
gdb_exit
|
||||
|
||||
kill_wait_spawned_process $test_spawn_id
|
||||
|
||||
return $res
|
||||
}
|
||||
|
||||
# Return true if we can spawn a program on the target and attach to
|
||||
# it.
|
||||
# it. Calls gdb_exit for the first call in a test-case.
|
||||
|
||||
proc can_spawn_for_attach { } {
|
||||
# We use exp_pid to get the inferior's pid, assuming that gives
|
||||
@@ -6173,8 +6219,39 @@ proc can_spawn_for_attach { } {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Assume yes.
|
||||
return 1
|
||||
# The normal sequence to use for a runtime test like
|
||||
# can_spawn_for_attach_1 is:
|
||||
# - gdb_exit (don't use a running gdb, we don't know what state it is in),
|
||||
# - gdb_start (start a new gdb), and
|
||||
# - gdb_exit (cleanup).
|
||||
#
|
||||
# By making can_spawn_for_attach_1 a gdb_caching_proc, we make it
|
||||
# unpredictable which test-case will call it first, and consequently a
|
||||
# test-case may pass in say a full test run, but fail when run
|
||||
# individually, due to a can_spawn_for_attach call in a location where a
|
||||
# gdb_exit (as can_spawn_for_attach_1 does) breaks things.
|
||||
# To avoid this, we move the initial gdb_exit out of
|
||||
# can_spawn_for_attach_1, guaranteeing that we end up in the same state
|
||||
# regardless of whether can_spawn_for_attach_1 is called. However, that
|
||||
# is only necessary for the first call in a test-case, so cache the result
|
||||
# in a global (which should be reset after each test-case) to keep track
|
||||
# of that.
|
||||
#
|
||||
# In summary, we distinguish between three cases:
|
||||
# - first call in first test-case. Executes can_spawn_for_attach_1.
|
||||
# Calls gdb_exit, gdb_start, gdb_exit.
|
||||
# - first call in following test-cases. Uses cached result of
|
||||
# can_spawn_for_attach_1. Calls gdb_exit.
|
||||
# - rest. Use cached result in cache_can_spawn_for_attach_1. Calls no
|
||||
# gdb_start or gdb_exit.
|
||||
global cache_can_spawn_for_attach_1
|
||||
if { [info exists cache_can_spawn_for_attach_1] } {
|
||||
return $cache_can_spawn_for_attach_1
|
||||
}
|
||||
gdb_exit
|
||||
|
||||
set cache_can_spawn_for_attach_1 [can_spawn_for_attach_1]
|
||||
return $cache_can_spawn_for_attach_1
|
||||
}
|
||||
|
||||
# Centralize the failure checking of "attach" command.
|
||||
@@ -6287,20 +6364,12 @@ proc spawn_id_get_pid { spawn_id } {
|
||||
return $testpid
|
||||
}
|
||||
|
||||
# Start a set of programs running and then wait for a bit, to be sure
|
||||
# that they can be attached to. Return a list of processes spawn IDs,
|
||||
# one element for each process spawned. It's a test error to call
|
||||
# this when [can_spawn_for_attach] is false.
|
||||
# Helper function for spawn_wait_for_attach and can_spawn_for_attach_1. As
|
||||
# spawn_wait_for_attach, but doesn't check for can_spawn_for_attach.
|
||||
|
||||
proc spawn_wait_for_attach { executable_list } {
|
||||
proc spawn_wait_for_attach_1 { executable_list } {
|
||||
set spawn_id_list {}
|
||||
|
||||
if ![can_spawn_for_attach] {
|
||||
# The caller should have checked can_spawn_for_attach itself
|
||||
# before getting here.
|
||||
error "can't spawn for attach with this target/board"
|
||||
}
|
||||
|
||||
foreach {executable} $executable_list {
|
||||
# Note we use Expect's spawn, not Tcl's exec, because with
|
||||
# spawn we control when to wait for/reap the process. That
|
||||
@@ -6314,6 +6383,21 @@ proc spawn_wait_for_attach { executable_list } {
|
||||
return $spawn_id_list
|
||||
}
|
||||
|
||||
# Start a set of programs running and then wait for a bit, to be sure
|
||||
# that they can be attached to. Return a list of processes spawn IDs,
|
||||
# one element for each process spawned. It's a test error to call
|
||||
# this when [can_spawn_for_attach] is false.
|
||||
|
||||
proc spawn_wait_for_attach { executable_list } {
|
||||
if ![can_spawn_for_attach] {
|
||||
# The caller should have checked can_spawn_for_attach itself
|
||||
# before getting here.
|
||||
error "can't spawn for attach with this target/board"
|
||||
}
|
||||
|
||||
return [spawn_wait_for_attach_1 $executable_list]
|
||||
}
|
||||
|
||||
#
|
||||
# gdb_load_cmd -- load a file into the debugger.
|
||||
# ARGS - additional args to load command.
|
||||
|
||||
Reference in New Issue
Block a user