From patchwork Fri May 15 15:58:23 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Brobecker X-Patchwork-Id: 6745 Received: (qmail 89778 invoked by alias); 15 May 2015 15:58:24 -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 89769 invoked by uid 89); 15 May 2015 15:58:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY autolearn=no version=3.3.2 X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Fri, 15 May 2015 15:58:22 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 0E82328A10; Fri, 15 May 2015 11:58:20 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id OQ-gNJvsrgil; Fri, 15 May 2015 11:58:19 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id C5826D3F6A; Fri, 15 May 2015 11:58:19 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id 4452F40DAA; Fri, 15 May 2015 08:58:23 -0700 (PDT) Date: Fri, 15 May 2015 08:58:23 -0700 From: Joel Brobecker To: Pedro Alves Cc: gdb-patches@sourceware.org, Jerome Guitton Subject: Re: [RFA/commit] Memory leak in on reading frame register Message-ID: <20150515155823.GL4767@adacore.com> References: <1431100524-7793-1-git-send-email-brobecker@adacore.com> <55508A83.3060605@redhat.com> <20150511205312.GE4767@adacore.com> <5551CB20.4090104@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <5551CB20.4090104@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) > >> Not sure about this. > >> > >> How come this in bpstat_check_breakpoint_conditions didn't > >> handle this issue already? : > >> > >> ... > >> /* We use value_mark and value_free_to_mark because it could > >> be a long time before we return to the command level and > >> call free_all_values. We can't call free_all_values > >> because we might be in the middle of evaluating a > >> function call. */ > >> struct value *mark = value_mark (); > >> > >> ... > >> value_free_to_mark (mark); > > > > An excellent question, which I will try to research in the next > > couple of days! > > Thanks. I wonder whether the leaks come from constructing the > current frame at each stop, instead of from evaluating > breakpoint conditions. E.g.., if we do a "step" over: > > while (1); > > ... are we constantly leaking values until the user does > ctrl-c? > > That would suggest to me to that we should be doing > value_mark/value_free_to_mark around each > handle_inferior_event. A very accurate guess, as it turns out. Condition evaluation is not the problem, here, but indeed, we a couple of calls to handle_inferior in addition to each call to bpstat_check_breakpoint_conditions. The former are responsible for the leak. How about the attached patch? gdb/ChangeLog: * infrun.c (handle_inferior_event_1): Renames handle_inferior_event. (handle_inferior_event): New function. Tested on x86_64-linux. No regression. Thanks! From 3d2f2a3967c143ba4c0c0c6c731bffd9a2cb726f Mon Sep 17 00:00:00 2001 From: Joel Brobecker Date: Fri, 13 Feb 2015 11:57:29 +0100 Subject: [PATCH] Memory leak reading frame register during inferior event handling When using a conditional breakpoint where the condition evaluated to false a large number of times before the program stopped, a user reported that GDB's memory consumption was growing very quickly until it ran out of memory. The problem was tracked down to temporary struct values being created each time the program stops and handles an inferior event. Because the breakpoint condition usually evaluates to false, there can be a fairly large number of such events to be handled before we eventually return the prompt to the user (which is when we would normally purge such values). This patch fixes the issue by making sure that handle_inferior_event releases all new values created during its execution. gdb/ChangeLog: * infrun.c (handle_inferior_event_1): Renames handle_inferior_event. (handle_inferior_event): New function. --- gdb/infrun.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/gdb/infrun.c b/gdb/infrun.c index 71cf208..96cddbd 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3680,7 +3680,7 @@ get_inferior_stop_soon (ptid_t ptid) once). */ static void -handle_inferior_event (struct execution_control_state *ecs) +handle_inferior_event_1 (struct execution_control_state *ecs) { enum stop_kind stop_soon; @@ -4202,6 +4202,23 @@ Cannot fill $_exitsignal with the correct signal number.\n")); } } +/* A wrapper around handle_inferior_event_1, which also makes sure + that all temporary struct value objects that were created during + the handling of the event get deleted at the end. */ + +static void +handle_inferior_event (struct execution_control_state *ecs) +{ + struct value *mark = value_mark (); + + handle_inferior_event_1 (ecs); + /* Purge all temporary values created during the event handling, + as it could be a long time before we return to the command level + where such values would otherwise be purged. */ + value_free_to_mark (mark); +} + + /* Come here when the program has stopped with a signal. */ static void -- 1.9.1