Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* [Fwd: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)]
@ 2002-11-21 14:42 Andrew Cagney
  2002-11-21 16:14 ` Daniel Jacobowitz
  2002-11-26  6:48 ` Andrew Cagney
  0 siblings, 2 replies; 8+ messages in thread
From: Andrew Cagney @ 2002-11-21 14:42 UTC (permalink / raw)
  To: gdb

[-- Attachment #1: Type: text/plain, Size: 140 bytes --]

FYI,

Too many memory reads/writes was one reason for a ptrace'd threaded 
shlib program running slow, I suspect this is the other.

Andrew

[-- Attachment #2: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?) --]
[-- Type: message/rfc822, Size: 5967 bytes --]

From: Andrew Cagney <ac131313@redhat.com>
To: nobody@sources.redhat.com
Cc: gdb-prs@sources.redhat.com,
Subject: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)
Date: 21 Nov 2002 21:18:01 -0000
Message-ID: <20021121211801.25549.qmail@sources.redhat.com>

The following reply was made to PR gdb/725; it has been noted by GNATS.

From: Andrew Cagney <ac131313@redhat.com>
To: gdb-gnats@sources.redhat.com
Cc:  
Subject: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)
Date: Thu, 21 Nov 2002 16:16:02 -0500

 "regcache.c" is innocent!
 
 (And the little I just learnt about GDB's thread implementation scares 
 me! :-)
 
 Briefly, the GNU/Linux thread code is giving regcache.c conflicting 
 stories over which inferior ptid should be in the register cache.  As a 
 consequence, every single register fetch leads to a regcache flush and 
 re-fetch.  Outch!
 
 
 Briefly,  core GDB tries to fetch a register.  This eventually leads to 
 the call:
 
 regcache_raw_read(REGNUM)
 
 	registers_tpid != inferior_tpid
 (gdb) print registers_ptid
 $6 = {pid = 31263, lwp = 0, tid = 0}
 (gdb) print inferior_ptid
 $7 = {pid = 31263, lwp = 31263, tid = 0}
 		-> flush regcache
 		-> registers_tpid = inferior_tpid
 	-- at this point regnum is invalid
 	target_fetch_registers (regnum)
 
 Since the inferior doesn't match the target, the cache is flushed, 
 inferior_ptid is updated, and the register is fetched.  The fetch flows 
 on down into the depths of the target and the call:
 
 Seen the problem yet?
 
 lin_lwp_fetch_registers(REGNUM):
 
 1347    lin_lwp_fetch_registers (int regno)
 1348    {
 1349      struct cleanup *old_chain = save_inferior_ptid ();
 1350
 1351      if (is_lwp (inferior_ptid))
 1352        inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
 1353
 (gdb)
 1354      fetch_inferior_registers (regno);
 1355
 1356      do_cleanups (old_chain);
 1357    }
 
 Seen the problem yet?
 
 Not sure why, but the code takes the path:
 	inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
 changing:
 (gdb) print inferior_ptid
 $10 = {pid = 31263, lwp = 31263, tid = 0}
 (gdb) n
 1354      fetch_inferior_registers (regno);
 (gdb) print inferior_ptid
 $11 = {pid = 31263, lwp = 0, tid = 0}
 (gdb)
 
 Seen the problem yet?
 
 And then proceeds to extract the registers using ptrace.  The extracted 
 registers are fed to the register cache using:
 
 supply_register(REGNUM, VAL):
 
 1209    supply_register (int regnum, const void *val)
 1210    {
 1211    #if 1
 1212      if (! ptid_equal (registers_ptid, inferior_ptid))
 1213        {
 1214          registers_changed ();
 1215          registers_ptid = inferior_ptid;
 1216        }
 (gdb)
 1217    #endif
 1218
 1219      set_register_cached (regnum, 1);
 
 and the assignment:
 
 1215          registers_ptid = inferior_ptid;
 (gdb) n
 1219      set_register_cached (regnum, 1);
 (gdb) print registers_ptid
 $14 = {pid = 31263, lwp = 0, tid = 0}
 (gdb)
 
 So, registers_ptid is set back to {pid = 31263, lwp = 0, tid = 0} ready 
 to start the entire cycle, again, on that very next register fetch!
 
 
 Two problems:
 
 
 - this means that the current register cache is being rendered useless 
 as it will never hang onto any register value.  Looks very like reason#2 
 for GDB being slow when debugging a threaded application.
 
 
 - in the case of `set debug target 1', the bug causes an infinite 
 recursion (the cause of the crash) because the code:
 1709    static void
 1710    debug_to_fetch_registers (int regno)
 1711    {
 1712      debug_target.to_fetch_registers (regno);
 1713      debug_print_register ("target_fetch_registers", regno);
 1714    }
 is assuming that the debug_target.to_fetch_registers (regno) call 
 results in the the register's value being entered into the cache, and 
 hence a further deprecated_read_register_gen() won't lead to a call to 
 target_fetch_registers()
 
 
 Fix?
 
 The long term fix is to have per-thread register caches, that is 
 progressing.
 
 I don't know about a short term fix though.
 
 Andrew
 


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

* Re: [Fwd: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)]
  2002-11-21 14:42 [Fwd: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)] Andrew Cagney
@ 2002-11-21 16:14 ` Daniel Jacobowitz
  2002-11-21 16:43   ` Andrew Cagney
  2002-11-26  6:48 ` Andrew Cagney
  1 sibling, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2002-11-21 16:14 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb

On Thu, Nov 21, 2002 at 05:42:24PM -0500, Andrew Cagney wrote:
> FYI,
> 
> Too many memory reads/writes was one reason for a ptrace'd threaded 
> shlib program running slow, I suspect this is the other.

Maybe, maybe not... definitely needs to go though!  Thanks for such a
thorough investigation, it gave me a good idea.

>  Briefly, the GNU/Linux thread code is giving regcache.c conflicting 
>  stories over which inferior ptid should be in the register cache.  As a 
>  consequence, every single register fetch leads to a regcache flush and 
>  re-fetch.  Outch!
>  
>  
>  Briefly,  core GDB tries to fetch a register.  This eventually leads to 
>  the call:
>  
>  regcache_raw_read(REGNUM)
>  
>  	registers_tpid != inferior_tpid
>  (gdb) print registers_ptid
>  $6 = {pid = 31263, lwp = 0, tid = 0}
>  (gdb) print inferior_ptid
>  $7 = {pid = 31263, lwp = 31263, tid = 0}
>  		-> flush regcache
>  		-> registers_tpid = inferior_tpid
>  	-- at this point regnum is invalid
>  	target_fetch_registers (regnum)
>  
>  Since the inferior doesn't match the target, the cache is flushed, 
>  inferior_ptid is updated, and the register is fetched.  The fetch flows 
>  on down into the depths of the target and the call:
>  
>  Seen the problem yet?

Yup.  Saw something else very interesting, too.

>  The long term fix is to have per-thread register caches, that is 
>  progressing.
>  
>  I don't know about a short term fix though.

I was working on a short-term fix and discovered it was almost entirely
in place already.  Look at a couple of random fetch_inferior_registers
implementations; every one that a GNU/Linux platform uses already will
fetch the LWP's registers if the LWP is non-zero.  So why not give that
to 'em?  Leave the inferior_ptid as it is, and make
fetch_inferior_registers honor the LWP id.

I fixed sparc-nat.c (the fix is a little gross but holds to the style
of the file); I fixed up lin-lwp; I timed a couple of tests.  Look at
what I got.

Currently, on my desktop, to run linux-dp.exp and schedlock.exp:
runtest linux-dp.exp schedlock.exp  101.06s user 50.80s system 130% cpu 1:56.27 total
With change:
runtest linux-dp.exp schedlock.exp  92.13s user 48.46s system 131% cpu 1:47.30 total

Wait, I'm being foolish.  Schedlock has some CPU-intensive loops in it
so when you're trying to get CPU information for GDB it's not a good
choice.  Trying again with linux-dp.exp and print-threads.exp,
currently:
runtest linux-dp.exp print-threads.exp  17.21s user 48.22s system 82% cpu 1:19.56 total
With change:
runtest linux-dp.exp print-threads.exp  16.67s user 45.35s system 82% cpu 1:15.27 total

Linux-dp also has some spinning and sending of SIGINTs, so again the
work done isn't entirely deterministic - but that's still an
interesting difference to me.  And we're definitely finding the correct
registers for each thread, at least on i386-linux; I'm pretty confident
about other targets, too.

And: it appears to fix the PR.  We do so terrifyingly much reading from
the inferior that it's kind of hard to tell; but normally it would have
crashed by now.  And I can "info threads" and print out $eip without it
looping again.

So, thoughts on the attached patch?

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2002-11-21  Daniel Jacobowitz  <drow@mvista.com>

	Fix PR gdb/725
	* lin-lwp.c (lin_lwp_fetch_registers): Remove.
	(lin_lwp_store_registers): Remove.
	(init_lin_lwp_ops): Use fetch_inferior_registers
	and store_inferior_registers directly.
	* sparc-nat.c (fetch_inferior_registers): Honor LWP ID.
	(store_inferior_registers): Likewise.

Index: lin-lwp.c
===================================================================
RCS file: /cvs/src/src/gdb/lin-lwp.c,v
retrieving revision 1.36
diff -u -p -r1.36 lin-lwp.c
--- lin-lwp.c	31 Oct 2002 21:00:08 -0000	1.36
+++ lin-lwp.c	22 Nov 2002 00:12:14 -0000
@@ -1343,32 +1343,6 @@ lin_lwp_mourn_inferior (void)
   child_ops.to_mourn_inferior ();
 }
 
-static void
-lin_lwp_fetch_registers (int regno)
-{
-  struct cleanup *old_chain = save_inferior_ptid ();
-
-  if (is_lwp (inferior_ptid))
-    inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
-
-  fetch_inferior_registers (regno);
-
-  do_cleanups (old_chain);
-}
-
-static void
-lin_lwp_store_registers (int regno)
-{
-  struct cleanup *old_chain = save_inferior_ptid ();
-
-  if (is_lwp (inferior_ptid))
-    inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
-
-  store_inferior_registers (regno);
-
-  do_cleanups (old_chain);
-}
-
 static int
 lin_lwp_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
 		     struct mem_attrib *attrib,
@@ -1426,8 +1400,10 @@ init_lin_lwp_ops (void)
   lin_lwp_ops.to_detach = lin_lwp_detach;
   lin_lwp_ops.to_resume = lin_lwp_resume;
   lin_lwp_ops.to_wait = lin_lwp_wait;
-  lin_lwp_ops.to_fetch_registers = lin_lwp_fetch_registers;
-  lin_lwp_ops.to_store_registers = lin_lwp_store_registers;
+  /* fetch_inferior_registers and store_inferior_registers will
+     honor the LWP id, so we can use them directly.  */
+  lin_lwp_ops.to_fetch_registers = fetch_inferior_registers;
+  lin_lwp_ops.to_store_registers = store_inferior_registers;
   lin_lwp_ops.to_xfer_memory = lin_lwp_xfer_memory;
   lin_lwp_ops.to_kill = lin_lwp_kill;
   lin_lwp_ops.to_create_inferior = lin_lwp_create_inferior;
Index: sparc-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-nat.c,v
retrieving revision 1.15
diff -u -p -r1.15 sparc-nat.c
--- sparc-nat.c	14 Nov 2002 20:37:29 -0000	1.15
+++ sparc-nat.c	22 Nov 2002 00:12:14 -0000
@@ -1,5 +1,6 @@
 /* Functions specific to running gdb native on a SPARC running SunOS4.
-   Copyright 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001
+   Copyright 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001,
+   2002
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -58,6 +59,15 @@ fetch_inferior_registers (int regno)
   struct regs inferior_registers;
   struct fp_status inferior_fp_registers;
   int i;
+  int fetch_pid;
+
+#ifdef __linux__
+  fetch_pid = TIDGET (inferior_ptid);
+  if (fetch_pid == 0)
+    fetch_pid = PIDGET (inferior_ptid);
+#else
+  fetch_pid = PIDGET (inferior_ptid);
+#endif
 
   /* We should never be called with deferred stores, because a prerequisite
      for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh.  */
@@ -75,7 +85,7 @@ fetch_inferior_registers (int regno)
       || regno >= Y_REGNUM
       || (!deprecated_register_valid[SP_REGNUM] && regno < I7_REGNUM))
     {
-      if (0 != ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
+      if (0 != ptrace (PTRACE_GETREGS, fetch_pid,
 		       (PTRACE_ARG3_TYPE) & inferior_registers, 0))
 	perror ("ptrace_getregs");
 
@@ -108,7 +118,7 @@ fetch_inferior_registers (int regno)
       regno == FPS_REGNUM ||
       (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31))
     {
-      if (0 != ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
+      if (0 != ptrace (PTRACE_GETFPREGS, fetch_pid,
 		       (PTRACE_ARG3_TYPE) & inferior_fp_registers,
 		       0))
 	perror ("ptrace_getfpregs");
@@ -153,6 +163,15 @@ store_inferior_registers (int regno)
   struct regs inferior_registers;
   struct fp_status inferior_fp_registers;
   int wanna_store = INT_REGS + STACK_REGS + FP_REGS;
+  int store_pid;
+
+#ifdef __linux__
+  store_pid = TIDGET (inferior_ptid);
+  if (store_pid == 0)
+    store_pid = PIDGET (inferior_ptid);
+#else
+  store_pid = PIDGET (inferior_ptid);
+#endif
 
   /* First decide which pieces of machine-state we need to modify.  
      Default for regno == -1 case is all pieces.  */
@@ -236,7 +255,7 @@ store_inferior_registers (int regno)
       inferior_registers.r_y =
 	*(int *) &deprecated_registers[REGISTER_BYTE (Y_REGNUM)];
 
-      if (0 != ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
+      if (0 != ptrace (PTRACE_SETREGS, store_pid,
 		       (PTRACE_ARG3_TYPE) & inferior_registers, 0))
 	perror ("ptrace_setregs");
     }
@@ -252,7 +271,7 @@ store_inferior_registers (int regno)
 	      &deprecated_registers[REGISTER_BYTE (FPS_REGNUM)],
 	      sizeof (FPU_FSR_TYPE));
       if (0 !=
-	  ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
+	  ptrace (PTRACE_SETFPREGS, store_pid,
 		  (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0))
 	perror ("ptrace_setfpregs");
     }


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

* Re: [Fwd: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)]
  2002-11-21 16:14 ` Daniel Jacobowitz
@ 2002-11-21 16:43   ` Andrew Cagney
  2002-11-21 17:38     ` Andrew Cagney
  2002-11-21 18:37     ` Daniel Jacobowitz
  0 siblings, 2 replies; 8+ messages in thread
From: Andrew Cagney @ 2002-11-21 16:43 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb

> On Thu, Nov 21, 2002 at 05:42:24PM -0500, Andrew Cagney wrote:
> 
>> FYI,
>> 
>> Too many memory reads/writes was one reason for a ptrace'd threaded 
>> shlib program running slow, I suspect this is the other.
> 
> 
> Maybe, maybe not... definitely needs to go though!  Thanks for such a
> thorough investigation, it gave me a good idea.

[snip]

>> currently:
>> runtest linux-dp.exp print-threads.exp  17.21s user 48.22s system 82% cpu 1:19.56 total
>> With change:
>> runtest linux-dp.exp print-threads.exp  16.67s user 45.35s system 82% cpu 1:15.27 total

Given that the numbers are being overwhelmed by all those memory read 
ptrace calls, a ~5% improvement is significant.

Try something simpler like running gdb under strace (tweak 
testsuite/lib/gdb.exp to run 'strace $GDB' instead of $GDB) and then 
count how many ptrace calls of each type occure.

>>  Briefly, the GNU/Linux thread code is giving regcache.c conflicting 
>>  stories over which inferior ptid should be in the register cache.  As a 
>>  consequence, every single register fetch leads to a regcache flush and 
>>  re-fetch.  Outch!
>>  
>>  
>>  Briefly,  core GDB tries to fetch a register.  This eventually leads to 
>>  the call:
>>  
>>  regcache_raw_read(REGNUM)
>>  
>>  	registers_tpid != inferior_tpid
>>  (gdb) print registers_ptid
>>  $6 = {pid = 31263, lwp = 0, tid = 0}
>>  (gdb) print inferior_ptid
>>  $7 = {pid = 31263, lwp = 31263, tid = 0}
>>  		-> flush regcache
>>  		-> registers_tpid = inferior_tpid
>>  	-- at this point regnum is invalid
>>  	target_fetch_registers (regnum)
>>  
>>  Since the inferior doesn't match the target, the cache is flushed, 
>>  inferior_ptid is updated, and the register is fetched.  The fetch flows 
>>  on down into the depths of the target and the call:
>>  
>>  Seen the problem yet?
> 
> 
> Yup.  Saw something else very interesting, too.
> 
> 
>>  The long term fix is to have per-thread register caches, that is 
>>  progressing.
>>  
>>  I don't know about a short term fix though.
> 
> 
> I was working on a short-term fix and discovered it was almost entirely
> in place already.  Look at a couple of random fetch_inferior_registers
> implementations; every one that a GNU/Linux platform uses already will
> fetch the LWP's registers if the LWP is non-zero.  So why not give that
> to 'em?  Leave the inferior_ptid as it is, and make
> fetch_inferior_registers honor the LWP id.

It feels right.  I'm hopeing that, eventually, the code will supply the 
registers direct to a (one of many) `struct thread_info' object.

> So, thoughts on the attached patch?

Thread maintainer question (not so sure about the #ifdef linux though :-).

Andrew



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

* Re: [Fwd: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)]
  2002-11-21 16:43   ` Andrew Cagney
@ 2002-11-21 17:38     ` Andrew Cagney
  2002-11-21 18:37     ` Daniel Jacobowitz
  1 sibling, 0 replies; 8+ messages in thread
From: Andrew Cagney @ 2002-11-21 17:38 UTC (permalink / raw)
  To: Andrew Cagney, gdb; +Cc: Daniel Jacobowitz

In fact:

cagney@torrens$ grep ptrace gdb.strace | wc -l
5236211

cagney@torrens$ grep PTRACE_PEEKUSER gdb.strace | wc -l
     162
cagney@torrens$ grep PTRACE_CONT gdb.strace | wc -l
     610
cagney@torrens$ grep SIGSTOP gdb.strace | grep kill | wc -l
     515

But, get this:

cagney@torrens$ grep PTRACE_PEEKTEXT gdb.strace | wc -l
5231130

so, until the PEEKTEXT is eliminated, it won't make any difference.

--

Plucking a ``random'' memory location out of thin air:

cagney@torrens$ grep 0x40040ea0 gdb.strace | grep ptrace | wc -l
    7038
cagney@torrens$ expr 7038 \* 250
1759500

(I think its a buffer that thread db needs - the buffer is read 7000 
times when the target only does ~160 continues (if that)).

Andrew


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

* Re: [Fwd: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)]
  2002-11-21 16:43   ` Andrew Cagney
  2002-11-21 17:38     ` Andrew Cagney
@ 2002-11-21 18:37     ` Daniel Jacobowitz
  2002-11-25 17:41       ` Daniel Jacobowitz
  1 sibling, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2002-11-21 18:37 UTC (permalink / raw)
  To: Andrew Cagney, msnyder, kettenis; +Cc: gdb

On Thu, Nov 21, 2002 at 07:42:54PM -0500, Andrew Cagney wrote:
> >On Thu, Nov 21, 2002 at 05:42:24PM -0500, Andrew Cagney wrote:
> >
> >>FYI,
> >>
> >>Too many memory reads/writes was one reason for a ptrace'd threaded 
> >>shlib program running slow, I suspect this is the other.
> >
> >
> >Maybe, maybe not... definitely needs to go though!  Thanks for such a
> >thorough investigation, it gave me a good idea.
> 
> [snip]
> 
> >>currently:
> >>runtest linux-dp.exp print-threads.exp  17.21s user 48.22s system 82% cpu 
> >>1:19.56 total
> >>With change:
> >>runtest linux-dp.exp print-threads.exp  16.67s user 45.35s system 82% cpu 
> >>1:15.27 total
> 
> Given that the numbers are being overwhelmed by all those memory read 
> ptrace calls, a ~5% improvement is significant.
> 
> Try something simpler like running gdb under strace (tweak 
> testsuite/lib/gdb.exp to run 'strace $GDB' instead of $GDB) and then 
> count how many ptrace calls of each type occure.

This was an excercise in patience; I had to mess with the timeouts,
too.  An initial strace log (of JUST ptrace calls!) was 221 MB.  Once I
bumped the timeouts high enough to run all of print-threads.exp without
DejaGNU getting bored and failing, it was even bigger: 918 MB.  As you
noticed in your next message, most of these are PEEKTEXT's.  This patch
does still make a tiny bit of difference, though.

Without the patch, the test takes about 16 minutes, has a 918MB log,
shows the one failure that I expected to see in print-threads.exp
(still haven't figured that one out), and:
   2113 PTRACE_???
     18 PTRACE_ATTACH
    233 PTRACE_CONT
18033347        PTRACE_PEEKTEXT
    121 PTRACE_PEEKUSER
    694 PTRACE_POKEDATA
      8 PTRACE_POKETEXT
     56 PTRACE_SINGLESTEP

With the patch the log was 480K smaller (i.e. the same size :), the run
took roughly the same time (not surprising, most of it is writing out
the log), same one failure, and:
   2107 PTRACE_???
     18 PTRACE_ATTACH
    241 PTRACE_CONT
18031743      PTRACE_PEEKTEXT
    121 PTRACE_PEEKUSER
    694 PTRACE_POKEDATA
      8 PTRACE_POKETEXT
     56 PTRACE_SINGLESTEP

The patch saved 6 PTRACE_??? calls and 1604 PTRACE_PEEKTEXT calls.  OK,
I'm not overwhelmed here.  The ??? are PTRACE_GETREGS/PTRACE_SETREGS,
of course.

> 
> >> Briefly, the GNU/Linux thread code is giving regcache.c conflicting 
> >> stories over which inferior ptid should be in the register cache.  As a 
> >> consequence, every single register fetch leads to a regcache flush and 
> >> re-fetch.  Outch!
> >> 
> >> 
> >> Briefly,  core GDB tries to fetch a register.  This eventually leads to 
> >> the call:
> >> 
> >> regcache_raw_read(REGNUM)
> >> 
> >> 	registers_tpid != inferior_tpid
> >> (gdb) print registers_ptid
> >> $6 = {pid = 31263, lwp = 0, tid = 0}
> >> (gdb) print inferior_ptid
> >> $7 = {pid = 31263, lwp = 31263, tid = 0}
> >> 		-> flush regcache
> >> 		-> registers_tpid = inferior_tpid
> >> 	-- at this point regnum is invalid
> >> 	target_fetch_registers (regnum)
> >> 
> >> Since the inferior doesn't match the target, the cache is flushed, 
> >> inferior_ptid is updated, and the register is fetched.  The fetch flows 
> >> on down into the depths of the target and the call:
> >> 
> >> Seen the problem yet?
> >
> >
> >Yup.  Saw something else very interesting, too.
> >
> >
> >> The long term fix is to have per-thread register caches, that is 
> >> progressing.
> >> 
> >> I don't know about a short term fix though.
> >
> >
> >I was working on a short-term fix and discovered it was almost entirely
> >in place already.  Look at a couple of random fetch_inferior_registers
> >implementations; every one that a GNU/Linux platform uses already will
> >fetch the LWP's registers if the LWP is non-zero.  So why not give that
> >to 'em?  Leave the inferior_ptid as it is, and make
> >fetch_inferior_registers honor the LWP id.
> 
> It feels right.  I'm hopeing that, eventually, the code will supply the 
> registers direct to a (one of many) `struct thread_info' object.
> 
> >So, thoughts on the attached patch?
> 
> Thread maintainer question (not so sure about the #ifdef linux though :-).

The #ifdef can just go actually.  The only operating system which uses
that file and threads is Linux, and when the BSDs get thread debugging
support I'd like to see them behave the same way, if they have multiple
LWPs.  Don't know anything about BSD threads.

So, thread maintainers, any opinion?  Here's the updated patch.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2002-11-21  Daniel Jacobowitz  <drow@mvista.com>

	Fix PR gdb/725
	* lin-lwp.c (lin_lwp_fetch_registers): Remove.
	(lin_lwp_store_registers): Remove.
	(init_lin_lwp_ops): Use fetch_inferior_registers
	and store_inferior_registers directly.
	* sparc-nat.c (fetch_inferior_registers): Honor LWP ID.
	(store_inferior_registers): Likewise.

Index: lin-lwp.c
===================================================================
RCS file: /cvs/src/src/gdb/lin-lwp.c,v
retrieving revision 1.36
diff -u -p -r1.36 lin-lwp.c
--- lin-lwp.c	31 Oct 2002 21:00:08 -0000	1.36
+++ lin-lwp.c	22 Nov 2002 02:35:31 -0000
@@ -1343,32 +1343,6 @@ lin_lwp_mourn_inferior (void)
   child_ops.to_mourn_inferior ();
 }
 
-static void
-lin_lwp_fetch_registers (int regno)
-{
-  struct cleanup *old_chain = save_inferior_ptid ();
-
-  if (is_lwp (inferior_ptid))
-    inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
-
-  fetch_inferior_registers (regno);
-
-  do_cleanups (old_chain);
-}
-
-static void
-lin_lwp_store_registers (int regno)
-{
-  struct cleanup *old_chain = save_inferior_ptid ();
-
-  if (is_lwp (inferior_ptid))
-    inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
-
-  store_inferior_registers (regno);
-
-  do_cleanups (old_chain);
-}
-
 static int
 lin_lwp_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
 		     struct mem_attrib *attrib,
@@ -1426,8 +1400,10 @@ init_lin_lwp_ops (void)
   lin_lwp_ops.to_detach = lin_lwp_detach;
   lin_lwp_ops.to_resume = lin_lwp_resume;
   lin_lwp_ops.to_wait = lin_lwp_wait;
-  lin_lwp_ops.to_fetch_registers = lin_lwp_fetch_registers;
-  lin_lwp_ops.to_store_registers = lin_lwp_store_registers;
+  /* fetch_inferior_registers and store_inferior_registers will
+     honor the LWP id, so we can use them directly.  */
+  lin_lwp_ops.to_fetch_registers = fetch_inferior_registers;
+  lin_lwp_ops.to_store_registers = store_inferior_registers;
   lin_lwp_ops.to_xfer_memory = lin_lwp_xfer_memory;
   lin_lwp_ops.to_kill = lin_lwp_kill;
   lin_lwp_ops.to_create_inferior = lin_lwp_create_inferior;
Index: sparc-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-nat.c,v
retrieving revision 1.15
diff -u -p -r1.15 sparc-nat.c
--- sparc-nat.c	14 Nov 2002 20:37:29 -0000	1.15
+++ sparc-nat.c	22 Nov 2002 02:35:31 -0000
@@ -1,5 +1,6 @@
 /* Functions specific to running gdb native on a SPARC running SunOS4.
-   Copyright 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001
+   Copyright 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001,
+   2002
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -58,6 +59,11 @@ fetch_inferior_registers (int regno)
   struct regs inferior_registers;
   struct fp_status inferior_fp_registers;
   int i;
+  int fetch_pid;
+
+  fetch_pid = TIDGET (inferior_ptid);
+  if (fetch_pid == 0)
+    fetch_pid = PIDGET (inferior_ptid);
 
   /* We should never be called with deferred stores, because a prerequisite
      for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh.  */
@@ -75,7 +81,7 @@ fetch_inferior_registers (int regno)
       || regno >= Y_REGNUM
       || (!deprecated_register_valid[SP_REGNUM] && regno < I7_REGNUM))
     {
-      if (0 != ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
+      if (0 != ptrace (PTRACE_GETREGS, fetch_pid,
 		       (PTRACE_ARG3_TYPE) & inferior_registers, 0))
 	perror ("ptrace_getregs");
 
@@ -108,7 +114,7 @@ fetch_inferior_registers (int regno)
       regno == FPS_REGNUM ||
       (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31))
     {
-      if (0 != ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
+      if (0 != ptrace (PTRACE_GETFPREGS, fetch_pid,
 		       (PTRACE_ARG3_TYPE) & inferior_fp_registers,
 		       0))
 	perror ("ptrace_getfpregs");
@@ -153,6 +159,11 @@ store_inferior_registers (int regno)
   struct regs inferior_registers;
   struct fp_status inferior_fp_registers;
   int wanna_store = INT_REGS + STACK_REGS + FP_REGS;
+  int store_pid;
+
+  store_pid = TIDGET (inferior_ptid);
+  if (store_pid == 0)
+    store_pid = PIDGET (inferior_ptid);
 
   /* First decide which pieces of machine-state we need to modify.  
      Default for regno == -1 case is all pieces.  */
@@ -236,7 +247,7 @@ store_inferior_registers (int regno)
       inferior_registers.r_y =
 	*(int *) &deprecated_registers[REGISTER_BYTE (Y_REGNUM)];
 
-      if (0 != ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
+      if (0 != ptrace (PTRACE_SETREGS, store_pid,
 		       (PTRACE_ARG3_TYPE) & inferior_registers, 0))
 	perror ("ptrace_setregs");
     }
@@ -252,7 +263,7 @@ store_inferior_registers (int regno)
 	      &deprecated_registers[REGISTER_BYTE (FPS_REGNUM)],
 	      sizeof (FPU_FSR_TYPE));
       if (0 !=
-	  ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
+	  ptrace (PTRACE_SETFPREGS, store_pid,
 		  (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0))
 	perror ("ptrace_setfpregs");
     }


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

* Re: [Fwd: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)]
  2002-11-21 18:37     ` Daniel Jacobowitz
@ 2002-11-25 17:41       ` Daniel Jacobowitz
  2002-11-25 18:00         ` Michael Snyder
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2002-11-25 17:41 UTC (permalink / raw)
  To: Andrew Cagney, msnyder, kettenis, gdb

On Thu, Nov 21, 2002 at 09:37:24PM -0500, Daniel Jacobowitz wrote:
> 2002-11-21  Daniel Jacobowitz  <drow@mvista.com>
> 
> 	Fix PR gdb/725
> 	* lin-lwp.c (lin_lwp_fetch_registers): Remove.
> 	(lin_lwp_store_registers): Remove.
> 	(init_lin_lwp_ops): Use fetch_inferior_registers
> 	and store_inferior_registers directly.
> 	* sparc-nat.c (fetch_inferior_registers): Honor LWP ID.
> 	(store_inferior_registers): Likewise.

Any comments on this patch?  If you like it, feel free to commit it for
5.3 - I'll be out of town this week.

> 
> Index: lin-lwp.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/lin-lwp.c,v
> retrieving revision 1.36
> diff -u -p -r1.36 lin-lwp.c
> --- lin-lwp.c	31 Oct 2002 21:00:08 -0000	1.36
> +++ lin-lwp.c	22 Nov 2002 02:35:31 -0000
> @@ -1343,32 +1343,6 @@ lin_lwp_mourn_inferior (void)
>    child_ops.to_mourn_inferior ();
>  }
>  
> -static void
> -lin_lwp_fetch_registers (int regno)
> -{
> -  struct cleanup *old_chain = save_inferior_ptid ();
> -
> -  if (is_lwp (inferior_ptid))
> -    inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
> -
> -  fetch_inferior_registers (regno);
> -
> -  do_cleanups (old_chain);
> -}
> -
> -static void
> -lin_lwp_store_registers (int regno)
> -{
> -  struct cleanup *old_chain = save_inferior_ptid ();
> -
> -  if (is_lwp (inferior_ptid))
> -    inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
> -
> -  store_inferior_registers (regno);
> -
> -  do_cleanups (old_chain);
> -}
> -
>  static int
>  lin_lwp_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
>  		     struct mem_attrib *attrib,
> @@ -1426,8 +1400,10 @@ init_lin_lwp_ops (void)
>    lin_lwp_ops.to_detach = lin_lwp_detach;
>    lin_lwp_ops.to_resume = lin_lwp_resume;
>    lin_lwp_ops.to_wait = lin_lwp_wait;
> -  lin_lwp_ops.to_fetch_registers = lin_lwp_fetch_registers;
> -  lin_lwp_ops.to_store_registers = lin_lwp_store_registers;
> +  /* fetch_inferior_registers and store_inferior_registers will
> +     honor the LWP id, so we can use them directly.  */
> +  lin_lwp_ops.to_fetch_registers = fetch_inferior_registers;
> +  lin_lwp_ops.to_store_registers = store_inferior_registers;
>    lin_lwp_ops.to_xfer_memory = lin_lwp_xfer_memory;
>    lin_lwp_ops.to_kill = lin_lwp_kill;
>    lin_lwp_ops.to_create_inferior = lin_lwp_create_inferior;
> Index: sparc-nat.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/sparc-nat.c,v
> retrieving revision 1.15
> diff -u -p -r1.15 sparc-nat.c
> --- sparc-nat.c	14 Nov 2002 20:37:29 -0000	1.15
> +++ sparc-nat.c	22 Nov 2002 02:35:31 -0000
> @@ -1,5 +1,6 @@
>  /* Functions specific to running gdb native on a SPARC running SunOS4.
> -   Copyright 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001
> +   Copyright 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001,
> +   2002
>     Free Software Foundation, Inc.
>  
>     This file is part of GDB.
> @@ -58,6 +59,11 @@ fetch_inferior_registers (int regno)
>    struct regs inferior_registers;
>    struct fp_status inferior_fp_registers;
>    int i;
> +  int fetch_pid;
> +
> +  fetch_pid = TIDGET (inferior_ptid);
> +  if (fetch_pid == 0)
> +    fetch_pid = PIDGET (inferior_ptid);
>  
>    /* We should never be called with deferred stores, because a prerequisite
>       for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh.  */
> @@ -75,7 +81,7 @@ fetch_inferior_registers (int regno)
>        || regno >= Y_REGNUM
>        || (!deprecated_register_valid[SP_REGNUM] && regno < I7_REGNUM))
>      {
> -      if (0 != ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
> +      if (0 != ptrace (PTRACE_GETREGS, fetch_pid,
>  		       (PTRACE_ARG3_TYPE) & inferior_registers, 0))
>  	perror ("ptrace_getregs");
>  
> @@ -108,7 +114,7 @@ fetch_inferior_registers (int regno)
>        regno == FPS_REGNUM ||
>        (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31))
>      {
> -      if (0 != ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
> +      if (0 != ptrace (PTRACE_GETFPREGS, fetch_pid,
>  		       (PTRACE_ARG3_TYPE) & inferior_fp_registers,
>  		       0))
>  	perror ("ptrace_getfpregs");
> @@ -153,6 +159,11 @@ store_inferior_registers (int regno)
>    struct regs inferior_registers;
>    struct fp_status inferior_fp_registers;
>    int wanna_store = INT_REGS + STACK_REGS + FP_REGS;
> +  int store_pid;
> +
> +  store_pid = TIDGET (inferior_ptid);
> +  if (store_pid == 0)
> +    store_pid = PIDGET (inferior_ptid);
>  
>    /* First decide which pieces of machine-state we need to modify.  
>       Default for regno == -1 case is all pieces.  */
> @@ -236,7 +247,7 @@ store_inferior_registers (int regno)
>        inferior_registers.r_y =
>  	*(int *) &deprecated_registers[REGISTER_BYTE (Y_REGNUM)];
>  
> -      if (0 != ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
> +      if (0 != ptrace (PTRACE_SETREGS, store_pid,
>  		       (PTRACE_ARG3_TYPE) & inferior_registers, 0))
>  	perror ("ptrace_setregs");
>      }
> @@ -252,7 +263,7 @@ store_inferior_registers (int regno)
>  	      &deprecated_registers[REGISTER_BYTE (FPS_REGNUM)],
>  	      sizeof (FPU_FSR_TYPE));
>        if (0 !=
> -	  ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
> +	  ptrace (PTRACE_SETFPREGS, store_pid,
>  		  (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0))
>  	perror ("ptrace_setfpregs");
>      }
> 

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


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

* Re: [Fwd: Re: gdb/725: Crash using debug target and regcaches (in 5.3  branch?)]
  2002-11-25 17:41       ` Daniel Jacobowitz
@ 2002-11-25 18:00         ` Michael Snyder
  0 siblings, 0 replies; 8+ messages in thread
From: Michael Snyder @ 2002-11-25 18:00 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Andrew Cagney, kettenis, gdb

Daniel Jacobowitz wrote:
> 
> On Thu, Nov 21, 2002 at 09:37:24PM -0500, Daniel Jacobowitz wrote:
> > 2002-11-21  Daniel Jacobowitz  <drow@mvista.com>
> >
> >       Fix PR gdb/725
> >       * lin-lwp.c (lin_lwp_fetch_registers): Remove.
> >       (lin_lwp_store_registers): Remove.
> >       (init_lin_lwp_ops): Use fetch_inferior_registers
> >       and store_inferior_registers directly.
> >       * sparc-nat.c (fetch_inferior_registers): Honor LWP ID.
> >       (store_inferior_registers): Likewise.
> 
> Any comments on this patch?  If you like it, feel free to commit it for
> 5.3 - I'll be out of town this week.

Seems like the spirit is in the right place.
Mark is probably in a better position than I am to comment on
the implementation.

> 
> >
> > Index: lin-lwp.c
> > ===================================================================
> > RCS file: /cvs/src/src/gdb/lin-lwp.c,v
> > retrieving revision 1.36
> > diff -u -p -r1.36 lin-lwp.c
> > --- lin-lwp.c 31 Oct 2002 21:00:08 -0000      1.36
> > +++ lin-lwp.c 22 Nov 2002 02:35:31 -0000
> > @@ -1343,32 +1343,6 @@ lin_lwp_mourn_inferior (void)
> >    child_ops.to_mourn_inferior ();
> >  }
> >
> > -static void
> > -lin_lwp_fetch_registers (int regno)
> > -{
> > -  struct cleanup *old_chain = save_inferior_ptid ();
> > -
> > -  if (is_lwp (inferior_ptid))
> > -    inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
> > -
> > -  fetch_inferior_registers (regno);
> > -
> > -  do_cleanups (old_chain);
> > -}
> > -
> > -static void
> > -lin_lwp_store_registers (int regno)
> > -{
> > -  struct cleanup *old_chain = save_inferior_ptid ();
> > -
> > -  if (is_lwp (inferior_ptid))
> > -    inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
> > -
> > -  store_inferior_registers (regno);
> > -
> > -  do_cleanups (old_chain);
> > -}
> > -
> >  static int
> >  lin_lwp_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
> >                    struct mem_attrib *attrib,
> > @@ -1426,8 +1400,10 @@ init_lin_lwp_ops (void)
> >    lin_lwp_ops.to_detach = lin_lwp_detach;
> >    lin_lwp_ops.to_resume = lin_lwp_resume;
> >    lin_lwp_ops.to_wait = lin_lwp_wait;
> > -  lin_lwp_ops.to_fetch_registers = lin_lwp_fetch_registers;
> > -  lin_lwp_ops.to_store_registers = lin_lwp_store_registers;
> > +  /* fetch_inferior_registers and store_inferior_registers will
> > +     honor the LWP id, so we can use them directly.  */
> > +  lin_lwp_ops.to_fetch_registers = fetch_inferior_registers;
> > +  lin_lwp_ops.to_store_registers = store_inferior_registers;
> >    lin_lwp_ops.to_xfer_memory = lin_lwp_xfer_memory;
> >    lin_lwp_ops.to_kill = lin_lwp_kill;
> >    lin_lwp_ops.to_create_inferior = lin_lwp_create_inferior;
> > Index: sparc-nat.c
> > ===================================================================
> > RCS file: /cvs/src/src/gdb/sparc-nat.c,v
> > retrieving revision 1.15
> > diff -u -p -r1.15 sparc-nat.c
> > --- sparc-nat.c       14 Nov 2002 20:37:29 -0000      1.15
> > +++ sparc-nat.c       22 Nov 2002 02:35:31 -0000
> > @@ -1,5 +1,6 @@
> >  /* Functions specific to running gdb native on a SPARC running SunOS4.
> > -   Copyright 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001
> > +   Copyright 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001,
> > +   2002
> >     Free Software Foundation, Inc.
> >
> >     This file is part of GDB.
> > @@ -58,6 +59,11 @@ fetch_inferior_registers (int regno)
> >    struct regs inferior_registers;
> >    struct fp_status inferior_fp_registers;
> >    int i;
> > +  int fetch_pid;
> > +
> > +  fetch_pid = TIDGET (inferior_ptid);
> > +  if (fetch_pid == 0)
> > +    fetch_pid = PIDGET (inferior_ptid);
> >
> >    /* We should never be called with deferred stores, because a prerequisite
> >       for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh.  */
> > @@ -75,7 +81,7 @@ fetch_inferior_registers (int regno)
> >        || regno >= Y_REGNUM
> >        || (!deprecated_register_valid[SP_REGNUM] && regno < I7_REGNUM))
> >      {
> > -      if (0 != ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
> > +      if (0 != ptrace (PTRACE_GETREGS, fetch_pid,
> >                      (PTRACE_ARG3_TYPE) & inferior_registers, 0))
> >       perror ("ptrace_getregs");
> >
> > @@ -108,7 +114,7 @@ fetch_inferior_registers (int regno)
> >        regno == FPS_REGNUM ||
> >        (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31))
> >      {
> > -      if (0 != ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
> > +      if (0 != ptrace (PTRACE_GETFPREGS, fetch_pid,
> >                      (PTRACE_ARG3_TYPE) & inferior_fp_registers,
> >                      0))
> >       perror ("ptrace_getfpregs");
> > @@ -153,6 +159,11 @@ store_inferior_registers (int regno)
> >    struct regs inferior_registers;
> >    struct fp_status inferior_fp_registers;
> >    int wanna_store = INT_REGS + STACK_REGS + FP_REGS;
> > +  int store_pid;
> > +
> > +  store_pid = TIDGET (inferior_ptid);
> > +  if (store_pid == 0)
> > +    store_pid = PIDGET (inferior_ptid);
> >
> >    /* First decide which pieces of machine-state we need to modify.
> >       Default for regno == -1 case is all pieces.  */
> > @@ -236,7 +247,7 @@ store_inferior_registers (int regno)
> >        inferior_registers.r_y =
> >       *(int *) &deprecated_registers[REGISTER_BYTE (Y_REGNUM)];
> >
> > -      if (0 != ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
> > +      if (0 != ptrace (PTRACE_SETREGS, store_pid,
> >                      (PTRACE_ARG3_TYPE) & inferior_registers, 0))
> >       perror ("ptrace_setregs");
> >      }
> > @@ -252,7 +263,7 @@ store_inferior_registers (int regno)
> >             &deprecated_registers[REGISTER_BYTE (FPS_REGNUM)],
> >             sizeof (FPU_FSR_TYPE));
> >        if (0 !=
> > -       ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
> > +       ptrace (PTRACE_SETFPREGS, store_pid,
> >                 (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0))
> >       perror ("ptrace_setfpregs");
> >      }
> >
> 
> --
> Daniel Jacobowitz
> MontaVista Software                         Debian GNU/Linux Developer


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

* Re: [Fwd: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)]
  2002-11-21 14:42 [Fwd: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)] Andrew Cagney
  2002-11-21 16:14 ` Daniel Jacobowitz
@ 2002-11-26  6:48 ` Andrew Cagney
  1 sibling, 0 replies; 8+ messages in thread
From: Andrew Cagney @ 2002-11-26  6:48 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb

> FYI,
> 
> Too many memory reads/writes was one reason for a ptrace'd threaded shlib program running slow, I suspect this is the other.

To correct this.

This should be a reason why GDB runs slow on GNU/Linux, but, isn't!  Per 
other thread, this inefficiency (a few 1 000 stray ptrace calls() is 
trivialized by the millions (yes >1 000 000) memory read ptrace calls. 
GDB was probably executing more memory ptrace() calls than the target 
program executes instructions .... (yea, right :-).

Andrew



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

end of thread, other threads:[~2002-11-26 14:48 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-11-21 14:42 [Fwd: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)] Andrew Cagney
2002-11-21 16:14 ` Daniel Jacobowitz
2002-11-21 16:43   ` Andrew Cagney
2002-11-21 17:38     ` Andrew Cagney
2002-11-21 18:37     ` Daniel Jacobowitz
2002-11-25 17:41       ` Daniel Jacobowitz
2002-11-25 18:00         ` Michael Snyder
2002-11-26  6:48 ` Andrew Cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox