From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7525 invoked by alias); 28 Dec 2011 18:02:39 -0000 Received: (qmail 7514 invoked by uid 22791); 28 Dec 2011 18:02:37 -0000 X-SWARE-Spam-Status: No, hits=-7.3 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 28 Dec 2011 18:02:17 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id pBSI1tCC022323 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 28 Dec 2011 13:01:55 -0500 Received: from host2.jankratochvil.net (ovpn-116-32.ams2.redhat.com [10.36.116.32]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id pBSI1mQ0029791 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Wed, 28 Dec 2011 13:01:51 -0500 Date: Wed, 28 Dec 2011 18:47:00 -0000 From: Jan Kratochvil To: gdb-patches@sourceware.org Cc: Joel Brobecker Subject: [patch] Fix gdb.cp/gdb2495.exp regression with gcc-4.7 #2 Message-ID: <20111228180148.GA18057@host2.jankratochvil.net> References: <20111222202047.GA16110@host2.jankratochvil.net> <20111227045606.GE23376@adacore.com> <20111228161208.GB10556@host2.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20111228161208.GB10556@host2.jankratochvil.net> User-Agent: Mutt/1.5.21 (2010-09-15) 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: 2011-12/txt/msg00877.txt.bz2 On Wed, 28 Dec 2011 17:12:08 +0100, Jan Kratochvil wrote: > I will yet try to adjust it somehow. This one may work. displaced_step_at_entry_point has been already assuming after gdbarch_breakpoint_from_pc (gdbarch, &addr, &bp_len); addr += bp_len * 2; ADDR can be used as an executable instruction address. Therefore the gdb_buffered_insn_length adjustment was possibly needlessly strong (and needlessly expensive). Expecting _start is at least as long as 2 * BP_LEN looks definitely valid and on archs supporting displaced stepping the assumption of _start length 3 * BP_LEN + gdbarch_max_insn_length looks also safe (also these archs have properly set gdbarch_max_insn_length which is therefore small enough). I am not convinced it works on each arch but it works at least on something so special like ia64 so it really may work everywhere. Displaced stepping is not implemented on each arch so the displaced_step_at_entry_point does not prove it works on every arch. While this proposed code applies to (almost - AT_ENTRY_POINT) any arch, so there is still a regression risk. No regressions on {x86_64,x86_64-m32,i686}-fedorarawhide-linux-gnu. Thanks, Jan 2011-12-28 Jan Kratochvil Fix regression for gdb.cp/gdb2495.exp with gcc-4.7. * arch-utils.c (displaced_step_at_entry_point): Incrase BP_LEN skip to 3 times. * infcall.c (call_function_by_hand) : New comment on stack executability. (call_function_by_hand) : Drop comment on ON_STACK preference. Move it upwards and fall through into AT_ENTRY_POINT. (call_function_by_hand) : New variable bp_len. Adjust DUMMY_ADDR with it. * ppc-linux-tdep.c (ppc_linux_displaced_step_location): Increase PPC_INSN_SIZE skip to 3 times. --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -86,7 +86,7 @@ displaced_step_at_entry_point (struct gdbarch *gdbarch) We don't want displaced stepping to interfere with those breakpoints, so leave space. */ gdbarch_breakpoint_from_pc (gdbarch, &addr, &bp_len); - addr += bp_len * 2; + addr += bp_len * 3; return addr; } --- a/gdb/infcall.c +++ b/gdb/infcall.c @@ -627,26 +628,16 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) switch (gdbarch_call_dummy_location (gdbarch)) { case ON_STACK: + /* ON_STACK has problems on some targets featuring security policies + disabling target stack executability. */ sp = push_dummy_code (gdbarch, sp, funaddr, args, nargs, target_values_type, &real_pc, &bp_addr, get_current_regcache ()); break; - case AT_ENTRY_POINT: - { - CORE_ADDR dummy_addr; - - real_pc = funaddr; - dummy_addr = entry_point_address (); - /* A call dummy always consists of just a single breakpoint, so - its address is the same as the address of the dummy. */ - bp_addr = dummy_addr; - break; - } case AT_SYMBOL: /* Some executables define a symbol __CALL_DUMMY_ADDRESS whose address is the location where the breakpoint should be - placed. Once all targets are using the overhauled frame code - this can be deleted - ON_STACK is a better option. */ + placed. */ { struct minimal_symbol *sym; CORE_ADDR dummy_addr; @@ -661,11 +652,41 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) dummy_addr = gdbarch_convert_from_func_ptr_addr (gdbarch, dummy_addr, ¤t_target); + /* A call dummy always consists of just a single breakpoint, + so it's address is the same as the address of the dummy. */ + bp_addr = dummy_addr; + break; } - else - dummy_addr = entry_point_address (); - /* A call dummy always consists of just a single breakpoint, - so it's address is the same as the address of the dummy. */ + break; + } + /* FALLTHROUGH */ + case AT_ENTRY_POINT: + { + CORE_ADDR dummy_addr; + int bp_len; + + real_pc = funaddr; + dummy_addr = entry_point_address (); + + /* If the inferior call throws an uncaught C++ exception, + the inferior unwinder tries to unwind all frames, including + our dummy frame. The unwinder determines the address of + the calling instruction by subtracting 1 to the return + address. So, using the entry point's address as the return + address would lead the unwinder to use the unwinding + information of the code immediately preceding the entry + point. This information, if found, is invalid for the dummy + frame, and can potentially crash the inferior's unwinder. + Therefore, we use the second byte (approximately, + alignments depending on GDBARCH). It does not matter if it + is placed inside the very first instruction, nothing tries + to execute it. */ + + gdbarch_breakpoint_from_pc (gdbarch, &dummy_addr, &bp_len); + dummy_addr += bp_len; + + /* A call dummy always consists of just a single breakpoint, so + its address is the same as the address of the dummy. */ bp_addr = dummy_addr; break; } --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -1075,7 +1075,7 @@ ppc_linux_displaced_step_location (struct gdbarch *gdbarch) /* Inferior calls also use the entry point as a breakpoint location. We don't want displaced stepping to interfere with those breakpoints, so leave space. */ - ppc_linux_entry_point_addr = addr + 2 * PPC_INSN_SIZE; + ppc_linux_entry_point_addr = addr + 3 * PPC_INSN_SIZE; } return ppc_linux_entry_point_addr;