[gdb/testsuite] Handle ptrace operation not permitted in can_spawn_for_attach
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-arm |
fail
|
Testing failed
|
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
fail
|
Testing failed
|
Commit Message
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.
---
gdb/testsuite/gdb.base/break-interp.exp | 4 ++
gdb/testsuite/gdb.base/dprintf-detach.exp | 2 +-
.../run-control-while-bg-execution.exp | 10 ++-
.../gdb.multi/attach-while-running.exp | 2 +-
.../gdb.threads/attach-into-signal.exp | 3 +-
.../gdb.threads/attach-slow-waitpid.exp | 3 +-
gdb/testsuite/gdb.threads/attach-stopped.exp | 3 +-
.../gdb.threads/check-libthread-db.exp | 42 +++++------
gdb/testsuite/lib/gdb.exp | 71 +++++++++++++++----
9 files changed, 100 insertions(+), 40 deletions(-)
base-commit: 6732c57eeea61d72ad1046fae1dd0d00920150e1
Comments
On 4/16/24 21:44, Tom de Vries wrote:
> 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.
AFAIK testing on aarch64-linux went fine, but on x86_64-linux I ran into
some problems (also reported by linaro CI), so I need to revise this
approach. I'll work on a v2.
Thanks,
- Tom
> ---
> gdb/testsuite/gdb.base/break-interp.exp | 4 ++
> gdb/testsuite/gdb.base/dprintf-detach.exp | 2 +-
> .../run-control-while-bg-execution.exp | 10 ++-
> .../gdb.multi/attach-while-running.exp | 2 +-
> .../gdb.threads/attach-into-signal.exp | 3 +-
> .../gdb.threads/attach-slow-waitpid.exp | 3 +-
> gdb/testsuite/gdb.threads/attach-stopped.exp | 3 +-
> .../gdb.threads/check-libthread-db.exp | 42 +++++------
> gdb/testsuite/lib/gdb.exp | 71 +++++++++++++++----
> 9 files changed, 100 insertions(+), 40 deletions(-)
>
> diff --git a/gdb/testsuite/gdb.base/break-interp.exp b/gdb/testsuite/gdb.base/break-interp.exp
> index addacde552d..d7f84db4770 100644
> --- a/gdb/testsuite/gdb.base/break-interp.exp
> +++ b/gdb/testsuite/gdb.base/break-interp.exp
> @@ -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
>
> diff --git a/gdb/testsuite/gdb.base/dprintf-detach.exp b/gdb/testsuite/gdb.base/dprintf-detach.exp
> index 550d319a895..b4184d698df 100644
> --- a/gdb/testsuite/gdb.base/dprintf-detach.exp
> +++ b/gdb/testsuite/gdb.base/dprintf-detach.exp
> @@ -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}]
> diff --git a/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp b/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp
> index f1cbd9351d3..a36c4ee3614 100644
> --- a/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp
> +++ b/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp
> @@ -108,8 +108,14 @@ proc do_test { action1 action2 } {
> }
> }
>
> -foreach_with_prefix action1 { kill detach add none } {
> - foreach_with_prefix action2 { start run attach } {
> +set actions1 { kill detach add none }
> +set actions2 { start run }
> +if { [can_spawn_for_attach] } {
> + lappend actions2 attach
> +}
> +
> +foreach_with_prefix action1 $actions1 {
> + foreach_with_prefix action2 $actions2 {
> do_test $action1 $action2
> }
> }
> diff --git a/gdb/testsuite/gdb.multi/attach-while-running.exp b/gdb/testsuite/gdb.multi/attach-while-running.exp
> index eade8b42a18..ca4fa635467 100644
> --- a/gdb/testsuite/gdb.multi/attach-while-running.exp
> +++ b/gdb/testsuite/gdb.multi/attach-while-running.exp
> @@ -36,7 +36,7 @@
>
> standard_testfile
>
> -require !use_gdb_stub
> +require can_spawn_for_attach
>
> if { [build_executable "failed to prepare" ${testfile} ${srcfile}] } {
> return
> diff --git a/gdb/testsuite/gdb.threads/attach-into-signal.exp b/gdb/testsuite/gdb.threads/attach-into-signal.exp
> index 87e34070548..91da960e09a 100644
> --- a/gdb/testsuite/gdb.threads/attach-into-signal.exp
> +++ b/gdb/testsuite/gdb.threads/attach-into-signal.exp
> @@ -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*}
>
> diff --git a/gdb/testsuite/gdb.threads/attach-slow-waitpid.exp b/gdb/testsuite/gdb.threads/attach-slow-waitpid.exp
> index dc3e62a7b7e..28d70daad8c 100644
> --- a/gdb/testsuite/gdb.threads/attach-slow-waitpid.exp
> +++ b/gdb/testsuite/gdb.threads/attach-slow-waitpid.exp
> @@ -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*}
>
> diff --git a/gdb/testsuite/gdb.threads/attach-stopped.exp b/gdb/testsuite/gdb.threads/attach-stopped.exp
> index 78e194c992f..0421ffc3794 100644
> --- a/gdb/testsuite/gdb.threads/attach-stopped.exp
> +++ b/gdb/testsuite/gdb.threads/attach-stopped.exp
> @@ -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*}
>
> diff --git a/gdb/testsuite/gdb.threads/check-libthread-db.exp b/gdb/testsuite/gdb.threads/check-libthread-db.exp
> index 5662eeda077..6976fe6f83b 100644
> --- a/gdb/testsuite/gdb.threads/check-libthread-db.exp
> +++ b/gdb/testsuite/gdb.threads/check-libthread-db.exp
> @@ -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}
> -
> - 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]
> -
> - 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
> + 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"
> +
> + 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_exit
> + kill_wait_spawned_process $test_spawn_id
> + }
> }
> }
> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index d48ea37c0cc..566a8296130 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -6131,6 +6131,43 @@ 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 { 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]
> + file 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.
> + }
> + }
> +
> + 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.
>
> @@ -6151,8 +6188,9 @@ proc can_spawn_for_attach { } {
> return 0
> }
>
> - # Assume yes.
> - return 1
> + gdb_exit
> +
> + return [can_spawn_for_attach_1]
> }
>
> # Centralize the failure checking of "attach" command.
> @@ -6265,20 +6303,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. 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
> @@ -6292,6 +6322,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.
>
> base-commit: 6732c57eeea61d72ad1046fae1dd0d00920150e1
@@ -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}]
@@ -108,8 +108,14 @@ proc do_test { action1 action2 } {
}
}
-foreach_with_prefix action1 { kill detach add none } {
- foreach_with_prefix action2 { start run attach } {
+set actions1 { kill detach add none }
+set actions2 { start run }
+if { [can_spawn_for_attach] } {
+ lappend actions2 attach
+}
+
+foreach_with_prefix action1 $actions1 {
+ foreach_with_prefix action2 $actions2 {
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}
-
- 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]
-
- 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
+ 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"
+
+ 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_exit
+ kill_wait_spawned_process $test_spawn_id
+ }
}
}
@@ -6131,6 +6131,43 @@ 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 { 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]
+ file 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.
+ }
+ }
+
+ 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.
@@ -6151,8 +6188,9 @@ proc can_spawn_for_attach { } {
return 0
}
- # Assume yes.
- return 1
+ gdb_exit
+
+ return [can_spawn_for_attach_1]
}
# Centralize the failure checking of "attach" command.
@@ -6265,20 +6303,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. 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
@@ -6292,6 +6322,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.