public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
* [Bug gdb/32608] New: [gdb, -m32] FAIL: gdb.threads/step-over-thread-exit-while-stop-all-threads.exp: displaced-stepping=auto: target-non-stop=on: iter 8: continue
@ 2025-01-28 11:55 vries at gcc dot gnu.org
2025-01-28 11:56 ` [Bug gdb/32608] " vries at gcc dot gnu.org
0 siblings, 1 reply; 2+ messages in thread
From: vries at gcc dot gnu.org @ 2025-01-28 11:55 UTC (permalink / raw)
To: gdb-prs
https://sourceware.org/bugzilla/show_bug.cgi?id=32608
Bug ID: 32608
Summary: [gdb, -m32] FAIL:
gdb.threads/step-over-thread-exit-while-stop-all-threa
ds.exp: displaced-stepping=auto: target-non-stop=on:
iter 8: continue
Product: gdb
Version: HEAD
Status: NEW
Severity: normal
Priority: P2
Component: gdb
Assignee: unassigned at sourceware dot org
Reporter: vries at gcc dot gnu.org
Target Milestone: ---
Created attachment 15902
--> https://sourceware.org/bugzilla/attachment.cgi?id=15902&action=edit
gdb.log
I did the following experiment:
...
$ for n in $(seq 1 50); do \
taskset -c 11 ./test.sh -m32 2>&1 \
| grep "^# of " \
| sort -u; cp gdb.log gdb.$n.log; \
done
...
where test.sh -m32 runs test-case
gdb.threads/step-over-thread-exit-while-stop-all-threads.exp with target board
unix/-m32, and ran into this FAIL:
...
Thread 36 "step-over-threa" received signal SIGSEGV, Segmentation fault.^M
[Switching to Thread 0xe72e0b40 (LWP 29790)]^M
0x00000000 in ?? ()^M
(gdb) FAIL: gdb.threads/step-over-thread-exit-while-stop-all-threads.exp:
displaced-stepping=auto: target-non-stop=on: iter 8: continue
...
I then added:
...
diff --git
a/gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.exp
b/gdb/testsuite/gdb.threads/step-ove
r-thread-exit-while-stop-all-threads.exp
index d37c44f7c73..e0729f88508 100644
---
a/gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.exp
+++
b/gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.exp
@@ -52,9 +52,12 @@ proc test {displaced-stepping target-non-stop} {
# Make sure the target reports the breakpoint stops.
gdb_test_no_output "set breakpoint condition-evaluation host"
+ gdb_test_no_output "set debug displaced on"
+ gdb_test_no_output "set debug infrun on"
+
for { set i 0 } { $i < 30 } { incr i } {
with_test_prefix "iter $i" {
- if { [gdb_test "continue" "hit Breakpoint $::decimal, break_here
.*"] != 0 } {
+ if { [gdb_test -no-prompt-anchor "continue" "hit Breakpoint
$::decimal, break_here .*"] != 0 } {
# Exit if there's a failure to avoid lengthy timeouts.
break
}
...
and redid the experiment, gdb.log attached.
The series of relevant events is as follows, following thread LWP 29790.
We're executing the my_exit function, specifically the syscall instruction at
8048632:
...
08048621 <my_exit>:
8048621: b8 01 00 00 00 mov $0x1,%eax
8048626: 8b 5c 24 04 mov 0x4(%esp),%ebx
804862a: 8b 4c 24 08 mov 0x8(%esp),%ecx
804862e: 8b 54 24 0c mov 0xc(%esp),%edx
08048632 <my_exit_syscall>:
8048632: cd 80 int $0x80
8048634: c3 ret
...
And we're executing it using displaced stepping, which is setup here:
...
[displaced] displaced_step_prepare_throw: displaced-stepping 29753.29790.0
now^M
[displaced] displaced_step_prepare_throw: original insn 0x8048632: cd 80
int $0x80^M
[displaced] prepare: selected buffer at 0x8048402^M
[displaced] prepare: saved 0x8048402: 5e 89 e1 83 e4 f0 50 54 52 e8 19 00 00
00 81 c3^M
[displaced] i386_displaced_step_copy_insn: 0x8048632->0x8048402: cd 80 90 00
00 00 53 83 ec 08 e8 0f fe ff ff 81^M
[displaced] displaced_step_prepare_throw: prepared successfully
thread=29753.29790.0, original_pc=0x8048632, displaced_pc=0x8048402^M
[displaced] displaced_step_prepare_throw: replacement insn 0x8048402: cd 80
int $0x80^M
...
So we copy the insn (0xcd 0x80) to a buffer at _start+0x2, with a nop added
(0x90).
Once it's setup, we do a PTRACE_SINGLESTEP:
...
[infrun] do_target_resume: resume_ptid=29753.29790.0, step=1,
sig=GDB_SIGNAL_0^M
...
Then this happens:
...
[infrun] stop_all_threads: 29753.29790.0 executing, need stop^M
...
which means that a SIGSTOP is sent to the thread.
And the stop happens:
...
[infrun] print_target_wait_results: target_wait (-1.0.0 [process -1],
status) =^M
[infrun] print_target_wait_results: 29753.29790.0 [Thread 0xe72e0b40 (LWP
29790)],^M
[infrun] print_target_wait_results: status->kind = STOPPED, sig =
GDB_SIGNAL_0^M
[infrun] handle_one: status->kind = STOPPED, sig = GDB_SIGNAL_0
29753.29790.0^M
...
Then the displaced stepping setup is reverted:
...
[displaced] finish: restored 29753.29790.0 0x8048402^M
[displaced] i386_displaced_step_fixup: fixup (0x8048632, 0x8048402), insn =
0xcd 0x80 ...^M
[displaced] i386_displaced_step_fixup: syscall changed %eip; not
relocating^M
[infrun] handle_one: displaced-step of 29753.29790.0 canceled^M
[infrun] global_thread_step_over_chain_enqueue: enqueueing thread
29753.29790.0 in global step over chain^M
...
Here we see two interesting things:
- the instruction pointer has changed, and
- the displaced-step is canceled.
The first is done here in i386_displaced_step_fixup:
...
if (i386_syscall_p (insn, &insn_len)
&& pc != to + (insn - insn_start) + insn_len
/* GDB can get control back after the insn after the syscall.
Presumably this is a kernel bug.
i386_displaced_step_copy_insn ensures it's a nop,
we add one to the length for it. */
&& pc != to + (insn - insn_start) + insn_len + 1)
displaced_debug_printf ("syscall changed %%eip; not relocating");
...
and the second here in handle_one:
...
if (displaced_step_finish (t, event.ws)
== DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED)
{
/* Add it back to the step-over queue. */
infrun_debug_printf
("displaced-step of %s canceled",
t->ptid.to_string ().c_str ());
t->control.trap_expected = 0;
if (!t->inf->detaching)
global_thread_step_over_chain_enqueue (t);
}
...
Then we resume:
...
[infrun] do_target_resume: resume_ptid=29753.29790.0, step=0,
sig=GDB_SIGNAL_0^M
...
and run into:
...
[infrun] print_target_wait_results: target_wait (-1.0.0 [process -1], status)
=^M
[infrun] print_target_wait_results: 29753.29790.0 [Thread 0xe72e0b40 (LWP
29790)],^M
[infrun] print_target_wait_results: status->kind = STOPPED, sig =
GDB_SIGNAL_SEGV^M
[infrun] handle_inferior_event: status->kind = STOPPED, sig =
GDB_SIGNAL_SEGV^M
...
at:
...
[infrun] handle_signal_stop: stop_pc=0x0^M
[infrun] handle_signal_stop: random signal (GDB_SIGNAL_SEGV)^M
...
So, AFAICT, this is a kernel bug, where the kernel overwrites the pc while it
shouldn't.
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply [flat|nested] 2+ messages in thread
* [Bug gdb/32608] [gdb, -m32] FAIL: gdb.threads/step-over-thread-exit-while-stop-all-threads.exp: displaced-stepping=auto: target-non-stop=on: iter 8: continue
2025-01-28 11:55 [Bug gdb/32608] New: [gdb, -m32] FAIL: gdb.threads/step-over-thread-exit-while-stop-all-threads.exp: displaced-stepping=auto: target-non-stop=on: iter 8: continue vries at gcc dot gnu.org
@ 2025-01-28 11:56 ` vries at gcc dot gnu.org
0 siblings, 0 replies; 2+ messages in thread
From: vries at gcc dot gnu.org @ 2025-01-28 11:56 UTC (permalink / raw)
To: gdb-prs
https://sourceware.org/bugzilla/show_bug.cgi?id=32608
--- Comment #1 from Tom de Vries <vries at gcc dot gnu.org> ---
Tentative patch:
...
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 4687ee6edb3..019a8653d9f 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -5524,6 +5524,8 @@ handle_one (const wait_one_event &event)
("displaced-step of %s canceled",
t->ptid.to_string ().c_str ());
+ regcache_write_pc (get_thread_regcache (t), t->prev_pc);
+
t->control.trap_expected = 0;
if (!t->inf->detaching)
global_thread_step_over_chain_enqueue (t);
...
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-01-28 11:56 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-01-28 11:55 [Bug gdb/32608] New: [gdb, -m32] FAIL: gdb.threads/step-over-thread-exit-while-stop-all-threads.exp: displaced-stepping=auto: target-non-stop=on: iter 8: continue vries at gcc dot gnu.org
2025-01-28 11:56 ` [Bug gdb/32608] " vries at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).