Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Jan Kratochvil <jan.kratochvil@redhat.com>
To: gdb-patches@sourceware.org
Subject: [patch 3/4] hw watchpoints kernel workaround
Date: Mon, 06 Dec 2010 11:14:00 -0000	[thread overview]
Message-ID: <20101206111405.GD27176@host0.dyn.jankratochvil.net> (raw)

Hi,

there has been a change in upstream Linux kernels behavior.  Formerly newly
created processes/threads inherited the debug registers content.  Very
recently the new processes/threads get the debug registers cleared.

ptrace: watchpoint-fork (DR fork() inheritance)
https://bugzilla.redhat.com/show_bug.cgi?id=660003
http://sources.redhat.com/cgi-bin/cvsweb.cgi/tests/ptrace-tests/tests/Attic/watchpoint-fork.c?rev=1.3&cvsroot=systemtap
if $? == 0 then it is old-style kernel - debug registers get inherited
if $? == 1 then it is new-style kernel - debug registers get zeroed

In fact so far I do not know it would cause any problem.  It rather
workarounds a GDB bug described in [patch 2/4] (b).  For threads GDB is
already ensuring the right debug registers content:
	linux_nat_set_new_thread (t, amd64_linux_new_thread);

But together with the second change in upstream Linux kernels behavior:

ptrace: watchpoint-zeroaddr: EINVAL on PTRACE_POKEUSER of DR7
https://bugzilla.redhat.com/show_bug.cgi?id=660204
http://sources.redhat.com/cgi-bin/cvsweb.cgi/tests/ptrace-tests/tests/watchpoint-zeroaddr.c?rev=1.1&cvsroot=systemtap
if $? == 0 then it is old-style kernel - anything is allowed
if $? == 1 then it is new-style kernel - EINVAL given on invalid DRs state

there is a problem GDB tries to remove watchpoints from registers where are
already zeroes (due to the first kernel change/bug).  And despite GDB "safely"
tries to unset control register first and only then reset the address
registers still for 2+ watchpoints it causes the kernel EINVAL.

I tried to make GDB working with any combination of these two behavior changes
present as such kernels are already released in the wild.

Therefore here is the workaround.  It is needed only on the new-style kernels.
(scope: RHEL-6 is old-style, updated Fedora 13 is already new-style)

BTW these are upstream Linux kernel behavior changes unrelated to utrace.
I do not know exact kernel version/commit of the change(s).


Thanks,
Jan


gdb/
2010-12-06  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Workaround Linux kernel Bug - Red Hat Bugzilla #660204.
	* i386-nat.c (i386_remove_aligned_watchpoint): New variables
	inferior_pid and inf.
	<inf->pid != inferior_pid>: New.

--- a/gdb/i386-nat.c
+++ b/gdb/i386-nat.c
@@ -453,6 +453,24 @@ i386_remove_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits)
 {
   struct dr_mirror *dr_mirror = dr_mirror_get ();
   int i, retval = -1;
+  int inferior_pid = ptid_get_pid (inferior_ptid);
+  struct inferior *inf = current_inferior ();
+
+  /* Are we detaching breakpoints from a fork-ed child?
+     See linux_nat_iterate_watchpoint_lwps.  */
+  if (inf->pid != inferior_pid)
+    {
+      int i;
+
+      /* Workaround some kernel versions reporting EINVAL on setting
+	 DR_CONTROL with still unset (and thus zero) DR_*ADDR registers.
+	 See: https://bugzilla.redhat.com/show_bug.cgi?id=660204
+	 It can happen as some kernel versions reset all DR registers to zero
+	 for the fork-ed child; other kernels copy them from the parent.  */
+
+      ALL_DEBUG_REGISTERS(i)
+	i386_dr_low.set_addr (i, dr_mirror->addr[i]);
+    }
 
   ALL_DEBUG_REGISTERS(i)
     {


             reply	other threads:[~2010-12-06 11:14 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-06 11:14 Jan Kratochvil [this message]
2010-12-06 13:46 ` Mark Kettenis
2010-12-11  5:16   ` [patch 4/4] " Jan Kratochvil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20101206111405.GD27176@host0.dyn.jankratochvil.net \
    --to=jan.kratochvil@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox