X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f DKIM-Filter: OpenDKIM Filter v2.11.0 delorie.com 491KvJwk3672892 Authentication-Results: delorie.com; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=gOQhZnvp X-Recipient: djgpp AT delorie DOT com X-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727816237; x=1728421037; darn=delorie.com; h=content-transfer-encoding:subject:from:to:content-language :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=NmWJQH3LjIplvxVKHILi5vJV7Sh5+rfeHH0xTPA2604=; b=gOQhZnvpyAlnbYGBeS4PmE+oCGyboovZ7OXQgjFKzBz/6BT2L0778ya3vB+gfbTOEu OgUnHOLrFm5O9epnibJ3Vj/1X44KOYipuDR3OqeDuhXWncxXkKjx4da+/i7uPPJgl3Ke zW3QU5iroiwnyBnVQjZp6YHV3YCz6fLfr8GoAMfqBAEse9zt4MkSKvlwAgUrcn7VK9j5 l+DnbEK0DObQ3BcDcxSGVJck/Ayt+jzuZZ2swL2HyguQ190R+fNI84EdziANGuddYru2 mcuiCTba+FTM6JEBP3B4D0XtM5nfucF9GRnjvkVwRgjED5ZMEa66Fg4nftq3bP2bo2QO BErQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727816237; x=1728421037; h=content-transfer-encoding:subject:from:to:content-language :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=NmWJQH3LjIplvxVKHILi5vJV7Sh5+rfeHH0xTPA2604=; b=hGJA7otM8GRnXs6fgYA/0XwXFbN7BC9pdeMO05ietOBhC2WKMBJRwBNbiKKqBlD3iv TCTC0NHIBYWiw3K/vF7Tk7ZCJoZPqhzEhKctSA4J5fH853tmAAi/w8dOP0B1+s05MTX8 euEnnpiFH9c4lCrbTW53C4nK852EjsSgE9IKaAo7C80B80IP46Ehz9Zgs44aF6YkCWaT +r4eRVs5wgAUlTDtfUtdFgBNOEdLRRhrAeqIUaiMhp76GiJzPJpeoXqaPY7LzBK+Bg/r +OdLX6GlFH/H1dNjLl/GKIuUrdfemgpM6JAEQ7F6t84rkyZRXlA9wiPLJdEjP4i5XapE 7ptw== X-Gm-Message-State: AOJu0Yxb0uZdwKydjFplciFxq3iyC1e89uJ0i1bRkAGRGvF2gsC7iV6y eVJcei14vbhfptKTXDsPoZsYMn5SQqbv6RRleyHLzRkEX/BYOVuDJhjMfw== X-Google-Smtp-Source: AGHT+IE7zbC+nz6JdWY6pq8l7e40XdyahFGMQfMzfwhuAFOSd31nMJlAt3CY5lF8eGSBBTSkRefXiQ== X-Received: by 2002:a05:6402:34cf:b0:5c5:cf0b:b515 with SMTP id 4fb4d7f45d1cf-5c8b18deb86mr506994a12.1.1727816236626; Tue, 01 Oct 2024 13:57:16 -0700 (PDT) Message-ID: <7d97575b-24ac-4d55-be14-266ade57b992@gmail.com> Date: Tue, 1 Oct 2024 22:57:15 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: djgpp AT delorie DOT com From: "J.W. Jagersma (jwjagersma AT gmail DOT com) [via djgpp AT delorie DOT com]" Subject: malloc clobbers sbrk'd memory Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Reply-To: djgpp AT delorie DOT com I believe I found a bug where malloc sporadically writes past the end of a memory chunk. I ran into this while working on mcount, which allocates the histogram and call graph via sbrk. When my test program was invoked with some specific number of arguments, the first histogram entry was clobbered, which in gprof appeared as if the program had spent a lot of time in 'start'. Turns out: the clobber value is the same as the special 'NONE' pointer used in nmalloc.c. What I believe is happening: the minimum chunk size created by __nmalloc_split is DATAOFFSET (which is sizeof(memblock)-4; does *not* include prevfree). But when the high half is then passed to mv2freelist, it writes prevfree=NONE, which is now past the end of the chunk. Solution is probably to define MINSAVE as (ALIGN + sizeof (memblock)), regardless of SAVEMEMORY tricks. It might be worth adding another 16 bytes or so, since minimum-size chunks are useless and only add clutter to the freelist. See test case below. Compile with -O0 and invoke with some number of arguments. On my machine the bug triggers with 21 single-char args, like so: C:\>test.exe x x x x x x x x x x x x x x x x x x x x x But the exact number may be dependent on environment size or other factors. --- #include #include #include int main () { free (malloc (100000)); int *p = (int *)sbrk (sizeof (int)); *p = 0; for (unsigned i = 0; i != 100000; ++i) { void *q = malloc (1); if (*p != 0) { printf ("BAD: *p=%i after %u mallocs!\n", *p, i + 1); return 1; } if (q > (void *)p) { printf ("passed p after %u mallocs\n", i + 1); break; } } printf ("OK\n"); return 0; }