native/Linux: internal error if resume is short-circuited

If the linux_nat_resume's short-circuits the resume because the
current thread has a pending status, and, a thread with a higher
number was previously stopped for a breakpoint, GDB internal errors,
like:

 /home/pedro/gdb/mygit/src/gdb/linux-nat.c:2590: internal-error: status_callback: Assertion `lp->status != 0' failed.

Fix this by make status_callback bail out earlier.  GDBserver is
already doing the same.

New test added that exercises this.

gdb/ChangeLog:
2015-03-19  Pedro Alves  <palves@redhat.com>

	* linux-nat.c (status_callback): Return early if the LWP has no
	status pending.

gdb/testsuite/ChangeLog:
2015-03-19  Pedro Alves  <palves@redhat.com>

	* gdb.threads/continue-pending-status.c: New file.
	* gdb.threads/continue-pending-status.exp: New file.
This commit is contained in:
Pedro Alves
2015-03-19 12:20:25 +00:00
parent b90fc18880
commit eb54c8bf08
5 changed files with 182 additions and 4 deletions

View File

@@ -2543,6 +2543,9 @@ status_callback (struct lwp_info *lp, void *data)
if (!lp->resumed)
return 0;
if (!lwp_status_pending_p (lp))
return 0;
if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
|| lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)
{
@@ -2551,8 +2554,6 @@ status_callback (struct lwp_info *lp, void *data)
CORE_ADDR pc;
int discard = 0;
gdb_assert (lp->status != 0);
pc = regcache_read_pc (regcache);
if (pc != lp->stop_pc)
@@ -2590,10 +2591,9 @@ status_callback (struct lwp_info *lp, void *data)
linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0);
return 0;
}
return 1;
}
return lwp_status_pending_p (lp);
return 1;
}
/* Return non-zero if LP isn't stopped. */