old-cross-binutils/gdb/testsuite/gdb.base/step-over-exit.c
Yao Qi f50bf8e515 Step over exit with reinsert breakpoints
This patch fixes a GDBserver crash when one thread is stepping over
a syscall instruction which is exit.  Step-over isn't finished due
to the exit, but GDBserver doesn't clean up the state of step-over,
so in the wait next time, GDBserver will wait on step_over_bkpt,
which is already exited, and GDBserver crashes because
'requested_child' is NULL.  See gdbserver logs below,

Need step over [LWP 14858]? yes, found breakpoint at 0x2aaaaad91307^M
proceed_all_lwps: found thread 14858 needing a step-over^M
Starting step-over on LWP 14858.  Stopping all threads^M
>>>> entering void stop_all_lwps(int, lwp_info*)
....
<<<< exiting void stop_all_lwps(int, lwp_info*)^M
Done stopping all threads for step-over.^M
pc is 0x2aaaaad91307^M
Writing 0f to 0x2aaaaad91307 in process 14858^M
Could not find fast tracepoint jump at 0x2aaaaad91307 in list (uninserting).^M
  pending reinsert at 0x2aaaaad91307^M
  step from pc 0x2aaaaad91307^M
Resuming lwp 14858 (step, signal 0, stop not expected)^M

 # Start step-over for LWP 14858

>>>> entering ptid_t linux_wait_1(ptid_t, target_waitstatus*, int)
....
LLFE: 14858 exited.
...
<<<< exiting ptid_t linux_wait_1(ptid_t, target_waitstatus*, int)

  # LWP 14858 exited
.....
>>>> entering ptid_t linux_wait_1(ptid_t, target_waitstatus*, int)^M
linux_wait_1: [<all threads>]^M
step_over_bkpt set [LWP 14858.14858], doing a blocking wait

  # but step_over_bkpt is still LWP 14858, which is wrong

The fix is to finish step-over if it is ongoing, and unsuspend other
threads.  Without the fix in linux-low.c, GDBserver will crash in
with running gdb.base/step-over-exit.exp.

gdb/gdbserver:

2016-06-17  Yao Qi  <yao.qi@linaro.org>

	* linux-low.c (unsuspend_all_lwps): Declare.
	(linux_low_filter_event): If thread exited, call finish_step_over.
	If step-over is finished, unsuspend other threads.

gdb/testsuite:

2016-06-17  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/step-over-exit.c: New.
	* gdb.base/step-over-exit.exp: New.
2016-06-17 10:38:55 +01:00

50 lines
1.1 KiB
C

/* This testcase is part of GDB, the GNU debugger.
Copyright 2016 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/>. */
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
static void
marker (void)
{}
int
main (void)
{
int pid;
pid = fork ();
if (pid == 0) /* child */
{
_exit (0);
}
else
{
}
pid = fork ();
if (pid == 0) /* child */
{
marker ();
_exit (0);
}
else
{
marker ();
}
}