From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6937 invoked by alias); 12 Dec 2006 15:50:37 -0000 Received: (qmail 6790 invoked by uid 22791); 12 Dec 2006 15:50:34 -0000 X-Spam-Check-By: sourceware.org Received: from 195.22.55.53.adsl.nextra.cz (HELO host0.dyn.jankratochvil.net) (195.22.55.53) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 12 Dec 2006 15:50:27 +0000 Received: from host0.dyn.jankratochvil.net (localhost [127.0.0.1]) by host0.dyn.jankratochvil.net (8.13.8/8.13.8) with ESMTP id kBCFnwch022065; Tue, 12 Dec 2006 16:49:58 +0100 Received: (from jkratoch@localhost) by host0.dyn.jankratochvil.net (8.13.8/8.13.8/Submit) id kBCFnw6G022064; Tue, 12 Dec 2006 16:49:58 +0100 Date: Tue, 12 Dec 2006 15:50:00 -0000 From: Jan Kratochvil To: Andrew Haley Cc: Ulrich Drepper , Mark Kettenis , gcc@gcc.gnu.org, libc-alpha@sources.redhat.com, gdb@sourceware.org, Jakub Jelinek , Richard Henderson Subject: Re: Unwinding CFI gcc practice of assumed `same value' regs Message-ID: <20061212154958.GA20103@host0.dyn.jankratochvil.net> References: <20061211190300.GA4372@host0.dyn.jankratochvil.net> <17790.46246.634400.638852@zebedee.pink> <22844.82.92.89.47.1165935102.squirrel@webmail.xs4all.nl> <17790.50417.668957.495292@zebedee.pink> <457EC8BF.3040707@redhat.com> <17790.51754.814267.773596@zebedee.pink> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="EVF5PPMfhYS0aIcm" Content-Disposition: inline In-Reply-To: <17790.51754.814267.773596@zebedee.pink> User-Agent: Mutt/1.4.2.2i X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2006-12/txt/msg00099.txt.bz2 --EVF5PPMfhYS0aIcm Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 2866 On Tue, 12 Dec 2006 16:26:34 +0100, Andrew Haley wrote: ... > It's certainly an inconsistency in the specification, which says that > null-termination is supported, and this implies that you can't put a zero in > there. I tested now that you can put the zero there for both the libgcc unwinder and for gdb(1) [tested only Fedora Core gdb-6.5-13.fc6], attached, on x86_64 compile [gcc-4.1.1-30] and run by: gcc -o fp0-x86_64 -O9 -fomit-frame-pointer -Wall fp0-x86_64.c -ggdb3; ./fp0-x86_64 The output provided at the end of this mail. Therefore I believe this sentence is wrong and it should be removed: http://www.x86-64.org/documentation/abi.pdf (draft 0.98) Page 28 (29/124) %rbp ... but the user code should mark the deepest stack frame by %setting the frame pointer to zero. On the other hand the right stack terminator for libgcc unwinder is `PC == 0': unwind-dw2.c:uw_frame_state_for (): if (context->ra == 0) return _URC_END_OF_STACK; And gdb should just get updated to behave the same way. libunwind already assumed end of stack on `PC == 0' before and I do not expect any platform would consider `PC == 0' as a valid _return_address_ (which is usually several bytes after any starting function address due to the call instruction). ... > "All of these" might be the right way to go. That is, keep > null-terminating the stack, strengthen the rules about what you might > do with %ebp, and extend debuginfo. For best compatibility null terminate the stack but by CFI and its indicated return address. Do not use %rbp (frame pointer register) in any way (regarding the stack termination condition). Believe only CFI-specified CFA address, unrelated to %rbp content. Regards, Jan ------------------------------------------------------------------------------ GNU gdb Red Hat Linux (6.5-13.fc6rh) This GDB was configured as "x86_64-redhat-linux-gnu"...Using host libthread_db library "/lib64/libthread_db.so.1". (gdb) b 12 Breakpoint 1 at 0x40060b: file fp0-x86_64.c, line 12. (gdb) r Starting program: /root/jkratoch/redhat/unwind/fp0-x86_64 Breakpoint 1, backtracer () at fp0-x86_64.c:12 12 int i = backtrace (buf, 512); (gdb) bt #0 backtracer () at fp0-x86_64.c:12 #1 0x0000000000400739 in badone () at fp0-x86_64.c:31 #2 0x000000000040074e in main () at fp0-x86_64.c:47 (gdb) p/x $rbp $1 = 0x7fff6ed61ca0 (gdb) up #1 0x0000000000400739 in badone () at fp0-x86_64.c:31 31 backtracer (); (gdb) p/x $rbp $2 = 0x0 (gdb) c Continuing. dummy 5 /root/jkratoch/redhat/unwind/fp0-x86_64[0x40062c] /root/jkratoch/redhat/unwind/fp0-x86_64[0x400739] /root/jkratoch/redhat/unwind/fp0-x86_64[0x40074e] /lib64/libc.so.6(__libc_start_main+0xf4)[0x301e81da44] /root/jkratoch/redhat/unwind/fp0-x86_64[0x400559] Program received signal SIGSEGV, Segmentation fault. 0x0000000000400684 in backtracer () at fp0-x86_64.c:21 21 RAFA(1); (gdb) q --EVF5PPMfhYS0aIcm Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="fp0-x86_64.c" Content-length: 842 #include #include #include #include static void backtracer (void) __attribute__((__noinline__)); static void backtracer (void) { void *buf[512]; puts("dummy"); int i = backtrace (buf, 512); printf ("%d\n", i); fflush (stdout); backtrace_symbols_fd (buf, i, STDOUT_FILENO); #define RAFA(level) \ printf("RA (%d) = %p, FA (%d) = %p\n", \ level, __builtin_return_address (level), \ level, __builtin_frame_address (level)) RAFA(0); RAFA(1); RAFA(2); RAFA(3); RAFA(4); RAFA(5); } static int badone (void) __attribute__((__noinline__)); static int badone (void) { backtracer (); return 0; } asm( " .text \n" "clearstack: \n" " pushq $0 \n" " popq %rax \n" " ret \n" ); extern void clearstack(void); int main (void) { clearstack (); badone (); return 0; } --EVF5PPMfhYS0aIcm--