From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19223 invoked by alias); 19 Feb 2019 23:44:11 -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 19124 invoked by uid 89); 19 Feb 2019 23:44:10 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=waroquiers, philippewaroquiersskynetbe, philippe.waroquiers@skynet.be, sk:philipp 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 ESMTP; Tue, 19 Feb 2019 23:44:08 +0000 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 92D6E5945B; Tue, 19 Feb 2019 23:44:07 +0000 (UTC) Received: from f29-4.lan (ovpn-117-11.phx2.redhat.com [10.3.117.11]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3EB075DD63; Tue, 19 Feb 2019 23:44:07 +0000 (UTC) Date: Tue, 19 Feb 2019 23:44:00 -0000 From: Kevin Buettner To: gdb-patches@sourceware.org Subject: Re: [RFA] Fix regcache leak, and avoid possible regcache access after detach. Message-ID: <20190219164406.43969e3c@f29-4.lan> In-Reply-To: <20190216205810.1253-1-philippe.waroquiers@skynet.be> References: <20190216205810.1253-1-philippe.waroquiers@skynet.be> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2019-02/txt/msg00318.txt.bz2 On Sat, 16 Feb 2019 21:58:10 +0100 Philippe Waroquiers wrote: > Valgrind reports leaks like the below in various tests, > e.g. gdb.threads/attach-slow-waitpid.exp, gdb.ada/task_switch_in_core.exp, ... > > Fix the leak by clearing the regcache when detaching from an inferior. > Note that these leaks are 'created' when GDB exits, > when the regcache::current_regcache is destroyed : the elements > of the forward_list are pointers, and the 'pointed to' memory is not > deleted by the forward_list destructor. > > Nevertheless, fixing this leak is good as it makes a bunch of > tests 'leak clean'. > > Also, it seems strange to keep a register cache for a process from > which GDB detached : it is not clear if this cache is still valid > after detach. And effectively, when clearing only the regcache, > (and not the frame cache), then the frame cache was still 'pointing' > at this regcache and was used when switching to the child process > in the test gdb.threads/watchpoint-fork.exp, which seems strange. > > So, we solve the leak and avoid possible accesses to the regcache > and frame cache of the detached inferior, by clearing both the > regcache and the frame cache. > > Tested on debian/amd64, natively and under Valgrind. Before committing, could you also test against native-gdbserver? I.e... make check RUNTESTFLAGS="--target_board=native-gdbserver" (I'd like the detach code in remote.c to be exercised as well. I've run into some subtle bugs in this area of remote.c in the past.) My remaining comments consist of a few nits... > diff --git a/gdb/target.c b/gdb/target.c > index 116510e8cb..0f10628590 100644 > --- a/gdb/target.c > +++ b/gdb/target.c > @@ -2010,6 +2010,8 @@ target_preopen (int from_tty) > void > target_detach (inferior *inf, int from_tty) > { > + ptid_t pid_ptid = ptid_t (inf->pid); > + Please move this declaration / initialization to the line just before where it's used. Since it's only used once, you could also just pass ptid_t (inf->pid) directly to registers_changed_ptid() and get rid of the declaration entirely. > /* As long as some to_detach implementations rely on the current_inferior > (either directly, or indirectly, like through target_gdbarch or by > reading memory), INF needs to be the current inferior. When that > @@ -2029,6 +2031,15 @@ target_detach (inferior *inf, int from_tty) > prepare_for_detach (); > > current_top_target ()->detach (inf, from_tty); > + > + /* After we have detached, clear the register cache for this inferior. */ > + registers_changed_ptid (pid_ptid); > + > + /* We have to ensure we have no frame cached left. Normally, s/cached/cache/ > + registers_changed_ptid (pid_ptid) calls reinit_frame_cache when > + inferior_ptid matches pid_ptid, but in our case, it does not > + call it, as inferior_pid has been reset. */ s/inferior_pid/inferior_ptid/ Thanks for that comment though; I was wondering why reinit_frame_cache needed to be called. > + reinit_frame_cache (); > } Okay with those changes, assuming that all goes well with the native-gdbserver testing.