From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5103 invoked by alias); 21 Nov 2002 22:42:34 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 4971 invoked from network); 21 Nov 2002 22:42:31 -0000 Received: from unknown (HELO localhost.redhat.com) (216.138.202.10) by sources.redhat.com with SMTP; 21 Nov 2002 22:42:31 -0000 Received: from redhat.com (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id A87F43E4B for ; Thu, 21 Nov 2002 17:42:24 -0500 (EST) Message-ID: <3DDD6150.10407@redhat.com> Date: Thu, 21 Nov 2002 14:42:00 -0000 From: Andrew Cagney User-Agent: Mozilla/5.0 (X11; U; NetBSD macppc; en-US; rv:1.0.0) Gecko/20020824 X-Accept-Language: en-us, en MIME-Version: 1.0 To: gdb@sources.redhat.com Subject: [Fwd: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)] Content-Type: multipart/mixed; boundary="------------020906030009080908050001" X-SW-Source: 2002-11/txt/msg00316.txt.bz2 This is a multi-part message in MIME format. --------------020906030009080908050001 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 140 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 --------------020906030009080908050001 Content-Type: message/rfc822; name="Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?)" Content-length: 5946 X-Mozilla-Status2: 00000000 Return-Path: Delivered-To: ac131313@localhost.redhat.com Received: from localhost (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id 73E1F3F30 for ; Thu, 21 Nov 2002 16:21:16 -0500 (EST) Envelope-to: cagney@gnu.org Delivery-date: Thu, 21 Nov 2002 16:18:23 -0500 Received: from fencepost.gnu.org by localhost with IMAP (fetchmail-5.9.13) for ac131313@localhost (single-drop); Thu, 21 Nov 2002 16:21:16 -0500 (EST) Received: from monty-python.gnu.org ([199.232.76.173]) by fencepost.gnu.org with esmtp (Exim 4.10) id 18EyiN-0008Rx-00 for cagney@gnu.org; Thu, 21 Nov 2002 16:18:23 -0500 Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.10) id 18EyiH-0000vu-00 for cagney@gnu.org; Thu, 21 Nov 2002 16:18:22 -0500 Received: from sources.redhat.com ([209.249.29.67]) by monty-python.gnu.org with smtp (Exim 4.10) id 18EyiG-0000vh-00 for cagney@gnu.org; Thu, 21 Nov 2002 16:18:16 -0500 Received: (qmail 25620 invoked by alias); 21 Nov 2002 21:18:01 -0000 Mailing-List: contact gdb-prs-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-prs-owner@sources.redhat.com Delivered-To: mailing list gdb-prs@sources.redhat.com Received: (qmail 25550 invoked by uid 71); 21 Nov 2002 21:18:01 -0000 Date: 21 Nov 2002 21:18:01 -0000 Message-ID: <20021121211801.25549.qmail@sources.redhat.com> To: nobody@sources.redhat.com Cc: gdb-prs@sources.redhat.com, From: Andrew Cagney Subject: Re: gdb/725: Crash using debug target and regcaches (in 5.3 branch?) Reply-To: Andrew Cagney X-Spam-Status: No, hits=3.2 required=5.0 tests=FROM_ENDS_IN_NUMS,MAILTO_TO_SPAM_ADDR,SPAM_PHRASE_00_01 version=2.41 X-Spam-Level: *** Content-length: 3790 The following reply was made to PR gdb/725; it has been noted by GNATS. From: Andrew Cagney 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 --------------020906030009080908050001--