mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-10-15 03:48:11 +08:00
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.
This commit is contained in:
@ -1,3 +1,9 @@
|
||||
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.
|
||||
|
||||
2016-06-17 Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* linux-low.c (linux_resume_one_lwp_throw): Assert
|
||||
|
@ -252,6 +252,7 @@ static void linux_resume_one_lwp (struct lwp_info *lwp,
|
||||
static void linux_resume (struct thread_resume *resume_info, size_t n);
|
||||
static void stop_all_lwps (int suspend, struct lwp_info *except);
|
||||
static void unstop_all_lwps (int unsuspend, struct lwp_info *except);
|
||||
static void unsuspend_all_lwps (struct lwp_info *except);
|
||||
static int linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
|
||||
int *wstat, int options);
|
||||
static int linux_wait_for_event (ptid_t ptid, int *wstat, int options);
|
||||
@ -2357,6 +2358,13 @@ linux_low_filter_event (int lwpid, int wstat)
|
||||
{
|
||||
if (debug_threads)
|
||||
debug_printf ("LLFE: %d exited.\n", lwpid);
|
||||
|
||||
if (finish_step_over (child))
|
||||
{
|
||||
/* Unsuspend all other LWPs, and set them back running again. */
|
||||
unsuspend_all_lwps (child);
|
||||
}
|
||||
|
||||
/* If there is at least one more LWP, then the exit signal was
|
||||
not the end of the debugged application and should be
|
||||
ignored, unless GDB wants to hear about thread exits. */
|
||||
|
Reference in New Issue
Block a user