diff --git a/gdb-archer.patch b/gdb-archer.patch index 48f0b8c..d6c8e38 100644 --- a/gdb-archer.patch +++ b/gdb-archer.patch @@ -35,21 +35,21 @@ Index: gdb-7.8/gdb/data-directory/Makefile.in =================================================================== --- gdb-7.8.orig/gdb/data-directory/Makefile.in 2014-07-29 19:29:02.665979655 +0200 +++ gdb-7.8/gdb/data-directory/Makefile.in 2014-07-29 19:29:33.053022486 +0200 -@@ -66,6 +66,8 @@ PYTHON_FILE_LIST = \ +@@ -65,6 +65,8 @@ PYTHON_FILE_LIST = \ + gdb/prompt.py \ gdb/xmethod.py \ - gdb/command/bound_registers.py \ gdb/command/__init__.py \ + gdb/command/ignore_errors.py \ + gdb/command/pahole.py \ gdb/command/xmethods.py \ gdb/command/frame_filters.py \ gdb/command/type_printers.py \ -@@ -73,7 +75,10 @@ PYTHON_FILE_LIST = \ - gdb/command/prompt.py \ - gdb/command/explore.py \ +@@ -74,7 +76,10 @@ PYTHON_FILE_LIST = \ gdb/function/__init__.py \ -- gdb/function/strfns.py -+ gdb/function/strfns.py \ + gdb/function/strfns.py \ + gdb/printer/__init__.py \ +- gdb/printer/bound_registers.py ++ gdb/printer/bound_registers.py \ + gdb/function/caller_is.py \ + gdb/function/in_scope.py \ + gdb/types.py diff --git a/gdb-dts-rhel6-python-compat.patch b/gdb-dts-rhel6-python-compat.patch index 3688713..a81e942 100644 --- a/gdb-dts-rhel6-python-compat.patch +++ b/gdb-dts-rhel6-python-compat.patch @@ -1,10 +1,10 @@ https://bugzilla.redhat.com/show_bug.cgi?id=1020004 -Index: gdb-7.7.90.20140613/gdb/data-directory/Makefile.in +Index: gdb-7.8/gdb/data-directory/Makefile.in =================================================================== ---- gdb-7.7.90.20140613.orig/gdb/data-directory/Makefile.in 2014-06-13 23:02:37.597115787 +0200 -+++ gdb-7.7.90.20140613/gdb/data-directory/Makefile.in 2014-06-13 23:03:21.285163909 +0200 -@@ -60,6 +60,8 @@ PYTHON_FILES = \ +--- gdb-7.8.orig/gdb/data-directory/Makefile.in 2014-10-19 18:25:34.187110261 +0200 ++++ gdb-7.8/gdb/data-directory/Makefile.in 2014-10-19 18:25:51.092121706 +0200 +@@ -60,6 +60,8 @@ PYTHON_FILE_LIST = \ gdb/frames.py \ gdb/FrameIterator.py \ gdb/FrameDecorator.py \ @@ -13,18 +13,18 @@ Index: gdb-7.7.90.20140613/gdb/data-directory/Makefile.in gdb/types.py \ gdb/printing.py \ gdb/prompt.py \ -@@ -74,6 +76,7 @@ PYTHON_FILES = \ +@@ -73,6 +75,7 @@ PYTHON_FILE_LIST = \ gdb/command/pretty_printers.py \ gdb/command/prompt.py \ gdb/command/explore.py \ + gdb/command/backtrace.py \ gdb/function/__init__.py \ gdb/function/strfns.py \ - gdb/function/caller_is.py \ -Index: gdb-7.7.90.20140613/gdb/python/lib/gdb/FrameWrapper.py + gdb/printer/__init__.py \ +Index: gdb-7.8/gdb/python/lib/gdb/FrameWrapper.py =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.7.90.20140613/gdb/python/lib/gdb/FrameWrapper.py 2014-06-13 23:02:37.598115788 +0200 ++++ gdb-7.8/gdb/python/lib/gdb/FrameWrapper.py 2014-10-19 18:25:36.808112031 +0200 @@ -0,0 +1,122 @@ +# Wrapper API for frames. + @@ -148,10 +148,10 @@ Index: gdb-7.7.90.20140613/gdb/python/lib/gdb/FrameWrapper.py + + def __getattr__ (self, name): + return getattr (self.frame, name) -Index: gdb-7.7.90.20140613/gdb/python/lib/gdb/backtrace.py +Index: gdb-7.8/gdb/python/lib/gdb/backtrace.py =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.7.90.20140613/gdb/python/lib/gdb/backtrace.py 2014-06-13 23:02:37.598115788 +0200 ++++ gdb-7.8/gdb/python/lib/gdb/backtrace.py 2014-10-19 18:25:36.808112031 +0200 @@ -0,0 +1,42 @@ +# Filtering backtrace. + @@ -195,10 +195,10 @@ Index: gdb-7.7.90.20140613/gdb/python/lib/gdb/backtrace.py + return iter + return old_frame_filter (iter) + -Index: gdb-7.7.90.20140613/gdb/python/lib/gdb/command/backtrace.py +Index: gdb-7.8/gdb/python/lib/gdb/command/backtrace.py =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ gdb-7.7.90.20140613/gdb/python/lib/gdb/command/backtrace.py 2014-06-13 23:02:37.598115788 +0200 ++++ gdb-7.8/gdb/python/lib/gdb/command/backtrace.py 2014-10-19 18:25:36.808112031 +0200 @@ -0,0 +1,106 @@ +# New backtrace command. + diff --git a/gdb-upstream.patch b/gdb-upstream.patch index 028fe7a..9d2bac8 100644 --- a/gdb-upstream.patch +++ b/gdb-upstream.patch @@ -65,3 +65,1708 @@ index 0e0202d..d849b4c 100644 # gdbserver does not have this issue. if ![is_remote target] { setup_kfail "*-*-*" gdb/15934 +From 63fcc8bcd98a8cd9672dd8672f663662f8caa811 Mon Sep 17 00:00:00 2001 +From: Pedro Alves +Date: Wed, 1 Oct 2014 10:44:08 +0100 +Subject: [PATCH 13/37] Aarch64: Make CPSR a 32-bit register again in the + target description + +This reverts commit a4d9ba85 - 'AARCH64: Change cpsr type to be +64bit.'. + +Even though Linux's ptrace exposes CPSR as 64-bit, CPSR is really +32-bit, and basing GDB's fundamentals on a particular OS's ptrace(2) +implementation is a bad idea. + +In addition, while that commit intended to fix big endian Aarch64, it +ended up breaking floating point debugging against GDBserver, for both +big and little endian, because it changed the CPSR to be 64-bit in the +features/aarch64-core.xml file, but missed regenerating the +regformats/aarch64.dat file. If we generate it now, we see this: + + diff --git c/gdb/regformats/aarch64.dat w/gdb/regformats/aarch64.dat + index afe1028..0d32183 100644 + --- c/gdb/regformats/aarch64.dat + +++ w/gdb/regformats/aarch64.dat + @@ -35,7 +35,7 @@ expedite:x29,sp,pc + 64:x30 + 64:sp + 64:pc + -32:cpsr + +64:cpsr + 128:v0 + 128:v1 + 128:v2 + +IOW, that commit left regformats/aarch64.dat still considering CPSR as +32-bits. regformats/aarch64.dat is used by GDBserver for its internal +regcache layout, and for the g/G packet register block. See the +generated aarch64.c file in GDBserver's build dir. + +So the target description xml file that GDBserver reports to GDB is +now claiming that CPSR is 64-bit, but what GDBserver actually puts in +the g/G register packets is 32-bits. Because GDB thinks CPSR is +64-bit (because that's what the XML description says), GDB will be +reading the remaining 32-bit bits of CPSR out of v0 (the register +immediately afterwards), and then all the registers that follow CPSR +in the register packet end up wrong in GDB, because they're being read +from the wrong offsets... + +gdb/ +2014-10-01 Pedro Alves + + * features/aarch64-core.xml (cpsr): Change back to 32-bit. + * features/aarch64.c: Regenerate. +--- + gdb/ChangeLog | 5 +++++ + gdb/features/aarch64-core.xml | 2 +- + gdb/features/aarch64.c | 2 +- + 3 files changed, 7 insertions(+), 2 deletions(-) + +### a/gdb/ChangeLog +### b/gdb/ChangeLog +## -1,3 +1,8 @@ ++2014-10-01 Pedro Alves ++ ++ * features/aarch64-core.xml (cpsr): Change back to 32-bit. ++ * features/aarch64.c: Regenerate. ++ + 2014-09-11 Pedro Alves + + PR gdb/17347 +--- a/gdb/features/aarch64-core.xml ++++ b/gdb/features/aarch64-core.xml +@@ -42,5 +42,5 @@ + + + +- ++ + +--- a/gdb/features/aarch64.c ++++ b/gdb/features/aarch64.c +@@ -50,7 +50,7 @@ initialize_tdesc_aarch64 (void) + tdesc_create_reg (feature, "x30", 30, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "sp", 31, 1, NULL, 64, "data_ptr"); + tdesc_create_reg (feature, "pc", 32, 1, NULL, 64, "code_ptr"); +- tdesc_create_reg (feature, "cpsr", 33, 1, NULL, 64, "int"); ++ tdesc_create_reg (feature, "cpsr", 33, 1, NULL, 32, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.fpu"); + field_type = tdesc_named_type (feature, "ieee_double"); +-- +1.9.3 + +From 244fe82b9c6542557a1c2d4d21af1092692d377f Mon Sep 17 00:00:00 2001 +From: Doug Evans +Date: Wed, 15 Oct 2014 13:23:23 -0700 +Subject: [PATCH 29/37] PR python/17364 + +gdb/ChangeLog: + + * python/lib/gdb/__init__.py (packages): Add "printer". + * python/lib/gdb/command/bound_registers.py: Moved to ... + * python/lib/gdb/printer/bound_registers.py: ... here. + Add printer to global set of builtin printers. Rename printer from + "bound" to "mpx_bound128". + * python/lib/gdb/printing.py (_builtin_pretty_printers): New global, + registered as global "builtin" printer. + (add_builtin_pretty_printer): New function. + * data-directory/Makefile.in (PYTHON_FILE_LIST): Update, and add + gdb/printer/__init__.py. +--- + gdb/ChangeLog | 15 +++++++++ + gdb/data-directory/Makefile.in | 5 +-- + gdb/python/lib/gdb/__init__.py | 3 +- + gdb/python/lib/gdb/command/bound_registers.py | 45 --------------------------- + gdb/python/lib/gdb/printer/__init__.py | 14 +++++++++ + gdb/python/lib/gdb/printer/bound_registers.py | 36 +++++++++++++++++++++ + gdb/python/lib/gdb/printing.py | 14 +++++++++ + 7 files changed, 84 insertions(+), 48 deletions(-) + delete mode 100644 gdb/python/lib/gdb/command/bound_registers.py + create mode 100644 gdb/python/lib/gdb/printer/__init__.py + create mode 100644 gdb/python/lib/gdb/printer/bound_registers.py + +### a/gdb/ChangeLog +### b/gdb/ChangeLog +## -1,3 +1,18 @@ ++2014-10-15 Doug Evans ++ Walfred Tedeschi ++ ++ PR python/17364 ++ * python/lib/gdb/__init__.py (packages): Add "printer". ++ * python/lib/gdb/command/bound_registers.py: Moved to ... ++ * python/lib/gdb/printer/bound_registers.py: ... here. ++ Add printer to global set of builtin printers. Rename printer from ++ "bound" to "mpx_bound128". ++ * python/lib/gdb/printing.py (_builtin_pretty_printers): New global, ++ registered as global "builtin" printer. ++ (add_builtin_pretty_printer): New function. ++ * data-directory/Makefile.in (PYTHON_FILE_LIST): Update, and add ++ gdb/printer/__init__.py. ++ + 2014-10-01 Pedro Alves + + * features/aarch64-core.xml (cpsr): Change back to 32-bit. +--- a/gdb/data-directory/Makefile.in ++++ b/gdb/data-directory/Makefile.in +@@ -64,7 +64,6 @@ PYTHON_FILE_LIST = \ + gdb/printing.py \ + gdb/prompt.py \ + gdb/xmethod.py \ +- gdb/command/bound_registers.py \ + gdb/command/__init__.py \ + gdb/command/xmethods.py \ + gdb/command/frame_filters.py \ +@@ -73,7 +72,9 @@ PYTHON_FILE_LIST = \ + gdb/command/prompt.py \ + gdb/command/explore.py \ + gdb/function/__init__.py \ +- gdb/function/strfns.py ++ gdb/function/strfns.py \ ++ gdb/printer/__init__.py \ ++ gdb/printer/bound_registers.py + + @HAVE_PYTHON_TRUE@PYTHON_FILES = $(PYTHON_FILE_LIST) + @HAVE_PYTHON_FALSE@PYTHON_FILES = +--- a/gdb/python/lib/gdb/__init__.py ++++ b/gdb/python/lib/gdb/__init__.py +@@ -81,7 +81,8 @@ PYTHONDIR = os.path.dirname(os.path.dirname(__file__)) + + packages = [ + 'function', +- 'command' ++ 'command', ++ 'printer' + ] + + # pkgutil.iter_modules is not available prior to Python 2.6. Instead, +--- a/gdb/python/lib/gdb/command/bound_registers.py ++++ /dev/null +@@ -1,45 +0,0 @@ +-# Pretty-printer utilities. +-# Copyright (C) 2013-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 . +- +-import gdb.printing +- +-class BoundPrinter: +- """Adds size field to a _rawbound128 type.""" +- +- def __init__ (self, val): +- self.val = val +- +- def to_string (self): +- upper = self.val["ubound"] +- lower = self.val["lbound"] +- size = (long) ((upper) - (lower)) +- if size > -1: +- size = size + 1 +- result = '{lbound = %s, ubound = %s} : size %s' % (lower, upper, size) +- return result +- +-# There are two pattern matching used: first one is related to a library +-# second is related to the type. Since we are displaying a register all +-# libraries are accepted. Type to be processed is the same present +-# in the xml file. +- +-def build_pretty_printer (): +- pp = gdb.printing.RegexpCollectionPrettyPrinter (".*") +- pp.add_printer ('bound', '^__gdb_builtin_type_bound128', BoundPrinter) +- return pp +- +-gdb.printing.register_pretty_printer (gdb.current_objfile (), +- build_pretty_printer ()) +--- /dev/null ++++ b/gdb/python/lib/gdb/printer/__init__.py +@@ -0,0 +1,14 @@ ++# Copyright (C) 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 . +--- /dev/null ++++ b/gdb/python/lib/gdb/printer/bound_registers.py +@@ -0,0 +1,36 @@ ++# Pretty-printers for bounds registers. ++# Copyright (C) 2013-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 . ++ ++import gdb.printing ++ ++class MpxBound128Printer: ++ """Adds size field to a mpx __gdb_builtin_type_bound128 type.""" ++ ++ def __init__ (self, val): ++ self.val = val ++ ++ def to_string (self): ++ upper = self.val["ubound"] ++ lower = self.val["lbound"] ++ size = (long) ((upper) - (lower)) ++ if size > -1: ++ size = size + 1 ++ result = '{lbound = %s, ubound = %s} : size %s' % (lower, upper, size) ++ return result ++ ++gdb.printing.add_builtin_pretty_printer ('mpx_bound128', ++ '^__gdb_builtin_type_bound128', ++ MpxBound128Printer) +--- a/gdb/python/lib/gdb/printing.py ++++ b/gdb/python/lib/gdb/printing.py +@@ -263,3 +263,17 @@ class FlagEnumerationPrinter(PrettyPrinter): + return _EnumInstance(self.enumerators, val) + else: + return None ++ ++ ++# Builtin pretty-printers. ++# The set is defined as empty, and files in printing/*.py add their printers ++# to this with add_builtin_pretty_printer. ++ ++_builtin_pretty_printers = RegexpCollectionPrettyPrinter("builtin") ++ ++register_pretty_printer(None, _builtin_pretty_printers) ++ ++# Add a builtin pretty-printer. ++ ++def add_builtin_pretty_printer(name, regexp, printer): ++ _builtin_pretty_printers.add_printer(name, regexp, printer) +-- +1.9.3 + +From 92e08c0d191908b7315603558226c7ca0bfa86a5 Mon Sep 17 00:00:00 2001 +From: Pedro Alves +Date: Fri, 17 Oct 2014 13:49:28 +0100 +Subject: [PATCH 32/37] Make common code handle target_terminal_* idempotency + +I found a place that should be giving back the terminal to the target, +but only if the target was already owning it. So I need to add a +getter for who owns the terminal. + +The trouble is that several places/target have their own globals to +track this state: + + - inflow.c:terminal_is_ours + - remote.c:remote_async_terminal_ours_p + - linux-nat.c:async_terminal_is_ours + - go32-nat.c:terminal_is_ours + +While one might think of adding a new target_ops method to query this, +conceptually, this state isn't really part of a particular target_ops. +Considering multi-target, the core shouldn't have to ask all targets +to know whether it's GDB that owns the terminal. There's only one GDB +(or rather, only one top level interpreter). + +So what this comment does is add a new global that is tracked by the +core instead. A subsequent pass may later remove the other globals. + +Tested on x86_64 Fedora 20, native and gdbserver. + +gdb/ +2014-10-17 Pedro Alves + + * target.c (enum terminal_state): New enum. + (terminal_state): New global. + (target_terminal_init): New function. + (target_terminal_inferior): Skip if inferior already owns the + terminal. + (target_terminal_ours, target_terminal_ours_for_output): New + functions. + * target.h (target_terminal_init): Convert to function prototype. + (target_terminal_ours_for_output): Convert to function prototype + and tweak comment. + (target_terminal_ours): Convert to function prototype and tweak + comment. + * windows-nat.c (do_initial_windows_stuff): Call + target_terminal_init instead of child_terminal_init_with_pgrp. +--- + gdb/ChangeLog | 17 +++++++++++++++++ + gdb/target.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + gdb/target.h | 20 +++++++------------- + gdb/windows-nat.c | 2 +- + 4 files changed, 81 insertions(+), 14 deletions(-) + +### a/gdb/ChangeLog +### b/gdb/ChangeLog +## -1,3 +1,20 @@ ++2014-10-17 Pedro Alves ++ ++ * target.c (enum terminal_state): New enum. ++ (terminal_state): New global. ++ (target_terminal_init): New function. ++ (target_terminal_inferior): Skip if inferior already owns the ++ terminal. ++ (target_terminal_ours, target_terminal_ours_for_output): New ++ functions. ++ * target.h (target_terminal_init): Convert to function prototype. ++ (target_terminal_ours_for_output): Convert to function prototype ++ and tweak comment. ++ (target_terminal_ours): Convert to function prototype and tweak ++ comment. ++ * windows-nat.c (do_initial_windows_stuff): Call ++ target_terminal_init instead of child_terminal_init_with_pgrp. ++ + 2014-10-15 Doug Evans + Walfred Tedeschi + +--- a/gdb/target.c ++++ b/gdb/target.c +@@ -482,6 +482,35 @@ target_load (char *arg, int from_tty) + (*current_target.to_load) (¤t_target, arg, from_tty); + } + ++/* Possible terminal states. */ ++ ++enum terminal_state ++ { ++ /* The inferior's terminal settings are in effect. */ ++ terminal_is_inferior = 0, ++ ++ /* Some of our terminal settings are in effect, enough to get ++ proper output. */ ++ terminal_is_ours_for_output = 1, ++ ++ /* Our terminal settings are in effect, for output and input. */ ++ terminal_is_ours = 2 ++ }; ++ ++static enum terminal_state terminal_state; ++ ++/* See target.h. */ ++ ++void ++target_terminal_init (void) ++{ ++ (*current_target.to_terminal_init) (¤t_target); ++ ++ terminal_state = terminal_is_ours; ++} ++ ++/* See target.h. */ ++ + void + target_terminal_inferior (void) + { +@@ -492,9 +521,36 @@ target_terminal_inferior (void) + if (target_can_async_p () && !sync_execution) + return; + ++ if (terminal_state == terminal_is_inferior) ++ return; ++ + /* If GDB is resuming the inferior in the foreground, install + inferior's terminal modes. */ + (*current_target.to_terminal_inferior) (¤t_target); ++ terminal_state = terminal_is_inferior; ++} ++ ++/* See target.h. */ ++ ++void ++target_terminal_ours (void) ++{ ++ if (terminal_state == terminal_is_ours) ++ return; ++ ++ (*current_target.to_terminal_ours) (¤t_target); ++ terminal_state = terminal_is_ours; ++} ++ ++/* See target.h. */ ++ ++void ++target_terminal_ours_for_output (void) ++{ ++ if (terminal_state != terminal_is_inferior) ++ return; ++ (*current_target.to_terminal_ours_for_output) (¤t_target); ++ terminal_state = terminal_is_ours_for_output; + } + + static void +--- a/gdb/target.h ++++ b/gdb/target.h +@@ -1359,31 +1359,25 @@ extern int target_remove_breakpoint (struct gdbarch *gdbarch, + /* Initialize the terminal settings we record for the inferior, + before we actually run the inferior. */ + +-#define target_terminal_init() \ +- (*current_target.to_terminal_init) (¤t_target) ++extern void target_terminal_init (void); + + /* Put the inferior's terminal settings into effect. + This is preparation for starting or resuming the inferior. */ + + extern void target_terminal_inferior (void); + +-/* Put some of our terminal settings into effect, +- enough to get proper results from our output, +- but do not change into or out of RAW mode +- so that no input is discarded. ++/* Put some of our terminal settings into effect, enough to get proper ++ results from our output, but do not change into or out of RAW mode ++ so that no input is discarded. This is a no-op if terminal_ours ++ was most recently called. */ + +- After doing this, either terminal_ours or terminal_inferior +- should be called to get back to a normal state of affairs. */ +- +-#define target_terminal_ours_for_output() \ +- (*current_target.to_terminal_ours_for_output) (¤t_target) ++extern void target_terminal_ours_for_output (void); + + /* Put our terminal settings into effect. + First record the inferior's terminal settings + so they can be restored properly later. */ + +-#define target_terminal_ours() \ +- (*current_target.to_terminal_ours) (¤t_target) ++extern void target_terminal_ours (void); + + /* Save our terminal settings. + This is called from TUI after entering or leaving the curses +--- a/gdb/windows-nat.c ++++ b/gdb/windows-nat.c +@@ -1744,7 +1744,7 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) + current thread until we report an event out of windows_wait. */ + inferior_ptid = pid_to_ptid (pid); + +- child_terminal_init_with_pgrp (pid); ++ target_terminal_init (); + target_terminal_inferior (); + + windows_initialization_done = 0; +-- +1.9.3 + +From 04f0515702a6e5711d71203fcc0ea488161ba086 Mon Sep 17 00:00:00 2001 +From: Pedro Alves +Date: Fri, 17 Oct 2014 13:31:25 +0100 +Subject: [PATCH 33/37] PR gdb/17472: With annotations, input while executing + in the foreground crashes readline/GDB +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Jan caught an intermittent GDB crash with the annota1.exp test: + + Starting program: .../gdb/testsuite/gdb.base/annota1 ^M + [...] + FAIL: gdb.base/annota1.exp: run until main breakpoint (timeout) + [...] + readline: readline_callback_read_char() called with no handler!^M + ERROR: Process no longer exists + +All we need to is to continue the inferior in the foreground, and type +a command while the inferior is running. E.g.: + + (gdb) set annotate 2 + + ▒▒pre-prompt + (gdb) + ▒▒prompt + c + + ▒▒post-prompt + Continuing. + + ▒▒starting + + ▒▒frames-invalid + + *inferior is running now* + + p 1 + + readline: readline_callback_read_char() called with no handler! + Aborted (core dumped) + $ + + +When we run a foreground execution command we call +target_terminal_inferior to stop GDB from processing input, and to put +the inferior's terminal settings in effect. Then we tell readline to +hide the prompt with display_gdb_prompt, which clears readline's input +callback too. When the target stops, we call target_terminal_ours, +which re-installs stdin in the event loop, and then we redisplay the +prompt, reinstalling the readline callbacks. + +However, when annotations are in effect, the "frames-invalid" +annotation code calls target_terminal_ours after 'resume' had already +called target_terminal_inferior: + + (top-gdb) bt + #0 0x000000000056b82f in annotate_frames_invalid () at gdb/annotate.c:219 + #1 0x000000000072e6cc in reinit_frame_cache () at gdb/frame.c:1705 + #2 0x0000000000594bb9 in registers_changed_ptid (ptid=...) at gdb/regcache.c:612 + #3 0x000000000064cca1 in target_resume (ptid=..., step=1, signal=GDB_SIGNAL_0) at gdb/target.c:2136 + #4 0x00000000005f57af in resume (step=1, sig=GDB_SIGNAL_0) at gdb/infrun.c:2263 + #5 0x00000000005f6051 in proceed (addr=18446744073709551615, siggnal=GDB_SIGNAL_DEFAULT, step=1) at gdb/infrun.c:2613 + +And then once we hide the prompt and remove readline's input handler +callback, we're in a bad state. We end up with the target running +supposedly in the foreground, but with stdin still installed on the +event loop. Any input then calls into readline, which aborts because +no rl_linefunc callback handler is installed: + + Program received signal SIGABRT, Aborted. + 0x0000003b36a35877 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 + 56 return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig); + + (top-gdb) bt + #0 0x0000003b36a35877 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 + #1 0x0000003b36a36f68 in __GI_abort () at abort.c:89 + During symbol reading, debug info gives source 9 included from file at zero line 0. + During symbol reading, debug info gives command-line macro definition with non-zero line 19: _STDC_PREDEF_H 1. + #2 0x0000000000784a25 in rl_callback_read_char () at src/readline/callback.c:116 + #3 0x0000000000619111 in rl_callback_read_char_wrapper (client_data=0x0) at src/gdb/event-top.c:167 + #4 0x00000000006194e7 in stdin_event_handler (error=0, client_data=0x0) at src/gdb/event-top.c:373 + #5 0x00000000006180da in handle_file_event (data=...) at src/gdb/event-loop.c:763 + #6 0x00000000006175c1 in process_event () at src/gdb/event-loop.c:340 + #7 0x0000000000617688 in gdb_do_one_event () at src/gdb/event-loop.c:404 + #8 0x00000000006176d8 in start_event_loop () at src/gdb/event-loop.c:429 + #9 0x0000000000619143 in cli_command_loop (data=0x0) at src/gdb/event-top.c:182 + #10 0x000000000060f4c8 in current_interp_command_loop () at src/gdb/interps.c:318 + #11 0x0000000000610691 in captured_command_loop (data=0x0) at src/gdb/main.c:323 + #12 0x000000000060c385 in catch_errors (func=0x610676 , func_args=0x0, errstring=0x900241 "", mask=RETURN_MASK_ALL) + at src/gdb/exceptions.c:237 + #13 0x0000000000611b8f in captured_main (data=0x7fffffffd7b0) at src/gdb/main.c:1151 + #14 0x000000000060c385 in catch_errors (func=0x610a8e , func_args=0x7fffffffd7b0, errstring=0x900241 "", mask=RETURN_MASK_ALL) + at src/gdb/exceptions.c:237 + #15 0x0000000000611bb8 in gdb_main (args=0x7fffffffd7b0) at src/gdb/main.c:1159 + #16 0x000000000045ef57 in main (argc=3, argv=0x7fffffffd8b8) at src/gdb/gdb.c:32 + +The fix is to make the annotation code call target_terminal_inferior +again after printing, if the inferior's settings were in effect. + +While at it, when we're doing output only, instead of +target_terminal_ours, we should call target_terminal_ours_for_output. +The latter doesn't actually remove stdin from the event loop, and also +leaves SIGINT forwarded to the target. + +New test included. + +Tested on x86_64 Fedora 20, native and gdbserver. + +gdb/ +2014-10-17 Pedro Alves + + PR gdb/17472 + * annotate.c (annotate_breakpoints_invalid): Use + target_terminal_our_for_output instead of target_terminal_ours. + Give back the terminal to the target. + (annotate_frames_invalid): Likewise. + +gdb/testsuite/ +2014-10-17 Pedro Alves + + PR gdb/17472 + * gdb.base/annota-input-while-running.c: New file. + * gdb.base/annota-input-while-running.exp: New file. +--- + gdb/ChangeLog | 8 ++ + gdb/annotate.c | 22 +++- + gdb/target.c | 8 ++ + gdb/target.h | 5 + + gdb/testsuite/ChangeLog | 6 + + .../gdb.base/annota-input-while-running.c | 25 ++++ + .../gdb.base/annota-input-while-running.exp | 130 +++++++++++++++++++++ + 7 files changed, 202 insertions(+), 2 deletions(-) + create mode 100644 gdb/testsuite/gdb.base/annota-input-while-running.c + create mode 100644 gdb/testsuite/gdb.base/annota-input-while-running.exp + +### a/gdb/ChangeLog +### b/gdb/ChangeLog +## -1,5 +1,13 @@ + 2014-10-17 Pedro Alves + ++ PR gdb/17472 ++ * annotate.c (annotate_breakpoints_invalid): Use ++ target_terminal_our_for_output instead of target_terminal_ours. ++ Give back the terminal to the target. ++ (annotate_frames_invalid): Likewise. ++ ++2014-10-17 Pedro Alves ++ + * target.c (enum terminal_state): New enum. + (terminal_state): New global. + (target_terminal_init): New function. +--- a/gdb/annotate.c ++++ b/gdb/annotate.c +@@ -72,8 +72,17 @@ annotate_breakpoints_invalid (void) + && (!breakpoints_invalid_emitted + || async_background_execution_p ())) + { +- target_terminal_ours (); ++ /* If the inferior owns the terminal (e.g., we're resuming), ++ make sure to leave with the inferior still owning it. */ ++ int was_inferior = target_terminal_is_inferior (); ++ ++ target_terminal_ours_for_output (); ++ + printf_unfiltered (("\n\032\032breakpoints-invalid\n")); ++ ++ if (was_inferior) ++ target_terminal_inferior (); ++ + breakpoints_invalid_emitted = 1; + } + } +@@ -210,8 +219,17 @@ annotate_frames_invalid (void) + && (!frames_invalid_emitted + || async_background_execution_p ())) + { +- target_terminal_ours (); ++ /* If the inferior owns the terminal (e.g., we're resuming), ++ make sure to leave with the inferior still owning it. */ ++ int was_inferior = target_terminal_is_inferior (); ++ ++ target_terminal_ours_for_output (); ++ + printf_unfiltered (("\n\032\032frames-invalid\n")); ++ ++ if (was_inferior) ++ target_terminal_inferior (); ++ + frames_invalid_emitted = 1; + } + } +--- a/gdb/target.c ++++ b/gdb/target.c +@@ -511,6 +511,14 @@ target_terminal_init (void) + + /* See target.h. */ + ++int ++target_terminal_is_inferior (void) ++{ ++ return (terminal_state == terminal_is_inferior); ++} ++ ++/* See target.h. */ ++ + void + target_terminal_inferior (void) + { +--- a/gdb/target.h ++++ b/gdb/target.h +@@ -1356,6 +1356,11 @@ extern int target_insert_breakpoint (struct gdbarch *gdbarch, + extern int target_remove_breakpoint (struct gdbarch *gdbarch, + struct bp_target_info *bp_tgt); + ++/* Returns true if the terminal settings of the inferior are in ++ effect. */ ++ ++extern int target_terminal_is_inferior (void); ++ + /* Initialize the terminal settings we record for the inferior, + before we actually run the inferior. */ + +### a/gdb/testsuite/ChangeLog +### b/gdb/testsuite/ChangeLog +## -1,3 +1,9 @@ ++2014-10-17 Pedro Alves ++ ++ PR gdb/17472 ++ * gdb.base/annota-input-while-running.c: New file. ++ * gdb.base/annota-input-while-running.exp: New file. ++ + 2014-09-11 Pedro Alves + + PR gdb/17347 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/annota-input-while-running.c +@@ -0,0 +1,25 @@ ++/* 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 ++ ++int ++main (void) ++{ ++ sleep (5); ++ return 0; /* set break here */ ++} +--- /dev/null ++++ b/gdb/testsuite/gdb.base/annota-input-while-running.exp +@@ -0,0 +1,130 @@ ++# Copyright 1999-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 . ++ ++# Test that annotations support doesn't leave GDB's terminal settings ++# into effect when we run a foreground command. ++ ++if [is_remote target] then { ++ # We cannot use runto_main because of the different prompt we get ++ # when using annotation level 2. ++ return 0 ++} ++ ++standard_testfile ++ ++if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug] == -1} { ++ return -1 ++} ++ ++# Break at main ++ ++gdb_test "break main" \ ++ "Breakpoint.*at.* file .*$srcfile.*\\." \ ++ "breakpoint main" ++ ++# NOTE: this prompt is OK only when the annotation level is > 1 ++# NOTE: When this prompt is in use the gdb_test procedure cannot be ++# used because it assumes that the last char after the gdb_prompt is a ++# white space. This is not true with this annotated prompt. So we ++# must use the gdb_annota_test replacement below, or ++# gdb_test_multiple. ++ ++set old_gdb_prompt $gdb_prompt ++set gdb_prompt "\r\n\032\032pre-prompt\r\n$gdb_prompt \r\n\032\032prompt\r\n" ++ ++# Like gdb_test, but cope with the annotation prompt. ++proc gdb_annota_test {command pattern message} { ++ global gdb_prompt ++ ++ gdb_test_multiple $command $message { ++ -re "$pattern$gdb_prompt$" { ++ pass "$message" ++ } ++ -re "$gdb_prompt$" { ++ fail "$message" ++ } ++ } ++} ++ ++# Set the annotation level to 2. ++ ++set test "annotation set at level 2" ++gdb_annota_test "set annotate 2" ".*" "annotation set at level 2" ++ ++# Run to main. ++ ++gdb_annota_test "run" \ ++ "\r\n\032\032post-prompt.*\r\n\r\n\032\032stopped.*" \ ++ "run until main breakpoint" ++ ++set test "delete breakpoints" ++gdb_test_multiple "delete" $test { ++ -re "Delete all breakpoints. .y or n." { ++ send_gdb "y\n" ++ exp_continue ++ } ++ -re "$gdb_prompt$" { ++ pass $test ++ } ++} ++ ++# Set the target running, and then type something. GDB used to have a ++# bug where it'd be accepting input even though the target was ++# supposedly resumed in the foreground. This ultimately resulted in ++# readline aborting. ++ ++set linenum [gdb_get_line_number "set break here"] ++ ++gdb_annota_test "break $linenum" \ ++ "Breakpoint .*$srcfile, line .*" \ ++ "break after sleep" ++ ++# Continue, and wait a bit to make sure the inferior really starts ++# running. Wait less than much the program sleeps, which is 5 ++# seconds, though. ++set saw_continuing 0 ++set test "continue" ++gdb_test_multiple $test $test { ++ -timeout 2 ++ -re "Continuing\\." { ++ set saw_continuing 1 ++ exp_continue ++ } ++ timeout { ++ gdb_assert $saw_continuing $test ++ } ++} ++ ++# Type something. ++send_gdb "print 1\n" ++ ++# Poor buggy GDB would crash before the breakpoint was hit. ++set test "breakpoint hit" ++gdb_test_multiple "" $test { ++ -re "stopped\r\n$gdb_prompt" { ++ pass $test ++ } ++} ++ ++set test "print command result" ++gdb_test_multiple "" $test { ++ -re "\r\n1\r\n\r\n\032\032value-history-end\r\n$gdb_prompt" { ++ pass $test ++ } ++} ++ ++# Restore the original prompt for the rest of the testsuite. ++ ++set gdb_prompt $old_gdb_prompt +-- +1.9.3 + +From e37951dc10da6940ef354f062fc43ee03687c571 Mon Sep 17 00:00:00 2001 +From: Pedro Alves +Date: Fri, 17 Oct 2014 13:31:25 +0100 +Subject: [PATCH 34/37] PR gdb/17300: Input after "c -a" crashes readline/GDB + +If all threads in the target were already running when the user does +"c -a", nothing puts the inferior's terminal settings in effect and +removes stdin from the event loop, which we must when running a +foreground command. The result is that user input afterwards crashes +readline/gdb: + + (gdb) start + Temporary breakpoint 1 at 0x4005d4: file continue-all-already-running.c, line 23. + Starting program: continue-all-already-running + + Temporary breakpoint 1, main () at continue-all-already-running.c:23 + 23 sleep (10); + (gdb) c -a& + Continuing. + (gdb) c -a + Continuing. + p 1 + readline: readline_callback_read_char() called with no handler! + Aborted (core dumped) + $ + +Backtrace: + + Program received signal SIGABRT, Aborted. + 0x0000003b36a35877 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 + 56 return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig); + (top-gdb) p 1 + $1 = 1 + (top-gdb) bt + #0 0x0000003b36a35877 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 + #1 0x0000003b36a36f68 in __GI_abort () at abort.c:89 + #2 0x0000000000784aa9 in rl_callback_read_char () at readline/callback.c:116 + #3 0x0000000000619181 in rl_callback_read_char_wrapper (client_data=0x0) at gdb/event-top.c:167 + #4 0x0000000000619557 in stdin_event_handler (error=0, client_data=0x0) at gdb/event-top.c:373 + #5 0x000000000061814a in handle_file_event (data=...) at gdb/event-loop.c:763 + #6 0x0000000000617631 in process_event () at gdb/event-loop.c:340 + #7 0x00000000006176f8 in gdb_do_one_event () at gdb/event-loop.c:404 + #8 0x0000000000617748 in start_event_loop () at gdb/event-loop.c:429 + #9 0x00000000006191b3 in cli_command_loop (data=0x0) at gdb/event-top.c:182 + #10 0x000000000060f538 in current_interp_command_loop () at gdb/interps.c:318 + #11 0x0000000000610701 in captured_command_loop (data=0x0) at gdb/main.c:323 + #12 0x000000000060c3f5 in catch_errors (func=0x6106e6 , func_args=0x0, errstring=0x9002c1 "", mask=RETURN_MASK_ALL) + at gdb/exceptions.c:237 + #13 0x0000000000611bff in captured_main (data=0x7fffffffd780) at gdb/main.c:1151 + #14 0x000000000060c3f5 in catch_errors (func=0x610afe , func_args=0x7fffffffd780, errstring=0x9002c1 "", mask=RETURN_MASK_ALL) + at gdb/exceptions.c:237 + #15 0x0000000000611c28 in gdb_main (args=0x7fffffffd780) at gdb/main.c:1159 + #16 0x000000000045ef97 in main (argc=5, argv=0x7fffffffd888) at gdb/gdb.c:32 + (top-gdb) + +Tested on x86_64 Fedora 20, native and gdbserver. + +gdb/ +2014-10-17 Pedro Alves + + PR gdb/17300 + * infcmd.c (continue_1): If continuing all threads in the + foreground, make sure the inferior's terminal settings are put in + effect. + +gdb/testsuite/ +2014-10-17 Pedro Alves + + PR gdb/17300 + * gdb.base/continue-all-already-running.c: New file. + * gdb.base/continue-all-already-running.exp: New file. +--- + gdb/ChangeLog | 7 ++ + gdb/infcmd.c | 18 +++++ + gdb/testsuite/ChangeLog | 6 ++ + .../gdb.base/continue-all-already-running.c | 25 +++++++ + .../gdb.base/continue-all-already-running.exp | 79 ++++++++++++++++++++++ + 5 files changed, 135 insertions(+) + create mode 100644 gdb/testsuite/gdb.base/continue-all-already-running.c + create mode 100644 gdb/testsuite/gdb.base/continue-all-already-running.exp + +### a/gdb/ChangeLog +### b/gdb/ChangeLog +## -1,5 +1,12 @@ + 2014-10-17 Pedro Alves + ++ PR gdb/17300 ++ * infcmd.c (continue_1): If continuing all threads in the ++ foreground, make sure the inferior's terminal settings are put in ++ effect. ++ ++2014-10-17 Pedro Alves ++ + PR gdb/17472 + * annotate.c (annotate_breakpoints_invalid): Use + target_terminal_our_for_output instead of target_terminal_ours. +--- a/gdb/infcmd.c ++++ b/gdb/infcmd.c +@@ -738,6 +738,24 @@ continue_1 (int all_threads) + + iterate_over_threads (proceed_thread_callback, NULL); + ++ if (sync_execution) ++ { ++ /* If all threads in the target were already running, ++ proceed_thread_callback ends up never calling proceed, ++ and so nothing calls this to put the inferior's terminal ++ settings in effect and remove stdin from the event loop, ++ which we must when running a foreground command. E.g.: ++ ++ (gdb) c -a& ++ Continuing. ++ ++ (gdb) c -a ++ Continuing. ++ ++ */ ++ target_terminal_inferior (); ++ } ++ + /* Restore selected ptid. */ + do_cleanups (old_chain); + } +### a/gdb/testsuite/ChangeLog +### b/gdb/testsuite/ChangeLog +## -1,5 +1,11 @@ + 2014-10-17 Pedro Alves + ++ PR gdb/17300 ++ * gdb.base/continue-all-already-running.c: New file. ++ * gdb.base/continue-all-already-running.exp: New file. ++ ++2014-10-17 Pedro Alves ++ + PR gdb/17472 + * gdb.base/annota-input-while-running.c: New file. + * gdb.base/annota-input-while-running.exp: New file. +--- /dev/null ++++ b/gdb/testsuite/gdb.base/continue-all-already-running.c +@@ -0,0 +1,25 @@ ++/* 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 ++ ++int ++main (void) ++{ ++ sleep (10); ++ return 0; /* set break here */ ++} +--- /dev/null ++++ b/gdb/testsuite/gdb.base/continue-all-already-running.exp +@@ -0,0 +1,79 @@ ++# Copyright (C) 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 . ++ ++# Test that "c -a" doesn't leave GDB processing input, even if all ++# threads were already running. PR gdb/17300. ++ ++standard_testfile ++ ++if { [prepare_for_testing ${testfile}.exp ${testfile} $srcfile] } { ++ return -1 ++} ++ ++gdb_test_no_output "set non-stop on" ++ ++if ![runto_main] { ++ return ++} ++ ++set linenum [gdb_get_line_number "set break here"] ++gdb_breakpoint "$linenum" ++ ++gdb_test "c -a&" "Continuing\\." ++ ++set test "no stop" ++gdb_test_multiple "" $test { ++ -timeout 1 ++ timeout { ++ pass $test ++ } ++} ++ ++# Paranoia. Check that input works after bg command. ++gdb_test "print 1" " = 1" ++ ++# Continue in the foreground, and wait one second to make sure the ++# inferior really starts running. If we get a prompt to soon (e.g., ++# the program stops), this issues a fail. ++set saw_continuing 0 ++set test "c -a" ++gdb_test_multiple "c -a" $test { ++ -timeout 1 ++ -re "Continuing\\." { ++ set saw_continuing 1 ++ exp_continue ++ } ++ timeout { ++ gdb_assert $saw_continuing $test ++ } ++} ++ ++# Type something while the inferior is running in the foreground. ++send_gdb "print 2\n" ++ ++# Poor buggy GDB would crash before the breakpoint was hit. ++set test "breakpoint hit" ++gdb_test_multiple "" $test { ++ -re "set break here ..\r\n$gdb_prompt " { ++ pass $test ++ } ++} ++ ++set test "print command result" ++gdb_test_multiple "" $test { ++ -re " = 2\r\n$gdb_prompt $" { ++ pass $test ++ } ++} +-- +1.9.3 + +From 36c57a3ceeb2260913f7d2d349e994dd844cbcae Mon Sep 17 00:00:00 2001 +From: Pedro Alves +Date: Fri, 17 Oct 2014 13:31:26 +0100 +Subject: [PATCH 35/37] PR gdb/17471: Repeating a background command makes it + foreground + +When we repeat a command, by just pressing , the input from the +previous command is reused for the new command invocation. + +When an execution command strips the "&" out of its incoming argument +string, to detect background execution, we poke a '\0' directly to the +incoming argument string. + +Combine both, and a repeat of a background command loses the "&". + +This is actually only visible if args other than "&" are specified +(e.g., "c 1&" or "next 2&" or "c -a&"), as in the special case of "&" +alone (e.g. "c&") doesn't actually clobber the incoming string. + +Fix this by making strip_bg_char return a new string instead of poking +a hole in the input string. + +New test included. + +Tested on x86_64 Fedora 20, native and gdbserver. + +gdb/ +2014-10-17 Pedro Alves + + PR gdb/17471 + * infcmd.c (strip_bg_char): Change prototype and rewrite. Now + returns a copy of the input. + (run_command_1, continue_command, step_1, jump_command) + (signal_command, until_command, advance_command, finish_command) + (attach_command): Adjust and install a cleanup to free the + stripped args. + +gdb/testsuite/ +2014-10-17 Pedro Alves + + PR gdb/17471 + * gdb.base/bg-execution-repeat.c: New file. + * gdb.base/bg-execution-repeat.exp: New file. +--- + gdb/ChangeLog | 10 ++ + gdb/infcmd.c | 142 ++++++++++++++++--------- + gdb/testsuite/ChangeLog | 6 ++ + gdb/testsuite/gdb.base/bg-execution-repeat.c | 33 ++++++ + gdb/testsuite/gdb.base/bg-execution-repeat.exp | 86 +++++++++++++++ + 5 files changed, 224 insertions(+), 53 deletions(-) + create mode 100644 gdb/testsuite/gdb.base/bg-execution-repeat.c + create mode 100644 gdb/testsuite/gdb.base/bg-execution-repeat.exp + +### a/gdb/ChangeLog +### b/gdb/ChangeLog +## -1,5 +1,15 @@ + 2014-10-17 Pedro Alves + ++ PR gdb/17471 ++ * infcmd.c (strip_bg_char): Change prototype and rewrite. Now ++ returns a copy of the input. ++ (run_command_1, continue_command, step_1, jump_command) ++ (signal_command, until_command, advance_command, finish_command) ++ (attach_command): Adjust and install a cleanup to free the ++ stripped args. ++ ++2014-10-17 Pedro Alves ++ + PR gdb/17300 + * infcmd.c (continue_1): If continuing all threads in the + foreground, make sure the inferior's terminal settings are put in +--- a/gdb/infcmd.c ++++ b/gdb/infcmd.c +@@ -107,8 +107,6 @@ static void run_no_args_command (char *args, int from_tty); + + static void go_command (char *line_no, int from_tty); + +-static int strip_bg_char (char **); +- + void _initialize_infcmd (void); + + #define ERROR_NO_INFERIOR \ +@@ -373,35 +371,40 @@ construct_inferior_arguments (int argc, char **argv) + } + + +-/* This function detects whether or not a '&' character (indicating +- background execution) has been added as *the last* of the arguments ARGS +- of a command. If it has, it removes it and returns 1. Otherwise it +- does nothing and returns 0. */ ++/* This function strips the '&' character (indicating background ++ execution) that is added as *the last* of the arguments ARGS of a ++ command. A copy of the incoming ARGS without the '&' is returned, ++ unless the resulting string after stripping is empty, in which case ++ NULL is returned. *BG_CHAR_P is an output boolean that indicates ++ whether the '&' character was found. */ + +-static int +-strip_bg_char (char **args) ++static char * ++strip_bg_char (const char *args, int *bg_char_p) + { +- char *p = NULL; ++ const char *p; + +- p = strchr (*args, '&'); ++ if (args == NULL || *args == '\0') ++ { ++ *bg_char_p = 0; ++ return NULL; ++ } + +- if (p) ++ p = args + strlen (args); ++ if (p[-1] == '&') + { +- if (p == (*args + strlen (*args) - 1)) +- { +- if (strlen (*args) > 1) +- { +- do +- p--; +- while (*p == ' ' || *p == '\t'); +- *(p + 1) = '\0'; +- } +- else +- *args = 0; +- return 1; +- } ++ p--; ++ while (p > args && isspace (p[-1])) ++ p--; ++ ++ *bg_char_p = 1; ++ if (p != args) ++ return savestring (args, p - args); ++ else ++ return NULL; + } +- return 0; ++ ++ *bg_char_p = 0; ++ return xstrdup (args); + } + + /* Common actions to take after creating any sort of inferior, by any +@@ -530,7 +533,8 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) + ptid_t ptid; + struct ui_out *uiout = current_uiout; + struct target_ops *run_target; +- int async_exec = 0; ++ int async_exec; ++ struct cleanup *args_chain; + + dont_repeat (); + +@@ -553,8 +557,8 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) + reopen_exec_file (); + reread_symbols (); + +- if (args != NULL) +- async_exec = strip_bg_char (&args); ++ args = strip_bg_char (args, &async_exec); ++ args_chain = make_cleanup (xfree, args); + + /* Do validation and preparation before possibly changing anything + in the inferior. */ +@@ -600,6 +604,9 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) + ui_out_flush (uiout); + } + ++ /* Done with ARGS. */ ++ do_cleanups (args_chain); ++ + /* We call get_inferior_args() because we might need to compute + the value now. */ + run_target->to_create_inferior (run_target, exec_file, get_inferior_args (), +@@ -773,13 +780,15 @@ continue_1 (int all_threads) + static void + continue_command (char *args, int from_tty) + { +- int async_exec = 0; ++ int async_exec; + int all_threads = 0; ++ struct cleanup *args_chain; ++ + ERROR_NO_INFERIOR; + + /* Find out whether we must run in the background. */ +- if (args != NULL) +- async_exec = strip_bg_char (&args); ++ args = strip_bg_char (args, &async_exec); ++ args_chain = make_cleanup (xfree, args); + + prepare_execution_command (¤t_target, async_exec); + +@@ -843,6 +852,9 @@ continue_command (char *args, int from_tty) + } + } + ++ /* Done with ARGS. */ ++ do_cleanups (args_chain); ++ + if (from_tty) + printf_filtered (_("Continuing.\n")); + +@@ -902,21 +914,25 @@ step_1 (int skip_subroutines, int single_inst, char *count_string) + { + int count = 1; + struct cleanup *cleanups = make_cleanup (null_cleanup, NULL); +- int async_exec = 0; ++ int async_exec; + int thread = -1; ++ struct cleanup *args_chain; + + ERROR_NO_INFERIOR; + ensure_not_tfind_mode (); + ensure_valid_thread (); + ensure_not_running (); + +- if (count_string) +- async_exec = strip_bg_char (&count_string); ++ count_string = strip_bg_char (count_string, &async_exec); ++ args_chain = make_cleanup (xfree, count_string); + + prepare_execution_command (¤t_target, async_exec); + + count = count_string ? parse_and_eval_long (count_string) : 1; + ++ /* Done with ARGS. */ ++ do_cleanups (args_chain); ++ + if (!single_inst || skip_subroutines) /* Leave si command alone. */ + { + struct thread_info *tp = inferior_thread (); +@@ -1137,7 +1153,8 @@ jump_command (char *arg, int from_tty) + struct symtab_and_line sal; + struct symbol *fn; + struct symbol *sfn; +- int async_exec = 0; ++ int async_exec; ++ struct cleanup *args_chain; + + ERROR_NO_INFERIOR; + ensure_not_tfind_mode (); +@@ -1145,8 +1162,8 @@ jump_command (char *arg, int from_tty) + ensure_not_running (); + + /* Find out whether we must run in the background. */ +- if (arg != NULL) +- async_exec = strip_bg_char (&arg); ++ arg = strip_bg_char (arg, &async_exec); ++ args_chain = make_cleanup (xfree, arg); + + prepare_execution_command (¤t_target, async_exec); + +@@ -1162,6 +1179,9 @@ jump_command (char *arg, int from_tty) + sal = sals.sals[0]; + xfree (sals.sals); + ++ /* Done with ARGS. */ ++ do_cleanups (args_chain); ++ + if (sal.symtab == 0 && sal.pc == 0) + error (_("No source file has been specified.")); + +@@ -1230,7 +1250,8 @@ static void + signal_command (char *signum_exp, int from_tty) + { + enum gdb_signal oursig; +- int async_exec = 0; ++ int async_exec; ++ struct cleanup *args_chain; + + dont_repeat (); /* Too dangerous. */ + ERROR_NO_INFERIOR; +@@ -1239,8 +1260,8 @@ signal_command (char *signum_exp, int from_tty) + ensure_not_running (); + + /* Find out whether we must run in the background. */ +- if (signum_exp != NULL) +- async_exec = strip_bg_char (&signum_exp); ++ signum_exp = strip_bg_char (signum_exp, &async_exec); ++ args_chain = make_cleanup (xfree, signum_exp); + + prepare_execution_command (¤t_target, async_exec); + +@@ -1372,7 +1393,8 @@ until_next_command (int from_tty) + static void + until_command (char *arg, int from_tty) + { +- int async_exec = 0; ++ int async_exec; ++ struct cleanup *args_chain; + + ERROR_NO_INFERIOR; + ensure_not_tfind_mode (); +@@ -1380,8 +1402,8 @@ until_command (char *arg, int from_tty) + ensure_not_running (); + + /* Find out whether we must run in the background. */ +- if (arg != NULL) +- async_exec = strip_bg_char (&arg); ++ arg = strip_bg_char (arg, &async_exec); ++ args_chain = make_cleanup (xfree, arg); + + prepare_execution_command (¤t_target, async_exec); + +@@ -1389,12 +1411,16 @@ until_command (char *arg, int from_tty) + until_break_command (arg, from_tty, 0); + else + until_next_command (from_tty); ++ ++ /* Done with ARGS. */ ++ do_cleanups (args_chain); + } + + static void + advance_command (char *arg, int from_tty) + { +- int async_exec = 0; ++ int async_exec; ++ struct cleanup *args_chain; + + ERROR_NO_INFERIOR; + ensure_not_tfind_mode (); +@@ -1405,12 +1431,15 @@ advance_command (char *arg, int from_tty) + error_no_arg (_("a location")); + + /* Find out whether we must run in the background. */ +- if (arg != NULL) +- async_exec = strip_bg_char (&arg); ++ arg = strip_bg_char (arg, &async_exec); ++ args_chain = make_cleanup (xfree, arg); + + prepare_execution_command (¤t_target, async_exec); + + until_break_command (arg, from_tty, 1); ++ ++ /* Done with ARGS. */ ++ do_cleanups (args_chain); + } + + /* Return the value of the result of a function at the end of a 'finish' +@@ -1686,8 +1715,8 @@ finish_command (char *arg, int from_tty) + { + struct frame_info *frame; + struct symbol *function; +- +- int async_exec = 0; ++ int async_exec; ++ struct cleanup *args_chain; + + ERROR_NO_INFERIOR; + ensure_not_tfind_mode (); +@@ -1695,14 +1724,17 @@ finish_command (char *arg, int from_tty) + ensure_not_running (); + + /* Find out whether we must run in the background. */ +- if (arg != NULL) +- async_exec = strip_bg_char (&arg); ++ arg = strip_bg_char (arg, &async_exec); ++ args_chain = make_cleanup (xfree, arg); + + prepare_execution_command (¤t_target, async_exec); + + if (arg) + error (_("The \"finish\" command does not take any arguments.")); + ++ /* Done with ARGS. */ ++ do_cleanups (args_chain); ++ + frame = get_prev_frame (get_selected_frame (_("No selected frame."))); + if (frame == 0) + error (_("\"finish\" not meaningful in the outermost frame.")); +@@ -2476,7 +2508,8 @@ attach_command_continuation_free_args (void *args) + void + attach_command (char *args, int from_tty) + { +- int async_exec = 0; ++ int async_exec; ++ struct cleanup *args_chain; + struct target_ops *attach_target; + + dont_repeat (); /* Not for the faint of heart */ +@@ -2497,8 +2530,8 @@ attach_command (char *args, int from_tty) + this function should probably be moved into target_pre_inferior. */ + target_pre_inferior (from_tty); + +- if (args != NULL) +- async_exec = strip_bg_char (&args); ++ args = strip_bg_char (args, &async_exec); ++ args_chain = make_cleanup (xfree, args); + + attach_target = find_attach_target (); + +@@ -2512,6 +2545,9 @@ attach_command (char *args, int from_tty) + shouldn't refer to attach_target again. */ + attach_target = NULL; + ++ /* Done with ARGS. */ ++ do_cleanups (args_chain); ++ + /* Set up the "saved terminal modes" of the inferior + based on what modes we are starting it with. */ + target_terminal_init (); +### a/gdb/testsuite/ChangeLog +### b/gdb/testsuite/ChangeLog +## -1,5 +1,11 @@ + 2014-10-17 Pedro Alves + ++ PR gdb/17471 ++ * gdb.base/bg-execution-repeat.c: New file. ++ * gdb.base/bg-execution-repeat.exp: New file. ++ ++2014-10-17 Pedro Alves ++ + PR gdb/17300 + * gdb.base/continue-all-already-running.c: New file. + * gdb.base/continue-all-already-running.exp: New file. +--- /dev/null ++++ b/gdb/testsuite/gdb.base/bg-execution-repeat.c +@@ -0,0 +1,33 @@ ++/* 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 ++ ++int ++foo (void) ++{ ++ return 0; /* set break here */ ++} ++ ++int ++main (void) ++{ ++ foo (); ++ sleep (5); ++ foo (); ++ return 0; ++} +--- /dev/null ++++ b/gdb/testsuite/gdb.base/bg-execution-repeat.exp +@@ -0,0 +1,86 @@ ++# Copyright (C) 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 . ++ ++# Test that repeating a background command doesn't lose the "&" in the ++# repeat, turning a background command into a foreground command. See ++# PR gdb/17471. ++ ++standard_testfile ++ ++if { [build_executable "failed to prepare" ${testfile} $srcfile] } { ++ return -1 ++} ++ ++set linenum [gdb_get_line_number "set break here"] ++ ++# Run the test proper. CONTINUE_CMD is the background continue ++# command to issue. ++ ++proc test {continue_cmd} { ++ global gdb_prompt ++ global binfile ++ global linenum ++ ++ clean_restart $binfile ++ ++ if ![runto_main] { ++ return ++ } ++ ++ gdb_breakpoint "$linenum" ++ ++ set test $continue_cmd ++ gdb_test_multiple $test $test { ++ -re "Continuing\\.\r\n$gdb_prompt " { ++ # Note no end anchor. If the breakpoint triggers soon enough ++ # enough we see further output after the prompt. ++ pass $test ++ } ++ } ++ ++ # Wait for the stop. Don't expect a prompt, as we had resumed the ++ # inferior in the background. ++ set test "breakpoint hit 1" ++ gdb_test_multiple "" $test { ++ -re "set break here" { ++ pass $test ++ } ++ } ++ ++ # Trigger a repeat. Buggy GDB used to lose the "&", making this a ++ # foreground command... ++ send_gdb "\n" ++ gdb_test "" "Continuing\\." "repeat bg command" ++ ++ # ... and thus further input wouldn't be processed until the target ++ # stopped. ++ gdb_test "print 1" " = 1" "input still accepted" ++ ++ # Make sure we see a stop after the print, and not before. Don't ++ # expect a prompt, as we had resumed the inferior in the background. ++ set test "breakpoint hit 2" ++ gdb_test_multiple "" $test { ++ -re "set break here ..\r\n" { ++ pass $test ++ } ++ } ++} ++ ++# Test with and without extra arguments. ++foreach cmd {"c&" "c 1&"} { ++ with_test_prefix $cmd { ++ test $cmd ++ } ++} +-- +1.9.3 + diff --git a/gdb.spec b/gdb.spec index 420d167..787e83e 100644 --- a/gdb.spec +++ b/gdb.spec @@ -26,7 +26,7 @@ Version: 7.8 # The release always contains a leading reserved number, start it at 1. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. -Release: 25%{?dist} +Release: 26%{?dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain and GFDL Group: Development/Debuggers @@ -722,8 +722,8 @@ find -name "*.info*"|xargs rm -f # Match the Fedora's version info. %patch2 -p1 -%patch349 -p1 %patch232 -p1 +%patch349 -p1 %patch888 -p1 %patch912 -p1 %patch889 -p1 @@ -1339,6 +1339,9 @@ then fi %changelog +* Sun Oct 19 2014 Jan Kratochvil - 7.8-26.fc21 +- Import 5 upstream gdb-7.8 branch fixes (async fix by Pedro Alves). + * Fri Oct 03 2014 Sergio Durigan Junior - 7.8-25.fc21 - Fix 'Slow gstack performance' (RH BZ 1103894, Jan Kratochvil).