From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 121346 invoked by alias); 3 Aug 2016 14:21:56 -0000 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 Received: (qmail 121333 invoked by uid 89); 3 Aug 2016 14:21:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.1 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=Originally, our X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 03 Aug 2016 14:21:53 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 31887C056800; Wed, 3 Aug 2016 14:21:52 +0000 (UTC) Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u73ELoPA011414; Wed, 3 Aug 2016 10:21:50 -0400 Subject: Re: [PATCH master/7.12] Throw error when ptrace fail in regsets_fetch_inferior_registers To: Yao Qi , gdb-patches@sourceware.org References: <1470230379-6790-1-git-send-email-yao.qi@linaro.org> From: Pedro Alves Message-ID: Date: Wed, 03 Aug 2016 14:21:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.1.1 MIME-Version: 1.0 In-Reply-To: <1470230379-6790-1-git-send-email-yao.qi@linaro.org> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-SW-Source: 2016-08/txt/msg00057.txt.bz2 On 08/03/2016 02:19 PM, Yao Qi wrote: > When I run process-dies-while-detaching.exp with GDBserver, I see many > warnings printed by GDBserver, > > ptrace(regsets_fetch_inferior_registers) PID=26183: No such process > ptrace(regsets_fetch_inferior_registers) PID=26183: No such process > ptrace(regsets_fetch_inferior_registers) PID=26184: No such process > ptrace(regsets_fetch_inferior_registers) PID=26184: No such process > > regsets_fetch_inferior_registers is called when GDBserver resumes each > lwp. > > #2 0x0000000000428260 in regsets_fetch_inferior_registers (regsets_info=0x4690d0 , regcache=0x31832020) > at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:5412 > #3 0x00000000004070e8 in get_thread_regcache (thread=0x31832940, fetch=fetch@entry=1) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/regcache.c:58 > #4 0x0000000000429c40 in linux_resume_one_lwp_throw (info=, signal=0, step=0, lwp=0x31832830) > at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4463 > #5 linux_resume_one_lwp (lwp=0x31832830, step=, signal=, info=) > at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4573 > > The is the case that threads are disappeared when GDB/GDBserver resumes > them. Our fix nowadays is to throw exception, caller > linux_resume_one_lwp catches the exception, and swallow it if the lwp > is gone. See linux-low.c:linux_resume_one_lwp. So this patch fixes > the problem by throwing exception in regsets_fetch_inferior_registers. > Another caller of regsets_fetch_inferior_registers, linux_fetch_registers, > needs to catch the exception the same way as linux_resume_one_lwp does. > Throwing is useful when the exception needs to cross several layers. Originally that was added because the exceptions had to cross through multiple layers, including inf-ptrace.c and the regcache. In cases where we have the ptrace errno code at hand, we can simply check for ESRCH. That is, in fact what regsets_store_inferior_registers does. else if (errno == ESRCH) { /* At this point, ESRCH should mean the process is already gone, in which case we simply ignore attempts to change its registers. See also the related comment in linux_resume_one_lwp. */ free (buf); return 0; } (store_register checks ESRCH too instead of throwing, as well as linux_detach_one_lwp and attach_proc_task_lwp_callback.) However, I don't think swallowing a register/write error is always the best to do. If we're resuming the program, then yes, we should swallow the error, because now that the thread is resumed, we'll collect the exit status shortly. But if the thread is _not_ resumed, the user has the now-dead thread selected, and does "info registers" or "p $somereg = 0xf00" -- then I think we should report back the error all the way back to the user, not swallow it and display random garbage for register contents, or pretend the write succeeded. So if we go the throw route, I think the catch should be somewhere higher level, in the code that is reading/writing registers because it is resuming the thread. See how linux-nat.c:resume_stopped_resumed_lwps's TRY block encloses more than one call that might throw. It may be that in this case the register read is coming from gdb directly (really no idea), which would mean that it's gdb that would have to ignore the error, which would complicate things. But until that is gone, I see no reason to prefer a throw/catch instead of simply checking for ESRCH, mirroring regsets_store_inferior_registers? Thanks, Pedro Alves