From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4411 invoked by alias); 30 Nov 2007 22:53:48 -0000 Received: (qmail 4402 invoked by uid 22791); 30 Nov 2007 22:53:47 -0000 X-Spam-Check-By: sourceware.org Received: from bluesmobile.specifix.com (HELO bluesmobile.specifix.com) (216.129.118.140) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 30 Nov 2007 22:53:43 +0000 Received: from [127.0.0.1] (bluesmobile.specifix.com [216.129.118.140]) by bluesmobile.specifix.com (Postfix) with ESMTP id 783643C35B for ; Fri, 30 Nov 2007 14:53:41 -0800 (PST) Subject: RFA: Fix check for no-saved-pc From: Michael Snyder To: gdb-patches@sourceware.org Content-Type: text/plain Date: Fri, 30 Nov 2007 22:53:00 -0000 Message-Id: <1196462431.2501.164.camel@localhost.localdomain> Mime-Version: 1.0 X-Mailer: Evolution 2.10.3 (2.10.3-4.fc7) Content-Transfer-Encoding: 7bit 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: 2007-11/txt/msg00572.txt.bz2 There's a check in get_prev_frame to see if the next saved pc is zero. I think it has an off-by-one error, and is checking for the pc of the wrong frame. To test this, I took the corefile that's generated by the testsuite (gdb.base/corefile.exp), edited it with khexedit, and nulled out one of the saved return addresses on the stack. This is the gdb output before my change: Core was generated by `gdb/testsuite/gdb.base/coremaker'. Program terminated with signal 6, Aborted. #0 0x40000402 in __kernel_vsyscall () (gdb) bt #0 0x40000402 in __kernel_vsyscall () #1 0x00a7bfa0 in raise () from /lib/libc.so.6 #2 0x00a7d8b1 in abort () from /lib/libc.so.6 #3 0x080486ce in func2 () at gdb/testsuite/gdb.base/coremaker.c:127 #4 0x080486d9 in func1 () at gdb/testsuite/gdb.base/coremaker.c:133 #5 0x00000000 in ?? () (gdb) And this is the output with the attached patch: (gdb) bt #0 0x40000402 in __kernel_vsyscall () #1 0x00a7bfa0 in raise () from /lib/libc.so.6 #2 0x00a7d8b1 in abort () from /lib/libc.so.6 #3 0x080486ce in func2 () at gdb/testsuite/gdb.base/coremaker.c:127 #4 0x080486d9 in func1 () at gdb/testsuite/gdb.base/coremaker.c:133 Backtrace stopped: frame did not save the PC (gdb) No other test suite changes, tests run on native i386 linux. 2007-11-30 Michael Snyder * frame.c (get_prev_frame): Remove unused local variable. (get_prev_frame): Check for null saved pc in the following ("prev") frame, not the current (already valid) frame. Set up stop_reason conditions for printing stop reason. Index: frame.c =================================================================== RCS file: /cvs/src/src/gdb/frame.c,v retrieving revision 1.235 diff -u -p -r1.235 frame.c --- frame.c 2 Nov 2007 14:47:27 -0000 1.235 +++ frame.c 30 Nov 2007 22:48:47 -0000 @@ -1355,8 +1355,6 @@ inside_entry_func (struct frame_info *th struct frame_info * get_prev_frame (struct frame_info *this_frame) { - struct frame_info *prev_frame; - /* Return the inner-most frame, when the caller passes in NULL. */ /* NOTE: cagney/2002-11-09: Not sure how this would happen. The caller should have previously obtained a valid frame using @@ -1469,9 +1467,12 @@ get_prev_frame (struct frame_info *this_ if (this_frame->level > 0 && get_frame_type (this_frame) == NORMAL_FRAME && get_frame_type (get_next_frame (this_frame)) == NORMAL_FRAME - && get_frame_pc (this_frame) == 0) + && frame_pc_unwind (this_frame) == 0) { frame_debug_got_null_frame (gdb_stdlog, this_frame, "zero PC"); + this_frame->stop_reason = UNWIND_NO_SAVED_PC; + this_frame->prev_p = 1; + this_frame->prev = NULL; return NULL; }