From patchwork Mon Apr 21 16:16:53 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hui Zhu X-Patchwork-Id: 632 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx23.g.dreamhost.com (mx2.sub5.homie.mail.dreamhost.com [208.113.200.128]) by wilcox.dreamhost.com (Postfix) with ESMTP id 5B8D4360068 for ; Mon, 21 Apr 2014 09:17:02 -0700 (PDT) Received: by homiemail-mx23.g.dreamhost.com (Postfix, from userid 14314964) id 1B03762E0CE24; Mon, 21 Apr 2014 09:17:01 -0700 (PDT) X-Original-To: gdb@patchwork.siddhesh.in Delivered-To: x14314964@homiemail-mx23.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx23.g.dreamhost.com (Postfix) with ESMTPS id B5FC662CDC14D for ; Mon, 21 Apr 2014 09:17:01 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:date:from:mime-version:to:subject :content-type:content-transfer-encoding; q=dns; s=default; b=L3T aWj0hE+F0PrDHyseSkZuAzMIVIoMMqltVtkGFJbIgZOZQyQl+zTxdv//PCWl5/ZY PDDgZnQUOrazjPO+LUTYXkWmzlfqn8257oi25DuuBf+8OpMCIIqwW9usMYwX/+9g 9qkitLUrulRhXK86Po7dNdz7jHW2/lo1bks/Dp6o= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:date:from:mime-version:to:subject :content-type:content-transfer-encoding; s=default; bh=8dI355FNz lO/t3dJQlLEM5QuLLI=; b=L757q40sOmXUJkMeEGmamIOxWyD4LERCkzWfUlvSn 6Yb1SI8FkWfn1yHzmzvDNVqDYBTOHqlPEenTF28CSpxc/cJxYGgNnCJ7wREHHm6e AhHY+vokr7MN/X7R74mHm/AA9PfO1r1NzH9k+/f9Ov00z9JjRUGXrE6dkoCpqDRC QU= Received: (qmail 14964 invoked by alias); 21 Apr 2014 16:17:00 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 14954 invoked by uid 89); 21 Apr 2014 16:17:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 21 Apr 2014 16:16:58 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1WcGtq-0006I8-Rx from Hui_Zhu@mentor.com for gdb-patches@sourceware.org; Mon, 21 Apr 2014 09:16:54 -0700 Received: from SVR-ORW-FEM-02.mgc.mentorg.com ([147.34.96.206]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Mon, 21 Apr 2014 09:16:54 -0700 Received: from localhost.localdomain (147.34.91.1) by svr-orw-fem-02.mgc.mentorg.com (147.34.96.168) with Microsoft SMTP Server id 14.2.247.3; Mon, 21 Apr 2014 09:16:54 -0700 Message-ID: <53554475.3010201@mentor.com> Date: Tue, 22 Apr 2014 00:16:53 +0800 From: Hui Zhu User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.4.0 MIME-Version: 1.0 To: gdb-patches ml Subject: [PATCH] Fix interrupt.exp fails with m32 in x86_64 X-IsSubscribed: yes X-DH-Original-To: gdb@patchwork.siddhesh.in make check RUNTESTFLAGS="GDB_TESTCASE_OPTIONS=\"-m32\" interrupt.exp" in x86_64 will got some fails: FAIL: gdb.base/interrupt.exp: signal SIGINT (the program is no longer running) FAIL: gdb.base/interrupt.exp: echo more data (timeout) FAIL: gdb.base/interrupt.exp: send end of file The issue can be reproduced: #uname -p x86_64 #gcc -g -m32 gdb.base/interrupt.c #gdb ./a.out (gdb) r Starting program: /home/teawater/gdb/binutils-gdb/gdb/testsuite/a.out talk to me baby data data ^C Program received signal SIGINT, Interrupt. 0xf7ffd430 in __kernel_vsyscall () (gdb) c Continuing. ^C Program received signal SIGINT, Interrupt. 0xf7ffd430 in __kernel_vsyscall () (gdb) p func1() $1 = 4 (gdb) c Continuing. Unknown error 512 [Inferior 1 (process 7953) exited with code 01] nbytes = read (0, &x, 1); if (nbytes < 0) { #ifdef EINTR if (errno != EINTR) #endif After GDB call a function "func1()" by hands, "read" will get errno 512(ERESTARTSYS) that should handled by Linux kernel. The root cause of this issue is: When user use ctrl-c stop the inferior, the signal will be handled in Linux kernel function "do_signal" in arch/x86/kernel/signal.c. The inferior will be stoped by function "ptrace_stop". The call trace is: #0 freezable_schedule () at include/linux/freezer.h:172 #1 ptrace_stop (exit_code=exit_code@entry=5, why=why@entry=262148, clear_code=clear_code@entry=0, info=info@entry=0xffff88001d833e78) at kernel/signal.c:1920 #2 0xffffffff8107ec33 in ptrace_signal (info=0xffff88001d833e78, signr=5) at kernel/signal.c:2157 #3 get_signal_to_deliver (info=info@entry=0xffff88001d833e78, return_ka=return_ka@entry=0xffff88001d833e58, regs=, cookie=cookie@entry=0x0 ) at kernel/signal.c:2269 #4 0xffffffff81013438 in do_signal (regs=regs@entry=0xffff88001d833f58) at arch/x86/kernel/signal.c:696 #5 0xffffffff81013a40 in do_notify_resume (regs=0xffff88001d833f58, unused=, thread_info_flags=4) at arch/x86/kernel/signal.c:747 #6 #7 0x0000000000000000 in irq_stack_union () When GDB "call func1()", to control inferior execute the function func1() and go back to old ip. GDB need set all the registers by GDB function "amd64_collect_native_gregset" that will zero-extend most of 32 bits registers to 64 bits and set to inferior. And execute from ptrace_stop and got back to do_signal. current_thread_info()->status TS_COMPAT will be clean by function "int_with_check" when it return to user space. When GDB "continue", inferior will execute from ptrace_stop and got back to do_signal again. Because this signal interrupt a syscall, go back to function do_signal will use function "syscall_get_error" check if this is a syscall and got error: static inline long syscall_get_error(struct task_struct *task, struct pt_regs *regs) { unsigned long error = regs->ax; #ifdef CONFIG_IA32_EMULATION /* * TS_COMPAT is set for 32-bit syscall entries and then * remains set until we return to user mode. */ if (task_thread_info(task)->status & TS_COMPAT) /* * Sign-extend the value so (int)-EFOO becomes (long)-EFOO * and will match correctly in comparisons. */ error = (long) (int) error; #endif return IS_ERR_VALUE(error) ? error : 0; } Now ax is in 32 bits now, need sign-extend to 64 bits. But current_thread_info()->status TS_COMPAT is cleared when GDB call "call func1()". Linux kernel don't know this is a 32 bits task and will not extend it. Then -ERESTARTSYS is not be handled and go back to user space. Then the syscall "read" get a errno in ERESTARTSYS. I make a patch that let eax sign-extend in function amd64_collect_native_gregset that can handle this issue. It can handle the issue and pass the regression test. Please help me review it. And I make a another patch for Linux kernel that can handle this issue too. I will post it to LKML later. Thanks, Hui 2014-04-21 Hui Zhu * amd64-nat.c(amd64_collect_native_gregset): Make %eax sign-extended. } @@ -156,7 +158,24 @@ amd64_collect_native_gregset (const stru int offset = amd64_native_gregset_reg_offset (gdbarch, i); if (offset != -1) - regcache_raw_collect (regcache, i, regs + offset); + { + if (i == I386_EAX_REGNUM + && gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32) + { + /* Make sure %eax get sign-extended to 64 bits. */ + LONGEST val; + + regcache_raw_collect (regcache, I386_EAX_REGNUM, + regs + offset); + val = extract_signed_integer ((gdb_byte *)(regs + offset), + 4, + gdbarch_byte_order (gdbarch)); + store_signed_integer ((gdb_byte *)(regs + offset), 8, + gdbarch_byte_order (gdbarch), val); + } + else + regcache_raw_collect (regcache, i, regs + offset); + } } } } --- a/gdb/amd64-nat.c +++ b/gdb/amd64-nat.c @@ -131,10 +131,12 @@ amd64_collect_native_gregset (const stru { num_regs = amd64_native_gregset32_num_regs; - /* Make sure %eax, %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp and + /* Make sure %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp and %eip get zero-extended to 64 bits. */ for (i = 0; i <= I386_EIP_REGNUM; i++) { + if (i == I386_EAX_REGNUM) + continue; if (regnum == -1 || regnum == i) memset (regs + amd64_native_gregset_reg_offset (gdbarch, i), 0, 8);