public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] [PR gdb/13463] linux-nat: Stop lwp before xfer if running
@ 2013-08-08 19:57 simark
  0 siblings, 0 replies; 7+ messages in thread
From: simark @ 2013-08-08 19:57 UTC (permalink / raw)
  To: gdb-patches

Hi,

This is an attempt at finding a solution for PR 13463:
http://sourceware.org/bugzilla/show_bug.cgi?id=13463

IMO, this is a serious bug (at least on x86 Linux). Inserting breakpoints
while the inferior is running does not work. It can be triggered very easily:

    1. Start a simple program in non-stop/async mode.
    2. Put a breakpoint anywhere in the program.
    
You should get an error like

    Cannot access memory at address 0x400504  
  
What happens is that GDB tries to ptrace read/write the inferior's memory
while the process is not stopped, which is not supported.

The obvious/naive solution is to stop the process and resume it whenever
we want to do a memory transfer while it is executing. I gave it a shot,
and it seems to work for me, but there is probably some cases it does not
cover, maybe other things it breaks or some better way to do it. I ran a
make check and gdb.sum was identical before and after (minus the time).

What do you think about it?

	* linux-nat.c (linux_nat_xfer_partial): Interrupt during the
	memory transfer, if it is running.

---
 gdb/linux-nat.c |   18 ++++++++++++++++--
 1 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 45a6e5f..b8c0d1c 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -294,8 +294,9 @@ static void linux_nat_async (void (*callback)
 			      void *context),
 			     void *context);
 static int kill_lwp (int lwpid, int signo);
-
+static int linux_nat_stop_lwp (struct lwp_info *lwp, void *data);
 static int stop_callback (struct lwp_info *lp, void *data);
+static void cleanup_target_stop(void *arg);
 
 static void block_child_signals (sigset_t *prev_mask);
 static void restore_child_signals_mask (sigset_t *prev_mask);
@@ -4205,11 +4206,24 @@ linux_nat_xfer_partial (struct target_ops *ops, enum target_object object,
   old_chain = save_inferior_ptid ();
 
   if (is_lwp (inferior_ptid))
-    inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
+    {
+      struct lwp_info* lwp;
+      inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
+
+      lwp = find_lwp_pid (inferior_ptid);
+      if (target_async_permitted && lwp != NULL && !lwp->stopped)
+	{
+	  make_cleanup (cleanup_target_stop, &lwp->ptid);
+	  linux_nat_stop_lwp (lwp, NULL);
+	  stop_wait_callback (lwp, NULL);
+	}
+    }
+
 
   xfer = linux_ops->to_xfer_partial (ops, object, annex, readbuf, writebuf,
 				     offset, len);
   do_cleanups (old_chain);
   return xfer;
 }
-- 
1.7.1

^ permalink raw reply	[flat|nested] 7+ messages in thread
* [PATCH] [PR gdb/13463] linux-nat: Stop lwp before xfer if running
@ 2013-08-08 19:59 simon.marchi
  2013-08-27 19:33 ` Pedro Alves
  0 siblings, 1 reply; 7+ messages in thread
From: simon.marchi @ 2013-08-08 19:59 UTC (permalink / raw)
  To: gdb-patches

(err, resending with setting From: correctly, sorry about that)

Hi,

This is an attempt at finding a solution for PR 13463:
http://sourceware.org/bugzilla/show_bug.cgi?id=13463

IMO, this is a serious bug (at least on x86 Linux). Inserting breakpoints
while the inferior is running does not work. It can be triggered very easily:

    1. Start a simple program in non-stop/async mode.
    2. Put a breakpoint anywhere in the program.
    
You should get an error like

    Cannot access memory at address 0x400504  
  
What happens is that GDB tries to ptrace read/write the inferior's memory
while the process is not stopped, which is not supported.

The obvious/naive solution is to stop the process and resume it whenever
we want to do a memory transfer while it is executing. I gave it a shot,
and it seems to work for me, but there is probably some cases it does not
cover, maybe other things it breaks or some better way to do it. I ran a
make check and gdb.sum was identical before and after (minus the time).

What do you think about it?

	* linux-nat.c (linux_nat_xfer_partial): Interrupt during the
	memory transfer, if it is running.

---
 gdb/linux-nat.c |   18 ++++++++++++++++--
 1 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 45a6e5f..b8c0d1c 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -294,8 +294,9 @@ static void linux_nat_async (void (*callback)
 			      void *context),
 			     void *context);
 static int kill_lwp (int lwpid, int signo);
-
+static int linux_nat_stop_lwp (struct lwp_info *lwp, void *data);
 static int stop_callback (struct lwp_info *lp, void *data);
+static void cleanup_target_stop(void *arg);
 
 static void block_child_signals (sigset_t *prev_mask);
 static void restore_child_signals_mask (sigset_t *prev_mask);
@@ -4205,11 +4206,24 @@ linux_nat_xfer_partial (struct target_ops *ops, enum target_object object,
   old_chain = save_inferior_ptid ();
 
   if (is_lwp (inferior_ptid))
-    inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
+    {
+      struct lwp_info* lwp;
+      inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
+
+      lwp = find_lwp_pid (inferior_ptid);
+      if (target_async_permitted && lwp != NULL && !lwp->stopped)
+	{
+	  make_cleanup (cleanup_target_stop, &lwp->ptid);
+	  linux_nat_stop_lwp (lwp, NULL);
+	  stop_wait_callback (lwp, NULL);
+	}
+    }
+
 
   xfer = linux_ops->to_xfer_partial (ops, object, annex, readbuf, writebuf,
 				     offset, len);
   do_cleanups (old_chain);
   return xfer;
 }
-- 
1.7.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-09-18 18:35 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-08 19:57 [PATCH] [PR gdb/13463] linux-nat: Stop lwp before xfer if running simark
2013-08-08 19:59 simon.marchi
2013-08-27 19:33 ` Pedro Alves
2013-08-27 19:36   ` Pedro Alves
2013-08-30 12:48   ` Simon Marchi
2013-09-02 19:03     ` Pedro Alves
2013-09-18 18:35     ` Doug Evans

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).