From patchwork Thu Jul 3 15:18: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: 1886 Received: (qmail 26903 invoked by alias); 3 Jul 2014 15:19:06 -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 26750 invoked by uid 89); 3 Jul 2014 15:19:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 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 (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 03 Jul 2014 15:19:00 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s63FIxE9014431 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 3 Jul 2014 11:18:59 -0400 Received: from brno.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s63FIu95024009 for ; Thu, 3 Jul 2014 11:18:58 -0400 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 1/9] Put the inferior's terminal settings in effect while running (fg) infcalls Date: Thu, 3 Jul 2014 16:18:48 +0100 Message-Id: <1404400736-17307-2-git-send-email-palves@redhat.com> In-Reply-To: <1404400736-17307-1-git-send-email-palves@redhat.com> References: <1404400736-17307-1-git-send-email-palves@redhat.com> The "call" and "print" commands presently always run synchronously, in the foreground, but GDB currently forgets to put the inferior's terminal settings into effect while running them, on async-capable targets, resulting in: (gdb) print func () hello world Program received signal SIGTTOU, Stopped (tty output). 0x000000373bceb8d0 in __libc_tcdrain (fd=1) at ../sysdeps/unix/sysv/linux/tcdrain.c:29 29 return INLINE_SYSCALL (ioctl, 3, fd, TCSBRK, 1); The program being debugged was signaled while in a function called from GDB. GDB remains in the frame where the signal was received. To change this behavior use "set unwindonsignal on". Evaluation of the expression containing the function (func) will be abandoned. When the function is done executing, GDB will silently stop. (gdb) That's because target_terminal_inferior skips actually doing anything if running in the background, and, nothing is setting sync_execution while running infcalls: void target_terminal_inferior (void) { /* A background resume (``run&'') should leave GDB in control of the terminal. Use target_can_async_p, not target_is_async_p, since at this point the target is not async yet. However, if sync_execution is not set, we know it will become async prior to resume. */ if (target_can_async_p () && !sync_execution) return; This would best be all cleaned up by making GDB not even call target_terminal_inferior and try to pass the terminal to the inferior if running in the background, but that's a more invasive fix that is better done post-7.8. This was originally caught by a patch later in this series that makes catch_command_errors use exception_print instead of print_any_exception. Note that print_flush calls serial_drain_output while print_any_exception doesnt't have that bit. And, gdb.gdb/python-selftest.exp does: gdb_test "call catch_command_errors(execute_command, \"python print 5\", 0, RETURN_MASK_ALL)" \ "Python not initialized.* = 0" which without this fix results in SIGTTOU... gdb/testsuite/ 2014-07-03 Pedro Alves * infcall.c (run_inferior_call): Set 'sync_execution' while running the inferior call. gdb/testsuite/ 2014-07-03 Pedro Alves * gdb.base/execution-termios.c: New file. * gdb.base/execution-termios.exp: New file. --- gdb/infcall.c | 7 ++++ gdb/testsuite/gdb.base/execution-termios.c | 35 ++++++++++++++++ gdb/testsuite/gdb.base/execution-termios.exp | 60 ++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 gdb/testsuite/gdb.base/execution-termios.c create mode 100644 gdb/testsuite/gdb.base/execution-termios.exp diff --git a/gdb/infcall.c b/gdb/infcall.c index 52f0612..a9b1ceb 100644 --- a/gdb/infcall.c +++ b/gdb/infcall.c @@ -388,6 +388,11 @@ run_inferior_call (struct thread_info *call_thread, CORE_ADDR real_pc) volatile struct gdb_exception e; int saved_in_infcall = call_thread->control.in_infcall; ptid_t call_thread_ptid = call_thread->ptid; + int saved_sync_execution = sync_execution; + + /* Infcalls run synchronously, in the foreground. */ + if (target_can_async_p ()) + sync_execution = 1; call_thread->control.in_infcall = 1; @@ -441,6 +446,8 @@ run_inferior_call (struct thread_info *call_thread, CORE_ADDR real_pc) if (call_thread != NULL) call_thread->control.in_infcall = saved_in_infcall; + sync_execution = saved_sync_execution; + return e; } diff --git a/gdb/testsuite/gdb.base/execution-termios.c b/gdb/testsuite/gdb.base/execution-termios.c new file mode 100644 index 0000000..adeb1f1 --- /dev/null +++ b/gdb/testsuite/gdb.base/execution-termios.c @@ -0,0 +1,35 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include +#include + +int +func (void) +{ + puts ("hello world\n"); + tcdrain (fileno (stdout)); + return 1; +} + +int +main (void) +{ + func (); + return 0; /* set break here */ +} diff --git a/gdb/testsuite/gdb.base/execution-termios.exp b/gdb/testsuite/gdb.base/execution-termios.exp new file mode 100644 index 0000000..cbdcce6 --- /dev/null +++ b/gdb/testsuite/gdb.base/execution-termios.exp @@ -0,0 +1,60 @@ +# Copyright 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . */ + +standard_testfile + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { + return -1 +} + +# Run to main, and execute BODY in the caller's context, with PREFIX +# set as test message prefix. + +proc test { prefix body } { + with_test_prefix $prefix { + if ![runto_main] { + fail "Can't run to main" + return 0 + } + uplevel 1 $body + } +} + +# If GDB forgets to put the inferior's terminal settings into effect +# while running any of these commands, the program will get a SIGTTOU. + +test "next" { + gdb_test "next" "set break here.*" "termios ok" +} + +test "infcall" { + if ![target_info exists gdb,cannot_call_functions] { + gdb_test "print func ()" " = 1" "termios ok" + } else { + unsupported "cannot call functions" + } +} + +test "continue" { + set lineno [gdb_get_line_number "set break here"] + gdb_test "break $lineno" + gdb_test "continue" ".*set break here.*" "termios ok" +} + +test "finish" { + gdb_test "break func" "func.*" + gdb_test "continue" "func .*" + gdb_test "finish" " = 1" "termios ok" +}