From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9244 invoked by alias); 22 Dec 2011 20:21:07 -0000 Received: (qmail 9233 invoked by uid 22791); 22 Dec 2011 20:21:05 -0000 X-SWARE-Spam-Status: No, hits=-7.9 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_EG 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; Thu, 22 Dec 2011 20:20:51 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id pBMKKpWF006990 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 22 Dec 2011 15:20:51 -0500 Received: from host2.jankratochvil.net (ovpn-116-60.ams2.redhat.com [10.36.116.60]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id pBMKKlLU023718 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Thu, 22 Dec 2011 15:20:50 -0500 Date: Thu, 22 Dec 2011 20:49:00 -0000 From: Jan Kratochvil To: gdb-patches@sourceware.org Subject: [patch] Fix gdb.cp/gdb2495.exp regression with gcc-4.7 Message-ID: <20111222202047.GA16110@host2.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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/msg00796.txt.bz2 Hi, (gdb) p exceptions.throw_function() Program received signal SIGSEGV, Segmentation fault. x86_64_fallback_frame_state (fs=0x7fffffffdc80, context=0x7fffffffdef0) at ../../../gcc/config/i386/linux-unwind.h:47 47 if (*(unsigned char *)(pc+0) == 0x48 The program being debugged was signaled while in a function called from GDB. [...] (gdb) FAIL: gdb.cp/gdb2495.exp: Call a function that raises an exception without a handler. This happens with gcc (GCC) 4.7.0 20111222 (experimental) on Fedora Rawhide (pre-17) x86_64 as the function before _start is PLT and PLTs have no proper .eh_frame entries. Still such .eh_frame PLT entry sure does not apply for the frame. Therefore it unwinds into garbage and then crashes on it (PC is 0x1 abo-ve). No regressions on {x86_64,x86_64-m32}-fedora16-linux-gnu. Thanks, Jan gdb/ 2011-12-22 Jan Kratochvil Fix regression for gdb.cp/gdb2495.exp with gcc-4.7. * gdbarch.sh (max_insn_length): Set the default length to 31. * gdbarch.c: Regenerate. * gdbarch.h: Regenerate. * infcall.c: Include disasm.h. (call_function_by_hand) : New variables insn and insn_len. Adjust DUMMY_ADDR with them if possible. --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -655,7 +655,8 @@ v:int:vbit_in_delta:::0:0::0 F:void:skip_permanent_breakpoint:struct regcache *regcache:regcache # The maximum length of an instruction on this architecture. -V:ULONGEST:max_insn_length:::0:0 +# It should be at least as maximum of all the supported architectures. +V:ULONGEST:max_insn_length:::31:31 # Copy the instruction at FROM to TO, and make any adjustments # necessary to single-step it at that address. --- a/gdb/infcall.c +++ b/gdb/infcall.c @@ -38,6 +38,7 @@ #include "ada-lang.h" #include "gdbthread.h" #include "exceptions.h" +#include "disasm.h" /* If we can't find a function's name from its address, we print this instead. */ @@ -634,9 +635,32 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) case AT_ENTRY_POINT: { CORE_ADDR dummy_addr; + gdb_byte *insn; + CORE_ADDR insn_len; real_pc = funaddr; dummy_addr = entry_point_address (); + + /* If the inferior call throws an uncaught C++ exception the inferior + unwinder will try to unwind all the frames incl. the dummy frame. + Using the entry_point_address directly will try to find FDE at the + function right before the entry_point_address address as the + unwinder subtracts 1 to get at the call instruction. FDE of the + preceding function, if found, would be invalid for the dummy frame + and it would crash the inferior's unwinder. Therefore attempt to + skip the very first instruction of entry_point_address. */ + + insn_len = gdbarch_max_insn_length (gdbarch); + insn = alloca (insn_len); + if (target_read_memory (dummy_addr, insn, insn_len) == 0) + dummy_addr += gdb_buffered_insn_length (gdbarch, insn, insn_len, + dummy_addr); + else + { + /* No problem probably occurs without this adjustment. INSN_LEN + may be for example larger than the entry_point_address code. */ + } + /* 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;