From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15370 invoked by alias); 15 Feb 2012 13:52:05 -0000 Received: (qmail 15352 invoked by uid 22791); 15 Feb 2012 13:52:01 -0000 X-SWARE-Spam-Status: No, hits=-1.2 required=5.0 tests=AWL,BAYES_00,FROM_12LTRDOM X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 15 Feb 2012 13:51:43 +0000 Received: from nat-dem.mentorg.com ([195.212.93.2] helo=eu2-mail.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1RxfGn-0000EA-Tz from Thomas_Schwinge@mentor.com for gdb-patches@sourceware.org; Wed, 15 Feb 2012 05:51:42 -0800 Received: from feldtkeller.schwinge.homeip.net ([172.30.64.129]) by eu2-mail.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Wed, 15 Feb 2012 14:51:40 +0100 From: Thomas Schwinge To: gdb-patches@sourceware.org Subject: [PATCH] [SH] Prologue skipping if there is none User-Agent: Notmuch/0.9-101-g81dad07 (http://notmuchmail.org) Emacs/23.3.1 (x86_64-pc-linux-gnu) Date: Wed, 15 Feb 2012 14:00:00 -0000 Message-ID: <87pqdgciho.fsf@schwinge.name> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha1; protocol="application/pgp-signature" 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: 2012-02/txt/msg00300.txt.bz2 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Content-length: 15404 Hi! (No specific SH maintainer CCed as none is listed in MAINTAINERS.) First, for SH GNU/Linux, when running the testsuite via gdbserver on pristine sources, I'm getting a large number of ERRORs, in the 350s. Is that normal or at least known? They're basically all of the kind ``ERROR: Process no longer exists'', and then follow-up errors until the end of the specific testcase. From a very quick glance, they all seem to be happening after the testcase has instructed GDB to invoke a function, such as: (gdb) PASS: gdb.cp/classes.exp: print g_D.p call class_param.Aptr_a (&g_A) ERROR: Process no longer exists UNRESOLVED: gdb.cp/classes.exp: call class_param.Aptr_a (&g_A) ERROR: Couldn't send call class_param.Aptr_x (&g_A) to GDB. This probably suggests where to begin looking unless that's know already. The prologue skipping issue is that GDB fails to place breakpoints correctly at the beginning of a function -- such as for ``break main'' -- for the case that there is no prologue in that function. In such a case, it will currently place the breakpoint *after* the first source code line instead of at its beginning, for example ``break main'' for gdb.base/arrayidx.c will put a breakpoint on line 25 instead of 23: 20 int 21 main (void) 22 { 23 array[0] =3D 5; 24=20=20 25 return 0; 26 } Dump of assembler code for function main: 0x00400600 <+0>: mov.l 0x400610 ,r1 ! 0x41083c 0x00400602 <+2>: mov #5,r2 0x00400604 <+4>: mov.l r2,@r1 0x00400606 <+6>: mov #0,r1 0x00400608 <+8>: mov r1,r0 0x0040060a <+10>: rts 0x0040060c <+12>: nop 0x0040060e <+14>: nop 0x00400610 <+16>: mov.b @(r0,r3),r8 0x00400612 <+18>: .word 0x0041 End of assembler dump. Crude log of debugging the SH GNU/Linux GDB when advising it to ``break main'': Breakpoint 3, sh_skip_prologue (gdbarch=3D0x90043c8, start_pc=3D4195840) OK, this is start_pc =3D=3D 0x400600. 715 if (!find_pc_partial_function (pc, NULL, &func_addr, &func_en= d)) Value returned is $3 =3D 1 (gdb) print/x func_addr=20 $4 =3D 0x400600 (gdb) print/x func_end $5 =3D 0x400614 OK. 2137 return find_pc_sect_line (pc, section, notcurrent); Value returned is $8 =3D {pspace =3D 0x8fed340, symtab =3D 0x901a21c, s= ection =3D 0x0, line =3D 23, pc =3D 4195840, end =3D 4195846, explicit_pc = =3D 0, explicit_line =3D 0} OK, still $8->pc =3D=3D 0x400600, and $8->end =3D=3D 0x400606, and these are attached to line 23, ``array[0] =3D 5;''. after_prologue (pc=3D4195840) at /scratch/tschwing/ST_sh-linux-gnu-lite= /obj/gdb-src-2012.03-999999-sh-linux-gnu-i686-pc-linux-gnu/gdb/sh-tdep.c:726 726 if (sal.end < func_end) (gdb) n 727 return sal.end; (gdb) print/x sal.end $9 =3D 0x400606 Wrong, because we now have not skipped the prologue, but the first real instruction. Anyway, apart from the 350 ERRORs (with and without my patch), there is a clear tendency of improvement, and no regressions: Progressions and removed failures: =20=20=20=20 FAIL -> PASS: default/gdb.sum:gdb.base/arrayidx.exp: Print array with a= rray-indexes off FAIL -> PASS: default/gdb.sum:gdb.base/arrayidx.exp: Print array with a= rray-indexes on FAIL -> PASS: default/gdb.sum:gdb.base/break-always.exp: continue to br= eakpoint: bar FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = finish; return call-sc-tc FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = finish; return call-sc-td FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = finish; return call-sc-te FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = finish; return call-sc-tf FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = finish; return call-sc-ti FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = finish; return call-sc-tl FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = finish; return call-sc-tld FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = finish; return call-sc-tll FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = finish; return call-sc-ts FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = return; return call-sc-tc FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = return; return call-sc-td FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = return; return call-sc-te FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = return; return call-sc-tf FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = return; return call-sc-ti FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = return; return call-sc-tl FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = return; return call-sc-tld FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = return; return call-sc-tll FAIL -> PASS: default/gdb.sum:gdb.base/call-sc.exp: advance to fun for = return; return call-sc-ts FAIL -> PASS: default/gdb.sum:gdb.base/gdb11531.exp: watchpoint variabl= e triggers at next FAIL -> PASS: default/gdb.sum:gdb.base/reread.exp: breakpoint foo in fi= rst file FAIL -> PASS: default/gdb.sum:gdb.base/reread.exp: run to foo() FAIL -> PASS: default/gdb.sum:gdb.base/return.exp: continue to return o= f -5 FAIL -> PASS: default/gdb.sum:gdb.base/return.exp: continue to return o= f -5.0 FAIL -> PASS: default/gdb.sum:gdb.base/return2.exp: void function retur= ned successfully FAIL -> PASS: default/gdb.sum:gdb.base/scope.exp: print funclocal at bar FAIL -> PASS: default/gdb.sum:gdb.base/scope.exp: print funclocal_bss a= t bar FAIL -> PASS: default/gdb.sum:gdb.base/skip.exp: step after deleting 1 = (3) FAIL -> PASS: default/gdb.sum:gdb.base/skip.exp: step after disabling 3= (5) FAIL -> PASS: default/gdb.sum:gdb.base/skip.exp: step after enable 3 (3) FAIL -> PASS: default/gdb.sum:gdb.base/step-resume-infcall.exp: step FAIL -> PASS: default/gdb.sum:gdb.base/step-test.exp: step into FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 1 structs-tc FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 1 structs-td FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 1 structs-tf FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 1 structs-ti FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 1 structs-tl FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 1 structs-tld FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 1 structs-tll FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 1 structs-ts FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 2 structs-tc-ti FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 2 structs-tc-tl FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 2 structs-tf FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 2 structs-tf-tc FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 2 structs-ti FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 2 structs-ti-tc FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 2 structs-tl FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or finish; return 2 structs-tl-tc FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 1 structs-tc FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 1 structs-td FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 1 structs-tf FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 1 structs-ti FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 1 structs-tl FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 1 structs-tld FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 1 structs-tll FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 1 structs-ts FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 2 structs-tc-ti FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 2 structs-tc-tl FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 2 structs-tf FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 2 structs-tf-tc FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 2 structs-ti FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 2 structs-ti-tc FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 2 structs-tl FAIL -> PASS: default/gdb.sum:gdb.base/structs.exp: advance to fun f= or return; return 2 structs-tl-tc FAIL -> PASS: default/gdb.sum:gdb.base/value-double-free.exp: continue FAIL -> PASS: default/gdb.sum:gdb.base/watch-cond-infcall.exp: sw: cont= inue FAIL -> PASS: default/gdb.sum:gdb.base/watchpoints.exp: Watchpoint hit = count is 2 FAIL -> PASS: default/gdb.sum:gdb.base/watchpoints.exp: Watchpoint hit = count is 3 FAIL -> PASS: default/gdb.sum:gdb.base/watchpoints.exp: Watchpoint hit = count is 4 FAIL -> PASS: default/gdb.sum:gdb.base/watchpoints.exp: Watchpoint hit = count is 5 FAIL -> PASS: default/gdb.sum:gdb.base/watchpoints.exp: Watchpoint ival= 1 hit count is 2 FAIL -> PASS: default/gdb.sum:gdb.base/watchpoints.exp: Watchpoint ival= 1 hit count is 3 FAIL -> PASS: default/gdb.sum:gdb.base/watchpoints.exp: watchpoint hit,= fifth time FAIL -> PASS: default/gdb.sum:gdb.base/watchpoints.exp: watchpoint hit,= fourth time FAIL -> PASS: default/gdb.sum:gdb.base/watchpoints.exp: watchpoint hit,= second time FAIL -> PASS: default/gdb.sum:gdb.base/watchpoints.exp: watchpoint hit,= third time FAIL -> PASS: default/gdb.sum:gdb.base/watchpoints.exp: watchpoint ival= 1 hit, second time FAIL -> PASS: default/gdb.sum:gdb.base/watchpoints.exp: watchpoint ival= 1 hit, third time FAIL -> PASS: default/gdb.sum:gdb.cp/expand-sals.exp: continue to break= point: func FAIL -> PASS: default/gdb.sum:gdb.cp/expand-sals.exp: continue to break= point: next caller func FAIL -> PASS: default/gdb.sum:gdb.cp/extern-c.exp: continue to breakpoi= nt: c_func FAIL -> PASS: default/gdb.sum:gdb.cp/extern-c.exp: continue to breakpoi= nt: c_funcs_1 FAIL -> PASS: default/gdb.sum:gdb.cp/extern-c.exp: continue to breakpoi= nt: c_funcs_2 FAIL -> PASS: default/gdb.sum:gdb.cp/namespace-nested-import.exp: print= C::x FAIL -> PASS: default/gdb.sum:gdb.linespec/linespec.exp: set breakpoint= at lspec.cc instance of NameSpace::overload FAIL -> PASS: default/gdb.sum:gdb.linespec/linespec.exp: set breakpoint= at specific instance of NameSpace::overload Removed FAIL: default/gdb.sum:gdb.base/chng-syms.exp: continue until ex= it at breakpoint first time through (the program is no longer running) Removed FAIL: default/gdb.sum:gdb.base/chng-syms.exp: running to stop_h= ere first time The patch is modeled after what most of all other targets are doing for getting past the prologue (if there is one), and have been changed accordingly before, such as in Git commits 93afe5e97284a3d460c19f72f096c4f561673e48, 42294ab40a733dbca9258929d0a6ec72e3059fbc, 5c176a3a457b50fb047477d5e32bdde5ca2dd267, for example. Probably the very same patch should be applied to sh64-tdep.c, but I don't have any possibility for testing that. Shall I to do that change ``blindly''? 2012-02-15 Thomas Schwinge * sh-tdep.c (sh_skip_prologue): Use skip_prologue_using_sal. (after_prologue): Remove. Index: gdb/sh-tdep.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/sh-tdep.c,v retrieving revision 1.236 diff -u -p -r1.236 sh-tdep.c --- gdb/sh-tdep.c 28 Jan 2012 18:08:20 -0000 1.236 +++ gdb/sh-tdep.c 15 Feb 2012 13:08:39 -0000 @@ -697,50 +697,25 @@ sh_analyze_prologue (struct gdbarch *gdb } =20 /* Skip any prologue before the guts of a function. */ - -/* Skip the prologue using the debug information. If this fails we'll - fall back on the 'guess' method below. */ -static CORE_ADDR -after_prologue (CORE_ADDR pc) -{ - struct symtab_and_line sal; - CORE_ADDR func_addr, func_end; - - /* If we can not find the symbol in the partial symbol table, then - there is no hope we can determine the function's start address - with this code. */ - if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end)) - return 0; - - /* Get the line associated with FUNC_ADDR. */ - sal =3D find_pc_line (func_addr, 0); - - /* There are only two cases to consider. First, the end of the source l= ine - is within the function bounds. In that case we return the end of the - source line. Second is the end of the source line extends beyond the - bounds of the current function. We need to use the slow code to - examine instructions in that case. */ - if (sal.end < func_end) - return sal.end; - else - return 0; -} - static CORE_ADDR sh_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) { - CORE_ADDR pc; + CORE_ADDR pc, func_addr; struct sh_frame_cache cache; =20 /* See if we can determine the end of the prologue via the symbol table. If so, then return either PC, or the PC after the prologue, whichever is greater. */ - pc =3D after_prologue (start_pc); + if (find_pc_partial_function (start_pc, NULL, &func_addr, NULL)) + { + CORE_ADDR post_prologue_pc + =3D skip_prologue_using_sal (gdbarch, func_addr); + if (post_prologue_pc !=3D 0) + return max (start_pc, post_prologue_pc); + } =20 - /* If after_prologue returned a useful address, then use it. Else - fall back on the instruction skipping code. */ - if (pc) - return max (pc, start_pc); + /* Can't determine prologue from the symbol table, need to examine + instructions. */ =20 cache.sp_offset =3D -4; pc =3D sh_analyze_prologue (gdbarch, start_pc, (CORE_ADDR) -1, &cache, 0= ); Gr=C3=BC=C3=9Fe, Thomas --=-=-= Content-Type: application/pgp-signature Content-length: 489 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAEBAgAGBQJPO7hkAAoJENuKOtuXzphJXKgH/2OdoTJmJE+q1hx/08ydTXfK G1vmCyTnkvGIt7ay5A4wiHuZS8ENXMqI6RCd0f8GY6ndVAj/ptbxSNp7Vi1H6571 f9CngHezEFxTa51QmQCcRLiQMPd0eVTjdXigdi8tIO5kpCzNaxJaOJyrlC9VBAvm t4c6tipdzkpVy1PC8xCt9FvM8/iRT0TgP49q5zIIuMn5g2CAI3AY0NB/RJ9EHZPD 88PgfM/KtqxHVVdn9Qk59wjj5yBNs8eo+TarxS/dNcgJ/Mf2cvH352W+fFQZ7XHQ OGnkJLR70MCA2hycIBwSIfGCa6wb6Qpi7plbGtsHuYLhCAsL+oD3Dxnkh5FYE60= =klN2 -----END PGP SIGNATURE----- --=-=-=--