From patchwork Thu Apr 16 02:29:27 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2165 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1776306648; bh=logOrtoBPIQSI3H7TxlFheGoeSotFWIF0MvNN8igH0c=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=YyrjxHE0+ZtWtFdj4r2ii1Ceimd0Y5JBs+WRtLRH1LTDA89MtbbSrbCS4zb0Sv9Sv KZihekc/+KO6/A5qElqLJ0YvTyWOTGjfsdalEkm0dwDYEnoqVaqmvtCZuMNcP/1l9l RXQbIvDQO4+wxlODzhbX014rKjituDzOV0unRDVI= Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 2C9D76A4AD for ; Wed, 15 Apr 2026 20:30:48 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id LfcVlZ6WnTok for ; Wed, 15 Apr 2026 20:30:48 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1776306647; bh=logOrtoBPIQSI3H7TxlFheGoeSotFWIF0MvNN8igH0c=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=Ln5QFdWS2cvgPiVsPtPF5qBfefArA9MYpm4G3ztQV1XxJk/o5IgVjy2ZCQpO5dg0U QdMYRsSqQVcrU93yOTA8nQS15dgwdy9hFCQzseW2G9E+39ikpy6HGypvPaHZlh3SPf o6ZSgpGBJxpAaV764GP/F1S22k1Kmc8c+2tJwATU= Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 312056A4A5 for ; Wed, 15 Apr 2026 20:30:47 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1776306645; bh=Uj/K2UQgxwveTO+QAal02FuDb0r6y3yGubcNC3FjrQs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qiORdAGVkf+wWPuJbTki4NHhVDyi1L1GyS2mneZefs6VgEoorpr1r5OsCg2+jVlR+ ELo1wsVgod516jInCEKBBhmCqUl/ENmpMmqcTUMMftVK5wlTMRQ/uQMEGQHoZxdWnA DqXp2ihxGYM+L6t63Ed5S2S6nD2PsDDdA04cqwEA= Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 16C1A6A49F; Wed, 15 Apr 2026 20:30:45 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id kajKKhTnAE1B; Wed, 15 Apr 2026 20:30:45 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1776306644; bh=qkguO0/qr/9ZIiw99jumfjpZHVv78d7aw5Re50+VTDY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Nl2bhUHkmb3bVr8eIpfPRWfkMErv1aWW/sH1LXQz8U9gL/veGMjbQiEAwZFomOXDw driOmKbtf5vPxeEaGS1lGzVQ0BEg/0v/jRBax2IAOrr+f8K3qW2oAE6Z1UCagipzFT 4m9kjrCjWB+/BuIQiypTkrCGSD5mnR11ZjRfvXpc= Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 824E96A44C; Wed, 15 Apr 2026 20:30:44 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Wed, 15 Apr 2026 20:29:27 -0600 Message-ID: <20260416023021.626949-3-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260416023021.626949-1-sjg@u-boot.org> References: <20260416023021.626949-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: 44KYGYE7TULWNOYSRJFNFAVX4OHUJMIJ X-Message-ID-Hash: 44KYGYE7TULWNOYSRJFNFAVX4OHUJMIJ X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 02/33] malloc: Expose registry-overflow state to tests List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass If the mcheck registry ever overflows, later allocations are not recorded so find_mcheck_hdr_in_chunk() cannot find their headers. Leak reports then print an empty caller column, and cmd_test_malloc_leak() fails with a confusing assertion where the expected output shows a function name and the actual output shows trailing whitespace. The 'registry overflow' printf() that marks this state is printed once and goes to the silenced test console, which makes the condition hard to notice. Promote the one-shot overflow flag to file scope expose it via a new malloc_mcheck_overflow() function. Check it at the top of cmd_test_malloc_leak() so any earlier test that exhausts the registry now produces a direct failure in the leak test rather than a misleading one based on missing caller strings. Signed-off-by: Simon Glass --- common/dlmalloc.c | 5 +++++ common/mcheck_core.inc.h | 6 +++--- include/malloc.h | 16 ++++++++++++++++ test/cmd/malloc.c | 6 ++++++ 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/common/dlmalloc.c b/common/dlmalloc.c index f05d7ae83c5..ae1e6d27d08 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -6010,6 +6010,11 @@ bool malloc_backtrace_is_active(bool *skipp, bool *busyp) #endif } +bool malloc_mcheck_overflow(void) +{ + return mcheck_registry_full; +} + static const char *mcheck_caller(void) { #if CONFIG_IS_ENABLED(MCHECK_BACKTRACE) diff --git a/common/mcheck_core.inc.h b/common/mcheck_core.inc.h index 968b058ba6d..9f13945cde8 100644 --- a/common/mcheck_core.inc.h +++ b/common/mcheck_core.inc.h @@ -79,6 +79,7 @@ static char mcheck_pedantic_flag __section(".data") = 0; static void *mcheck_registry[REGISTRY_SZ] __section(".data") = {0}; static size_t mcheck_chunk_count __section(".data") = 0; static size_t mcheck_chunk_count_max __section(".data") = 0; +static bool mcheck_registry_full __section(".data"); typedef unsigned long long mcheck_elem; typedef struct { @@ -200,7 +201,6 @@ static void *mcheck_allocated_helper(void *altoghether_ptr, size_t customer_sz, size_t alignment, int clean_content, const char *caller) { - static bool overflow_msg_shown; const size_t slop = alignment ? mcheck_evaluate_memalign_prefix_size(alignment) - sizeof(struct mcheck_hdr) : 0; struct mcheck_hdr *hdr = (struct mcheck_hdr *)((char *)altoghether_ptr + slop); @@ -239,8 +239,8 @@ static void *mcheck_allocated_helper(void *altoghether_ptr, size_t customer_sz, return payload; // normal end } - if (!overflow_msg_shown) { - overflow_msg_shown = true; + if (!mcheck_registry_full) { + mcheck_registry_full = true; printf("\n\nERROR: mcheck registry overflow, pedantic check would be incomplete!\n\n"); } return payload; diff --git a/include/malloc.h b/include/malloc.h index 05d4c06fb89..0a780fc03c3 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -863,6 +863,22 @@ static inline bool malloc_backtrace_is_active(bool *skipp, bool *busyp) } #endif +/** + * malloc_mcheck_overflow() - Check whether the mcheck registry filled + * + * The mcheck code registers each allocation's header in a fixed-size array so + * that leak reporting and pedantic checking can find it. If the array is ever + * exhausted, later allocations are still returned but their caller info cannot + * be recovered. + * + * Return: true if the registry has overflowed at any point + */ +#if CONFIG_IS_ENABLED(MCHECK_HEAP_PROTECTION) +bool malloc_mcheck_overflow(void); +#else +static inline bool malloc_mcheck_overflow(void) { return false; } +#endif + /** * malloc_chunk_size() - Return the dlmalloc chunk size for an allocation * diff --git a/test/cmd/malloc.c b/test/cmd/malloc.c index 95809845dd7..db4350afe68 100644 --- a/test/cmd/malloc.c +++ b/test/cmd/malloc.c @@ -63,6 +63,12 @@ static int cmd_test_malloc_leak(struct unit_test_state *uts) void *ptr; int ret; + /* + * If the mcheck registry ever overflowed, later allocations are not + * registered and leak reports cannot recover the caller string. + */ + ut_assert(!malloc_mcheck_overflow()); + /* Take a snapshot, then check with no leaks */ ut_assertok(malloc_leak_check_start(&snap)); ut_assert(snap.count > 0);