public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Yao Qi <qiyaoltc@gmail.com>
To: Antoine Tremblay <antoine.tremblay@ericsson.com>
Cc: Pedro Alves <palves@redhat.com>,
	 "gdb-patches\@sourceware.org" <gdb-patches@sourceware.org>
Subject: Re: [PATCH 1/2] This patch fixes GDBServer's run control for single stepping
Date: Thu, 30 Mar 2017 16:06:00 -0000	[thread overview]
Message-ID: <86d1cy4umo.fsf@gmail.com> (raw)
In-Reply-To: <wwokzig4l0i1.fsf@ericsson.com> (Antoine Tremblay's message of	"Wed, 29 Mar 2017 08:40:22 -0400")

Antoine Tremblay <antoine.tremblay@ericsson.com> writes:

>> In software single step, we calculate the next pcs, and select
>> breakpoint kinds of them, according to current pc.  If current
>> pc is not within IT block (!InITBlock ()) or the last instruction
>> in IT block (LastInITBlock ()), we can safely use 16-bit thumb
>> breakpoint for any thumb instruction.  That is, in
>> gdbserver/linux-aarch32-low.c:arm_breakpoint_kind_from_current_state,
>> we can return ARM_BP_KIND_THUMB if (!InITBlock () || LastInITBlock ()).
>
> This is not entirely true since we have to check if the next pcs are in
> an IT block rather then only the current one, so there's multiple
> scenarios.

In fact, we need to know whether the next pcs will be conditionally
executed or not, right?  If they won't be conditionally executed, we can
use 16-bit thumb breakpoint instruction.  By checking CPSR, if
current PC is not in IT block or on the last instruction in IT block,
the next pcs can't be conditionally executed.  I've already had a patch
below to implement what I described.

The problem of this patch is that we end up inserting different
kinds of breakpoints on the same instruction.  For a given 32-bit thumb
instruction, GDB and GDBserver knows 32-bit thumb breakpoint instruction
is used for GDB breakpoint, but only GDBserver knows 16-bit thumb
breakpoint is used for GDBserver single-step breakpoint, so GDB will be
confused on this.  I stopped here, and start to do something else.

>
> Consider if current PC is the IT instruction for example, then there's
> at least 2 next pcs inside the IT block where we will need to install an THUMB2
> breakpoint and get_next_pcs will return that.

-- 
Yao (齐尧)

From fad6162c9365535a09ca1072f15469e6007c0fd2 Mon Sep 17 00:00:00 2001
From: Yao Qi <yao.qi@linaro.org>
Date: Fri, 24 Feb 2017 09:25:43 +0000
Subject: [PATCH] Only use 32-bit thumb-2 breakpoint instruction on necessary

It takes two PTRACE_POKETEXT calls to write 32-bit thumb-2 breakpoint to
a 2-byte aligned address, and other threads can observe the partially
modified instruction in the memory between these two calls.  This causes
problems on single stepping multi-thread program in GDBserver.

32-bit thumb-2 breakpoint was invented for single step 32-bit thumb-2
instruction in IT block,
http://lists.infradead.org/pipermail/linux-arm-kernel/2010-January/007488.html
but we can use 16-bit thumb breakpoint instruction anywhere else.
That is what this patch does.  Change in set_breakpoint_type_at is similar
to breakpoint.c:breakpoint_kind.

This patch fixes fails in gdb.threads/schedlock.exp.

Even with patch, 32-bit thumb-2 breakpoint is still used for 32-bit thumb-2
instructions in IT block, so the problem is still there.  This patch is a
partial fix to PR 21169.

gdb/gdbserver:

2017-02-24  Yao Qi  <yao.qi@linaro.org>

	PR server/21169
	* linux-aarch32-low.c (arm_breakpoint_kind_from_current_state):
	Set kind to ARM_BP_KIND_THUMB if program is out of IT block or
	on the last instruction of IT block.
	* mem-break.c (set_breakpoint_type_at): Call
	target_breakpoint_kind_from_current_state to get breakpoint kind
	for single_step breakpoint.

diff --git a/gdb/gdbserver/linux-aarch32-low.c b/gdb/gdbserver/linux-aarch32-low.c
index 2b710ba..7409050 100644
--- a/gdb/gdbserver/linux-aarch32-low.c
+++ b/gdb/gdbserver/linux-aarch32-low.c
@@ -288,7 +288,30 @@ arm_breakpoint_kind_from_current_state (CORE_ADDR *pcptr)
   if (arm_is_thumb_mode ())
     {
       *pcptr = MAKE_THUMB_ADDR (*pcptr);
-      return arm_breakpoint_kind_from_pc (pcptr);
+      int kind = arm_breakpoint_kind_from_pc (pcptr);
+
+      if (kind == ARM_BP_KIND_THUMB2)
+	{
+	    unsigned long cpsr;
+	    struct regcache *regcache
+	      = get_thread_regcache (current_thread, 1);
+
+	    collect_register_by_name (regcache, "cpsr", &cpsr);
+	    /* Only use 32-bit thumb-2 breakpoint if *PCPTR is within
+	       IT block, because it takes two PTRACE_POKETEXT calls to
+	       write 32-bit thumb-2 breakpoint to a 2-byte aligned
+	       address, and other threads can observe the partially
+	       modified instruction in the memory between two
+	       PTRACE_POKETEXT calls.
+
+	       Don't use 32-bit thumb-2 breakpoint if program is not
+	       in IT block or on the last instruction of IT block,
+	       (ITSTATE.IT<2:0> == 000).  These bits are from CPSR bit
+	       10, 25, and 26.  */
+	    if ((cpsr & 0x06000400) == 0)
+	      kind = ARM_BP_KIND_THUMB;
+	}
+      return kind;
     }
   else
     {
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
index 6e6926a..f3845cf 100644
--- a/gdb/gdbserver/mem-break.c
+++ b/gdb/gdbserver/mem-break.c
@@ -855,7 +855,21 @@ set_breakpoint_type_at (enum bkpt_type type, CORE_ADDR where,
 {
   int err_ignored;
   CORE_ADDR placed_address = where;
-  int breakpoint_kind = target_breakpoint_kind_from_pc (&placed_address);
+  int breakpoint_kind;
+
+  /* Get the kind of breakpoint to PLACED_ADDRESS except single-step
+     breakpoint.  Get the kind of single-step breakpoint according to
+     the current register state.  */
+  if (type == single_step_breakpoint)
+    {
+      breakpoint_kind
+	= target_breakpoint_kind_from_current_state (&placed_address);
+    }
+  else
+    {
+      breakpoint_kind
+	= target_breakpoint_kind_from_pc (&placed_address);
+    }
 
   return set_breakpoint (type, raw_bkpt_type_sw,
 			 placed_address, breakpoint_kind, handler,

  parent reply	other threads:[~2017-03-30 16:06 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-29 12:07 Antoine Tremblay
2016-11-29 12:07 ` [PATCH 2/2] Avoid step-over infinite loop in GDBServer Antoine Tremblay
2017-01-16 17:27   ` Antoine Tremblay
2017-01-18 16:31     ` Antoine Tremblay
2017-02-03 16:21   ` Pedro Alves
2017-02-17  3:39     ` Antoine Tremblay
2017-02-22 10:15   ` Yao Qi
2017-03-27 13:28     ` Antoine Tremblay
2016-11-29 12:12 ` [PATCH 1/2] This patch fixes GDBServer's run control for single stepping Antoine Tremblay
2017-01-16 17:28 ` Antoine Tremblay
2017-01-27 15:01 ` Yao Qi
2017-01-27 16:07   ` Antoine Tremblay
2017-01-27 17:01     ` Yao Qi
2017-01-27 18:24       ` Antoine Tremblay
2017-01-29 21:41         ` Yao Qi
2017-01-30 13:29           ` Antoine Tremblay
2017-02-03 16:13             ` Pedro Alves
2017-02-17  1:42               ` Antoine Tremblay
2017-02-17  2:05                 ` Pedro Alves
2017-02-17  3:06                   ` Antoine Tremblay
2017-02-17 22:19                     ` Yao Qi
2017-02-18  0:19                       ` Antoine Tremblay
2017-02-18 22:49                         ` Yao Qi
2017-02-19 19:40                           ` Antoine Tremblay
2017-02-19 20:31                             ` Antoine Tremblay
2017-03-29 12:41                           ` Antoine Tremblay
2017-03-29 14:11                             ` Antoine Tremblay
2017-03-29 17:54                               ` Antoine Tremblay
2017-03-30 16:06                             ` Yao Qi [this message]
2017-03-30 18:31                               ` Antoine Tremblay
2017-03-31 16:31                                 ` Yao Qi
2017-03-31 18:22                                   ` Antoine Tremblay
2017-04-03 12:41                                     ` Yao Qi
2017-04-03 13:18                                       ` Antoine Tremblay
2017-04-03 15:18                                         ` Yao Qi
2017-04-03 16:57                                           ` Antoine Tremblay
2017-02-16 22:32             ` Yao Qi
2017-02-17  2:17               ` Antoine Tremblay

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=86d1cy4umo.fsf@gmail.com \
    --to=qiyaoltc@gmail.com \
    --cc=antoine.tremblay@ericsson.com \
    --cc=gdb-patches@sourceware.org \
    --cc=palves@redhat.com \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).