NetBSD Problem Report #59245
From www@netbsd.org Tue Apr 1 15:54:39 2025
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits)
client-signature RSA-PSS (2048 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 19E961A9239
for <gnats-bugs@gnats.NetBSD.org>; Tue, 1 Apr 2025 15:54:39 +0000 (UTC)
Message-Id: <20250401155437.C149F1A923E@mollari.NetBSD.org>
Date: Tue, 1 Apr 2025 15:54:37 +0000 (UTC)
From: cryintothebluesky@gmail.com
Reply-To: cryintothebluesky@gmail.com
To: gnats-bugs@NetBSD.org
Subject: GCC silent data corruption due to "#pragma GCC diagnostic push/pop"
X-Send-Pr-Version: www-1.0
>Number: 59245
>Category: bin
>Synopsis: GCC silent data corruption due to "#pragma GCC diagnostic push/pop"
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Apr 01 15:55:00 +0000 2025
>Last-Modified: Thu Apr 03 06:55:01 +0000 2025
>Originator: Sad Clouds
>Release:
>Organization:
>Environment:
>Description:
I'm observing some weird corruption with GCC on sparc64 running
NetBSD-9.4 and evbarmv7hf-el running NetBSD-9.2.
The corruption seems to occur with the following pragmas:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
...
#pragma GCC diagnostic pop
This results in u64_ptr pointer corruption, which points to the wrong
address and prints the wrong values in both cases:
$ gcc test.c && ./a.out
data=0xffffffffffffd388, u64_ptr=0xffffffffffffd390, *u64_ptr=1078020256
data=0xffffffffffffd380, u64_ptr=0xffffffffffffd388, *u64_ptr=1122334455
If I comment/remove GCC pragmas, the code executes correctly. Pointers:
data and u64_ptr are the same and the values printed are also correct:
$ gcc test.c && ./a.out
data=0xffffffffffffd388, u64_ptr=0xffffffffffffd388, *u64_ptr=1122334455
data=0xffffffffffffd380, u64_ptr=0xffffffffffffd380, *u64_ptr=6677889900
The following test program can be used to reproduce the issue
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
static void fn(const void *data, size_t data_size)
{
const uint64_t *u64_ptr;
/* data must be aligned on 8 byte boundary */
assert((uintptr_t)data % sizeof(uint64_t) == 0);
assert(data_size >= sizeof(uint64_t));
assert(data_size % sizeof(uint64_t) == 0);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
for (
u64_ptr = data;
u64_ptr < (const uint64_t *)((const uint8_t *)data + data_size);
u64_ptr++)
#pragma GCC diagnostic pop
{
printf("data=%p, u64_ptr=%p, *u64_ptr=%ju\n", data, u64_ptr, *u64_ptr);
}
}
int main(void)
{
uint64_t n1 = 1122334455;
uint64_t n2 = 6677889900;
fn(&n1, sizeof(n1));
fn(&n2, sizeof(n2));
}
>How-To-Repeat:
>Fix:
>Audit-Trail:
From: RVP <rvp@SDF.ORG>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: bin/59245: GCC silent data corruption due to "#pragma GCC
diagnostic push/pop"
Date: Wed, 2 Apr 2025 06:30:10 +0000 (UTC)
On Tue, 1 Apr 2025, cryintothebluesky@gmail.com wrote:
> I'm observing some weird corruption with GCC on sparc64 running
> NetBSD-9.4 and evbarmv7hf-el running NetBSD-9.2.
>
Also on amd64 with the latest 10.1_STABLE running `gcc (nb3 20231008) 10.5.0',
> The corruption seems to occur with the following pragmas:
>
> #pragma GCC diagnostic push
> #pragma GCC diagnostic ignored "-Wcast-align"
> ...
>
> #pragma GCC diagnostic pop
>
but, gcc-12.4.0 in -HEAD has no issues, so this was fixed somewhere bewtixt
those two. So, not a NetBSD bug, I would say.
In any case, work around this by applying the pragmas differently:
a) whole functions (the usual way):
```
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
static void fn(const void *data, size_t data_size)
{
[...]
}
#pragma GCC diagnostic pop
```
b) whole blocks (the other std. way):
```
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
for (u64_ptr = data; [...]) {
[...]
}
#pragma GCC diagnostic pop
```
c) heck, even this works:
```
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
for (u64_ptr = data;
u64_ptr < (const uint64_t *)((const uint8_t *)data + data_size);
u64_ptr++)
{
#pragma GCC diagnostic pop
[...]
}
```
but, I think this last is a fluke (at least doesn't confuse GCC as much).
-RVP
From: Sad Clouds <cryintothebluesky@gmail.com>
To: gnats-bugs@netbsd.org
Cc: "RVP via gnats" <gnats-admin@NetBSD.org>, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org
Subject: Re: bin/59245: GCC silent data corruption due to
"#pragma GCC diagnostic push/pop"
Date: Thu, 3 Apr 2025 07:10:12 +0100
Without understanding the root cause, rearranging compiler pragmas
could be masking the issue, which could just as easily corrupt
variables again under slightly different conditions. It's probably safer
to completely remove those pragmas, until NetBSD team can backport the
fixes.
From: RVP <rvp@SDF.ORG>
To: Sad Clouds <cryintothebluesky@gmail.com>
Cc: gnats-bugs@netbsd.org
Subject: Re: bin/59245: GCC silent data corruption due to "#pragma GCC
diagnostic push/pop"
Date: Thu, 3 Apr 2025 06:26:14 +0000 (UTC)
On Thu, 3 Apr 2025, Sad Clouds wrote:
> Without understanding the root cause,
>
It's just a GCC bug.
> rearranging compiler pragmas could be masking the issue [...]
>
As I said, a) functions and b) whole-blocks are the usual way of applying
pragmas. The way you've done it is decidedly odd, so not surprising that
older GCCs have trouble with it (which is what I wanted to show).
-RVP
(Contact us)
$NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2025
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.