From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27472 invoked by alias); 11 Apr 2010 01:52:47 -0000 Received: (qmail 27463 invoked by uid 22791); 11 Apr 2010 01:52:45 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=BAYES_00,TW_EG,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 11 Apr 2010 01:52:39 +0000 Received: (qmail 22458 invoked from network); 11 Apr 2010 01:52:38 -0000 Received: from unknown (HELO orlando.localnet) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 11 Apr 2010 01:52:38 -0000 From: Pedro Alves To: gdb-patches@sourceware.org Subject: Fix solib-disc.exp regression with x86 gdbserver Date: Sun, 11 Apr 2010 01:52:00 -0000 User-Agent: KMail/1.12.2 (Linux/2.6.31-20-generic; KDE/4.3.2; x86_64; ; ) Cc: "H.J. Lu" MIME-Version: 1.0 Content-Type: Text/Plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Message-Id: <201004110252.35997.pedro@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-04/txt/msg00319.txt.bz2 The testsuite shows a couple of new regression with x86 gdbserver: -PASS: gdb.base/solib-disc.exp: check $pc after load +FAIL: gdb.base/solib-disc.exp: check $pc after load -PASS: gdb.base/solib-disc.exp: check $pc after unload +FAIL: gdb.base/solib-disc.exp: check $pc after unload The test stops at a breakpoint, saves the PC, disconnects, reconnects, and expects to find the same PC. But, it doesn't currently: ... print/x $pc $1 = 0x2b5a65534fc0 ^^^^^^^^^^^^^^ (gdb) PASS: gdb.base/solib-disc.exp: save $pc after load disconnect Ending remote debugging. (gdb) PASS: gdb.base/solib-disc.exp: disconnect after load readchar: Got EOF Remote side has terminated connection. GDBserver will reopen the connection. Listening on port 2463 Remote debugging from host 127.0.0.1 target remote localhost:2463 ... Loaded symbols for /lib64/ld-linux-x86-64.so.2 0x00002b5a65534fc1 in _dl_debug_state () at dl-debug.c:77 77 dl-debug.c: No such file or directory. in dl-debug.c (gdb) PASS: gdb.base/solib-disc.exp: reconnect after load print/x $pc $2 = 0x2b5a65534fc1 ^^^^^^^^^^^^^^ (gdb) FAIL: gdb.base/solib-disc.exp: check $pc after load Note the off-by-one. This is the decr_pc_after_break getting lost between disconnect/reconnect. gdbserver's regcache is not write-through, registers are only flushed to the threads just before resuming them. The problem is that there's new code that recreates all thread's regcaches without flushing them to the threads before the recreation. #0 init_register_cache (regcache=0x6453f0, regbuf=0x0) at ../../../src/gdb/gdbserver/regcache.c:85 #1 0x00000000004074fb in new_register_cache () at ../../../src/gdb/gdbserver/regcache.c:114 #2 0x00000000004075a5 in realloc_register_cache (thread_p=0x645390) at ../../../src/gdb/gdbserver/regcache.c:142 #3 0x00000000004068ce in for_each_inferior (list=0x63c5c0, action=0x407570 ) at ../../../src/gdb/gdbserver/inferiors.c:134 #4 0x0000000000407662 in set_register_cache (regs=0x638580, n=58) at ../../../src/gdb/gdbserver/regcache.c:167 #5 0x000000000041a0df in init_registers_amd64_linux () at amd64-linux.c:93 #6 0x0000000000423692 in x86_linux_update_xmltarget () at ../../../src/gdb/gdbserver/linux-x86-low.c:849 #7 0x00000000004238a2 in x86_linux_process_qsupported (query=0x0) at ../../../src/gdb/gdbserver/linux-x86-low.c:980 #8 0x000000000042265e in linux_process_qsupported (query=0x0) at ../../../src/gdb/gdbserver/linux-low.c:4235 #9 0x000000000040d433 in handle_query (own_buf=0x63d190 "qSupported:xmlRegisters=i386", packet_len=28, ... This is losing any register changes done before "disconnect" in the previous session. The patch below fixes it, and I've applied it. (H.J., in case you don't know yet, here's how one easily tests against gdbserver on localhost: ) -- Pedro Alves 2010-04-11 Pedro Alves gdb/gdbserver/ * regcache.c (realloc_register_cache): Invalidate inferior's regcache before recreating it. --- gdb/gdbserver/regcache.c | 2 ++ 1 file changed, 2 insertions(+) Index: src/gdb/gdbserver/regcache.c =================================================================== --- src.orig/gdb/gdbserver/regcache.c 2010-04-11 01:53:44.000000000 +0100 +++ src/gdb/gdbserver/regcache.c 2010-04-11 02:32:15.000000000 +0100 @@ -138,6 +138,8 @@ realloc_register_cache (struct inferior_ struct regcache *regcache = (struct regcache *) inferior_regcache_data (thread); + if (regcache != NULL) + regcache_invalidate_one (thread_p); free_register_cache (regcache); set_inferior_regcache_data (thread, new_register_cache ()); }