Re: linux native async mode support

Pedro Alves
2008-03-28T16:07:31Z

[-- Attachment #1: Type: text/plain, Size: 1667 bytes --]

A Friday 28 March 2008 14:47:54, Maciej W. Rozycki wrote:
> On Fri, 21 Mar 2008, Pedro Alves wrote:
> > This is what I checked in after another round of testing
> > on x86_64-unknown-linux-gnu.
>
> Hmm, I have narrowed it down to be the reason of breakage when the
> current head of the tree is built for the mipsisa32-sde-elf target. The
> symptom is when you run GBD interactively (no arguments) and enter any
> line for processing (a lone new-line character is enough), then the
> program crashes with SIGSEGV (an infinite recursion, it would seem).

Yes, it's infinite recursion. Thanks for spotting that, and sorry for
giving you trouble.

The problem comes from the way we cope to the fact that
target_can_async_p is called in several places before the
runnable target is pushed on the stack. This particular case was
happening in execute_command.

Currently, if no target is yet pushed, we default
to look for the default run target, and check if that can async.
On a cross-configured gdb, without a native debugger, there's no
default run target, so find_default_run_target calls error. As if
this wasn't a problematic enough, throw_exception ends up calling
target_can_async_p, which leads to infinite recursion. I know
that Vladimir has a two patches that remove these two problematic
target_can_async_p calls (one that removes the
command_list_handler_continuation, the other that removes the
target_can_async_p call from throw_exception), but that still
leaves a lot of call in infcmd.c, that I'm not sure we'll be able
to remove.

The attached fixes the problem for me. We're not really
interested in calling error in this case.

--
Pedro Alves

[-- Attachment #2: fix_inf_recursion.diff --]
[-- Type: text/x-diff, Size: 2383 bytes --]

2008-03-28 Pedro Alves <pedro@codesourcery.com>

* target.c (find_default_run_target): All a NULL `do_mesg'
parameter. If it is NULL, don't call error.
(find_default_can_async_p, find_default_is_async_p): Pass NULL as
`do_mesg'parameter to find_default_run_target. If no target was
found, return 0.

---
gdb/target.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)

Index: src/gdb/target.c
===================================================================
--- src.orig/gdb/target.c 2008-03-28 15:16:23.000000000 +0000
+++ src/gdb/target.c 2008-03-28 15:50:54.000000000 +0000
@@ -1782,7 +1782,8 @@ The \"%s\" target does not support \"run
execute a run or attach command without any other data. This is
used to locate the default process stratum.

- Result is always valid (error() is called for errors). */
+ If DO_MESG is not NULL, the result is always valid (error() is
+ called for errors); else, return NULL on error. */

static struct target_ops *
find_default_run_target (char *do_mesg)
@@ -1804,7 +1805,12 @@ find_default_run_target (char *do_mesg)
}

if (count != 1)
- error (_("Don't know how to %s. Try \"help target\"."), do_mesg);
+ {
+ if (do_mesg)
+ error (_("Don't know how to %s. Try \"help target\"."), do_mesg);
+ else
+ return NULL;
+ }

return runable;
}
@@ -1835,8 +1841,12 @@ find_default_can_async_p (void)
{
struct target_ops *t;

- t = find_default_run_target ("async");
- if (t->to_can_async_p)
+ /* This may be called before the target is pushed on the stack;
+ look for the default process stratum. If there's none, gdb isn't
+ configured with a native debugger, and target remote isn't
+ connected yet. */
+ t = find_default_run_target (NULL);
+ if (t && t->to_can_async_p)
return (t->to_can_async_p) ();
return 0;
}
@@ -1846,8 +1856,12 @@ find_default_is_async_p (void)
{
struct target_ops *t;

- t = find_default_run_target ("async");
- if (t->to_is_async_p)
+ /* This may be called before the target is pushed on the stack;
+ look for the default process stratum. If there's none, gdb isn't
+ configured with a native debugger, and target remote isn't
+ connected yet. */
+ t = find_default_run_target (NULL);
+ if (t && t->to_is_async_p)
return (t->to_is_async_p) ();
return 0;
}