From patchwork Thu Mar 13 19:02:48 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 74 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx21.g.dreamhost.com (caibbdcaaahb.dreamhost.com [208.113.200.71]) by wilcox.dreamhost.com (Postfix) with ESMTP id D19763600C0 for ; Thu, 13 Mar 2014 12:02:58 -0700 (PDT) Received: by homiemail-mx21.g.dreamhost.com (Postfix, from userid 14314964) id 8568CC86E84; Thu, 13 Mar 2014 12:02:58 -0700 (PDT) X-Original-To: gdb@patchwork.siddhesh.in Delivered-To: x14314964@homiemail-mx21.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx21.g.dreamhost.com (Postfix) with ESMTPS id 4E619C388BB for ; Thu, 13 Mar 2014 12:02:58 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; q=dns; s= default; b=y3KSpRYGUP4R3ntY033YfrOF9qYwi1SeVfXt/h/IHD3ibvOcf7sC3 v1E5ZvPVzg5vCeWbFdP6HKsTO3o1UExBITZd9PgsIOoC/b+Xqt71WZj8mw299VU3 OSxtp0mXLbtat1nxDfJsYm3E/njIwMPOki0adDMnG0dfP40uJTQWu0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; s=default; bh=Z/S1mhdqsE+vAGu0rt2zNNNbljI=; b=CZ/fwDTWycpfK0TaY3MfinatTr8C k8hn/lR4wue1GDpAXueta3MaAF0FSgEgDIZQQiYH3vz4dW1eMi2qk01AnApkzGnE j9YFoFh36+7tNlIm8nowX98UDLKEzCc3XJqoUnDgtQsSAkMoKFAIlo53VbkgFWP5 1RR077ppp8O7kI4= Received: (qmail 30171 invoked by alias); 13 Mar 2014 19:02:55 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 30161 invoked by uid 89); 13 Mar 2014 19:02:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 13 Mar 2014 19:02:53 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s2DJ2oG7011742 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 13 Mar 2014 15:02:51 -0400 Received: from brno.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s2DJ2mx6020303 for ; Thu, 13 Mar 2014 15:02:49 -0400 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [RFC PATCH] Allow disabling the default run target. Date: Thu, 13 Mar 2014 19:02:48 +0000 Message-Id: <1394737368-29334-1-git-send-email-palves@redhat.com> X-DH-Original-To: gdb@patchwork.siddhesh.in Wonder what people think of this. This is practically done, but misses tests. I'll try writing some if people agree with the approach. Sometimes it's useful to be able to disable the default run target. E.g., sometimes GDB disconnects from the extended-remote target I was debugging, without me noticing it, and then I do "run". That starts the program locally, and only after a little head scratch session do I figure out the program is running locally instead of remotely as intended. Same thing with "attach", "info os", etc. With the patch, we now can have this instead: (gdb) set default-run-target off (gdb) target extended-remote :9999 ... *gdb disconnects* (gdb) run Don't know how to run. Try "help target". To still be able to connect to the native target with default-run-target set to off, I've made "target child" work instead of erroring out as today. Before: (gdb) target child Use the "run" command to start a child process. After: (gdb) target child (gdb) maint print target-stack The current target stack is: - child (Child process) - exec (Local exec file) - None (None) (gdb) run Starting program: ./a.out ... I've also wanted this for the testsuite, when running against the native-extended-gdbserver.exp board (runs against gdbserver in extended-remote mode). With that board, it's always a bug to launch a program with the native target. Turns out we still have one such case this patch catches: (gdb) break main Breakpoint 1 at 0x4009e5: file ../../../src/gdb/testsuite/gdb.base/coremaker.c, line 138. (gdb) run Don't know how to run. Try "help target". (gdb) FAIL: gdb.base/corefile.exp: run: with core Tested on x86_64 Fedora 17, native, and also with the extended-gdbserver board. gdb/ 2014-03-13 Pedro Alves * inf-child.c (inf_child_ops, inf_child_explicitly_opened): New globals. (inf_child_open): Push the target instead of erroring out. (inf_child_disconnect, inf_child_close, inf_child_maybe_unpush): New functions. (inf_child_target): Install inf_child_disconnect and inf_child_close. Store a pointer to the returned object. * inf-child.h (inf_child_maybe_unpush): New declaration. * inf-ptrace.c (inf_ptrace_mourn_inferior, inf_ptrace_detach): Use inf_child_maybe_unpush. * linux-nat.c (super_close): New global. (linux_nat_close): Call super_close. (linux_nat_add_target): Store a pointer to the base class's to_close method. * target.c (default_run_target): New global. (show_default_run_target): New function. (find_default_run_target): Return NULL if falling back to the default run target is disabled. (_initialize_target): Install set/show default-run-target. * NEWS: Mention "set default-run-target", and target child. gdb/doc/ 2014-03-13 Pedro Alves * gdb.texinfo (Starting): Document "set/show default-run-target". (Target Commands): Document "target child". gdb/testsuite/ 2014-03-13 Pedro Alves * boards/native-extended-gdbserver.exp (GDBFLAGS): Set to "set default-run-target off". --- gdb/NEWS | 11 ++++ gdb/doc/gdb.texinfo | 58 ++++++++++++++++++++++ gdb/inf-child.c | 44 +++++++++++++++- gdb/inf-child.h | 2 + gdb/inf-ptrace.c | 6 +-- gdb/linux-nat.c | 8 +++ gdb/target.c | 48 ++++++++++++++---- gdb/testsuite/boards/native-extended-gdbserver.exp | 2 + 8 files changed, 164 insertions(+), 15 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index 2a384ba..8ed796c 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -43,6 +43,12 @@ maint ada show ignore-descriptive-types the user manual for more details on descriptive types and the intended usage of this option. +set default-run-target + Control whether GDB is allowed to fall back to the default run + target (usually the native target) for the run, attach, + etc. commands when not connected to any target yet. See also + "target child" below. + * New features in the GDB remote stub, GDBserver ** New option --debug-format=option1[,option2,...] allows one to add @@ -76,6 +82,11 @@ maint ada show ignore-descriptive-types * The "catch syscall" command now works on s390*-linux* targets. +* The "target child" command now connects to the default run target + (usually the native target) instead of erroring out. This can be + used to launch native programs when "set default-run-target" is set + to off. + * New remote packets qXfer:btrace:read's annex diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index de5ac63..f2b39af 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -2146,6 +2146,57 @@ initialization file---such as @file{.cshrc} for C-shell, $@file{.zshenv} for the Z shell, or the file specified in the @samp{BASH_ENV} environment variable for BASH. +@anchor{set default-run-target} +@kindex set default-run-target +@item set default-run-target +@itemx set default-run-target on +@itemx set default-run-target off +@itemx show default-run-target + +By default, if not connected to any target yet (e.g., with +@code{target remote}), the @code{run} command starts your program +under @value{GDBN}, on your local machine. When you're sure you don't +want to debug programs on your local machine, you can tell +@value{GDBN} to not fall back to the default native target with the +@code{set default-run-target off} command. + +If @code{on}, which is the default, and if @value{GDBN} is not +connected to a target already, the @code{run} command uses the default +native target, if one is available. + +If @code{off}, and if @value{GDBN} is not connected to a target +already, the @code{run} command fail with an error: + +@smallexample +(@value{GDBP}) run +Don't know how to run. Try "help target". +@end smallexample + +If @value{GDBN} is already connected to a target, @value{GDBN} always +uses it with the @code{run} command. + +In any case, you can explicitly connect to the default native target +with the @code{target child} command. For example, + +@smallexample +(@value{GDBP}) set default-run-target off +(@value{GDBP}) run +Don't know how to run. Try "help target". +(@value{GDBP}) target child +(@value{GDBP}) run +Starting program: ./a.out +[Inferior 1 (process 10421) exited normally] +@end smallexample + +In case you connected explicitly to the @code{target child} target, +@value{GDBN} remains connected even if all inferiors exit, ready for +the next @code{run} command. Use the @code{disconnect} command to +disconnect from the @code{child} target. + +Examples of other commands that likewise respect the +@code{default-run-target} setting: @code{run}, @code{attach}, +@code{info proc}, @code{info osdata}. + @kindex set disable-randomization @item set disable-randomization @itemx set disable-randomization on @@ -18050,6 +18101,13 @@ provide these. For info about any processor-specific simulator details, see the appropriate section in @ref{Embedded Processors, ,Embedded Processors}. +@item target child +@cindex native target +Setup for local/native process debugging. Useful to make the +@code{run}, @code{attach}, etc.@: commands spawn native processes even +when @code{set default-run-target} is @code{off} (@pxref{set +default-run-target}). + @end table Different targets are available on different configurations of @value{GDBN}; diff --git a/gdb/inf-child.c b/gdb/inf-child.c index cc16b40..d6aebf5 100644 --- a/gdb/inf-child.c +++ b/gdb/inf-child.c @@ -40,6 +40,10 @@ #include #include +/* A pointer to what is returned by inf_child_target. Used to be able + to push the most-derived target in reaction to "target child". */ +static struct target_ops *inf_child_ops = NULL; + /* Helper function for child_wait and the derivatives of child_wait. HOSTSTATUS is the waitstatus from wait() or the equivalent; store our translation of that in OURSTATUS. */ @@ -109,10 +113,41 @@ inf_child_prepare_to_store (struct target_ops *self, { } +/* True if the user did "target child". In that case, we won't unpush + the child target automatically when the last inferior is gone. */ +static int inf_child_explicitly_opened; + static void inf_child_open (char *arg, int from_tty) { - error (_("Use the \"run\" command to start a child process.")); + target_preopen (from_tty); + push_target (inf_child_ops); + inf_child_explicitly_opened = 1; +} + +static void +inf_child_disconnect (struct target_ops *target, char *args, int from_tty) +{ + if (args != NULL) + error (_("Argument given to \"disconnect\".")); + + /* This offers to detach/kill current inferiors, and then pops all + targets. */ + target_preopen (from_tty); +} + +static void +inf_child_close (struct target_ops *target) +{ + /* In case we were forcibly closed. */ + inf_child_explicitly_opened = 0; +} + +void +inf_child_maybe_unpush (struct target_ops *ops) +{ + if (!inf_child_explicitly_opened && !have_inferiors ()) + unpush_target (ops); } static void @@ -410,6 +445,8 @@ inf_child_target (void) t->to_longname = "Child process"; t->to_doc = "Child process (started by the \"run\" command)."; t->to_open = inf_child_open; + t->to_close = inf_child_close; + t->to_disconnect = inf_child_disconnect; t->to_post_attach = inf_child_post_attach; t->to_fetch_registers = inf_child_fetch_inferior_registers; t->to_store_registers = inf_child_store_inferior_registers; @@ -445,5 +482,10 @@ inf_child_target (void) t->to_magic = OPS_MAGIC; t->to_use_agent = inf_child_use_agent; t->to_can_use_agent = inf_child_can_use_agent; + + /* Store a pointer so we can push the target from + inf_child_open. */ + inf_child_ops = t; + return t; } diff --git a/gdb/inf-child.h b/gdb/inf-child.h index 4473cff..56c69fe 100644 --- a/gdb/inf-child.h +++ b/gdb/inf-child.h @@ -25,6 +25,8 @@ extern struct target_ops *inf_child_target (void); +extern void inf_child_maybe_unpush (struct target_ops *ops); + /* Functions for helping to write a native target. */ /* This is for native targets which use a unix/POSIX-style waitstatus. */ diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c index bffb4ba..7d077b8 100644 --- a/gdb/inf-ptrace.c +++ b/gdb/inf-ptrace.c @@ -176,8 +176,7 @@ inf_ptrace_mourn_inferior (struct target_ops *ops) generic_mourn_inferior (); - if (!have_inferiors ()) - unpush_target (ops); + inf_child_maybe_unpush (ops); } /* Attach to the process specified by ARGS. If FROM_TTY is non-zero, @@ -297,8 +296,7 @@ inf_ptrace_detach (struct target_ops *ops, const char *args, int from_tty) inferior_ptid = null_ptid; detach_inferior (pid); - if (!have_inferiors ()) - unpush_target (ops); + inf_child_maybe_unpush (ops); } /* Kill the inferior. */ diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 5535462..f9b0ed0 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -201,6 +201,10 @@ static int (*linux_nat_siginfo_fixup) (siginfo_t *, Called by our to_xfer_partial. */ static target_xfer_partial_ftype *super_xfer_partial; +/* The saved to_close method, inherited from inf-ptrace.c. + Called by our to_close. */ +static void (*super_close) (struct target_ops *); + static unsigned int debug_linux_nat; static void show_debug_linux_nat (struct ui_file *file, int from_tty, @@ -4776,6 +4780,8 @@ linux_nat_close (struct target_ops *self) if (linux_ops->to_close) linux_ops->to_close (linux_ops); + + super_close (self); } /* When requests are passed down from the linux-nat layer to the @@ -4857,6 +4863,8 @@ linux_nat_add_target (struct target_ops *t) t->to_async = linux_nat_async; t->to_terminal_inferior = linux_nat_terminal_inferior; t->to_terminal_ours = linux_nat_terminal_ours; + + super_close = t->to_close; t->to_close = linux_nat_close; /* Methods for non-stop support. */ diff --git a/gdb/target.c b/gdb/target.c index 0d22297..ca7a56f 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -2574,6 +2574,20 @@ target_require_runnable (void) internal_error (__FILE__, __LINE__, _("No targets found")); } +/* Whether GDB is allowed to fall back to the default run target for + "run", "attach", etc. when no target is connected yet. */ +static int default_run_target = 1; + +static void +show_default_run_target (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, + _("Whether GDB may fall back to the " + "default run target is %s.\n"), + value); +} + /* Look through the list of possible targets for a target that can execute a run or attach command without any other data. This is used to locate the default process stratum. @@ -2584,23 +2598,28 @@ target_require_runnable (void) static struct target_ops * find_default_run_target (char *do_mesg) { - struct target_ops **t; struct target_ops *runable = NULL; - int count; - count = 0; - - for (t = target_structs; t < target_structs + target_struct_size; - ++t) + if (default_run_target) { - if ((*t)->to_can_run != delegate_can_run && target_can_run (*t)) + struct target_ops **t; + int count = 0; + + for (t = target_structs; t < target_structs + target_struct_size; + ++t) { - runable = *t; - ++count; + if ((*t)->to_can_run != delegate_can_run && target_can_run (*t)) + { + runable = *t; + ++count; + } } + + if (count != 1) + runable = NULL; } - if (count != 1) + if (runable == NULL) { if (do_mesg) error (_("Don't know how to %s. Try \"help target\"."), do_mesg); @@ -4369,4 +4388,13 @@ When this permission is on, GDB may interrupt/stop the target's execution.\n\ Otherwise, any attempt to interrupt or stop will be ignored."), set_target_permissions, NULL, &setlist, &showlist); + + add_setshow_boolean_cmd ("default-run-target", class_support, + &default_run_target, _("\ +Set whether GDB may fall back to the default run target."), _("\ +Show whether GDB may fall back to the default run target."), _("\ +When on, and GDB is not connected to a target yet, GDB\n\ +attempts \"run\" and other commands with the default run target."), + NULL, show_default_run_target, + &setlist, &showlist); } diff --git a/gdb/testsuite/boards/native-extended-gdbserver.exp b/gdb/testsuite/boards/native-extended-gdbserver.exp index 8bb95db..d6959a7 100644 --- a/gdb/testsuite/boards/native-extended-gdbserver.exp +++ b/gdb/testsuite/boards/native-extended-gdbserver.exp @@ -36,6 +36,8 @@ set_board_info gdb_protocol "extended-remote" send_user "configuring for gdbserver local testing (extended-remote)\n" +set GDBFLAGS "${GDBFLAGS} -ex \"set default-run-target off\"" + # We must load this explicitly here, and rename the procedures we want # to override. If we didn't do this, given that mi-support.exp is # loaded later in the test files, the procedures loaded then would