This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: fix gdbserver's infinite loop when something goes wrong, after something having gone wrong...
- From: Pedro Alves <palves at redhat dot com>
- To: GDB Patches <gdb-patches at sourceware dot org>
- Date: Mon, 23 Jan 2012 16:42:53 +0000
- Subject: Re: fix gdbserver's infinite loop when something goes wrong, after something having gone wrong...
- References: <4F109365.30609@redhat.com>
On 01/13/2012 08:26 PM, Pedro Alves wrote:
> gdbserver can be caught in an infinite loop if something goes wrong
> and longjmp's while detaching or killing all inferiors, just before
> exiting. In my case, I'm hacking a board file that runs the whole
> testsuite in extended-remote mode against a local gdbserver, and I
> had a several-gigabytes gdb.log file filled with:
>
> ...
> Detaching process(es): 22031
> Couldn't write debug register
> Detaching process(es): 22031
> Couldn't write debug register
> Detaching process(es): 22031
> Couldn't write debug register
> Detaching process(es): 22031
> Couldn't write debug register
> Detaching process(es): 22031
> Couldn't write debug register
> Detaching process(es): 22031
> Couldn't write debug register
> Detaching process(es): 22031
> Couldn't write debug register
> Detaching process(es): 22031
> Couldn't write debug register
> Detaching process(es): 22031
> Couldn't write debug register
> Detaching process(es): 22031
> Couldn't write debug register
> Detaching process(es): 22031
> Couldn't write debug register
> Detaching process(es): 22031
> ...
>
> Obviously, detaching shouldn't have failed, but that's another story.
>
> The patch below fixes it.
>
> Note I'm thinking of making gdbserver also use gdb's exception/cleanup
> mechanism at some point.
There's another setjmp/longmp path in the same function that causes a
similar infinite loop... This patch fixes it.
Tested on x86_64 Fedora 16 local gdbserver, and applied.
2012-01-23 Pedro Alves <palves@redhat.com>
* server.c (main): Avoid yet another case of infinite loop while
detaching/killing after a longjmp.
---
gdb/gdbserver/server.c | 27 ++++++++++++++++++---------
1 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 3080a0c..c1788a9 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -2727,13 +2727,10 @@ main (int argc, char *argv[])
inferiors, we'd end up here again, stuck in an infinite loop
trap. Be sure that if that happens, we exit immediately
instead. */
- if (setjmp (toplevel))
- {
- fprintf (stderr, "Detach or kill failed. Exiting\n");
- exit (1);
- }
-
- detach_or_kill_for_exit ();
+ if (setjmp (toplevel) == 0)
+ detach_or_kill_for_exit ();
+ else
+ fprintf (stderr, "Detach or kill failed. Exiting\n");
exit (1);
}
@@ -2779,8 +2776,20 @@ main (int argc, char *argv[])
if (exit_requested || run_once)
{
- detach_or_kill_for_exit ();
- exit (0);
+ /* If something fails and longjmps while detaching or
+ killing inferiors, we'd end up here again, stuck in an
+ infinite loop trap. Be sure that if that happens, we
+ exit immediately instead. */
+ if (setjmp (toplevel) == 0)
+ {
+ detach_or_kill_for_exit ();
+ exit (0);
+ }
+ else
+ {
+ fprintf (stderr, "Detach or kill failed. Exiting\n");
+ exit (1);
+ }
}
fprintf (stderr,