debuginfod/debuginfod-client.c: correct string format on 32bit arches with 64bit time_t
Message ID | 20211121221411.404194-1-alex@linutronix.de |
---|---|
State | Superseded |
Headers |
Return-Path: <elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DB27E3858411 for <patchwork@sourceware.org>; Sun, 21 Nov 2021 22:14:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DB27E3858411 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1637532865; bh=R3vHZgXN0AFEtbIWtN4PJXjzO5kFdEzFopJlEurs94k=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Help: List-Subscribe:From:Reply-To:Cc:From; b=k1mkPwU+mAXWD2tLyUwNnM1repL61jPRZiv+YAhqO5iL8AHj4p82lOFiImhLVZlGZ GJ0H8IFmSzrudtGBRg9Xb74G1J2plUPr1au+FBjNu/59OhE2fg28T9rX03tnwJN78P 0kLDOFFGS0dDxAH5tpftI7WvCk2PgNx8ciWdS83A= X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by sourceware.org (Postfix) with ESMTPS id 9B73D3858C3A for <elfutils-devel@sourceware.org>; Sun, 21 Nov 2021 22:14:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9B73D3858C3A Received: by mail-wr1-x42e.google.com with SMTP id a9so29093073wrr.8 for <elfutils-devel@sourceware.org>; Sun, 21 Nov 2021 14:14:16 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=R3vHZgXN0AFEtbIWtN4PJXjzO5kFdEzFopJlEurs94k=; b=jCNYkNBT6gp3d7ysc6M2ooXBUQmS5xThQY9reDoF1sVtnDSFbCwK6ADHO1KbhufhuW /aGpQqqoRzVtNt9ftbvzAMm05W7XR9djcyUjoQ7Y32RYO4SG+OrpBN9c3LDybPGH+q6W mTysRbpfhYD2XCMVorLnuw/5KrZ9PDqDHN/83DgegoWbUPiMZZKL+x9Lq7MGWOPovydB QCQ791tSrGzrUt2Ikq3vT0rIcScnChuMZKWZfbyaJHCa6R8cVUmUaxPBafdnpUQWzZDa 7/I0G/zsLG45Gd7NdOpS6ASy5KoEMf56P+/SJu+4gu+JpvbHa+4LI1zFwVO6kLDt79X2 RWvQ== X-Gm-Message-State: AOAM531XI0EjXjVpoLKxCWIPu5ANlQnwYpMbSC7tSyLsQ3gqPp7kMW0E 6m0QkrC959TYWmKeX8ayLeU= X-Google-Smtp-Source: ABdhPJwyJcG5CRIXaOYI1/h6kj84yCJXxXBSjZPwqBfVlLFRS0yKTEsS9Q9h2UZCAD/DlQvysiuWcQ== X-Received: by 2002:a5d:58c5:: with SMTP id o5mr31858592wrf.15.1637532855716; Sun, 21 Nov 2021 14:14:15 -0800 (PST) Received: from nereus.lab.linutronix.de. (b2b-109-90-143-203.unitymedia.biz. [109.90.143.203]) by smtp.gmail.com with ESMTPSA id t127sm20706817wma.9.2021.11.21.14.14.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 21 Nov 2021 14:14:15 -0800 (PST) X-Google-Original-From: Alexander Kanavin <alex@linutronix.de> To: mark@klomp.org, elfutils-devel@sourceware.org Subject: [PATCH] debuginfod/debuginfod-client.c: correct string format on 32bit arches with 64bit time_t Date: Sun, 21 Nov 2021 23:14:11 +0100 Message-Id: <20211121221411.404194-1-alex@linutronix.de> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Elfutils-devel mailing list <elfutils-devel.sourceware.org> List-Unsubscribe: <https://sourceware.org/mailman/options/elfutils-devel>, <mailto:elfutils-devel-request@sourceware.org?subject=unsubscribe> List-Archive: <https://sourceware.org/pipermail/elfutils-devel/> List-Help: <mailto:elfutils-devel-request@sourceware.org?subject=help> List-Subscribe: <https://sourceware.org/mailman/listinfo/elfutils-devel>, <mailto:elfutils-devel-request@sourceware.org?subject=subscribe> From: Alexander Kanavin via Elfutils-devel <elfutils-devel@sourceware.org> Reply-To: Alexander Kanavin <alex.kanavin@gmail.com> Cc: Alexander Kanavin <alex.kanavin@gmail.com>, Khem Raj <raj.khem@gmail.com> Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org Sender: "Elfutils-devel" <elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org> |
Series |
debuginfod/debuginfod-client.c: correct string format on 32bit arches with 64bit time_t
|
|
Commit Message
Alexander Kanavin
Nov. 21, 2021, 10:14 p.m. UTC
From: Alexander Kanavin <alex.kanavin@gmail.com> Use intmax_t to print time_t time_t is platform dependent and some of architectures e.g. x32, riscv32, arc use 64bit time_t even while they are 32bit architectures, therefore directly using integer printf formats will not work portably, use intmax_t to typecast time_t into printf family of functions. musl 1.2.0 and above uses time64 on all platforms; glibc 2.34 has added support for time64 (which might be enabled by distro-wide CFLAGS), with possibly 2.35 or 2.36 making it enabled by default. Use a plain int for scanning cache_config, as that's what the function returns. Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com> Signed-off-by: Khem Raj <raj.khem@gmail.com> --- debuginfod/debuginfod-client.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
Comments
Hi - > Use intmax_t to print time_t > [...] > - if (dprintf(fd, "%ld", cache_config_default_s) < 0) > + if (dprintf(fd, "%jd", (intmax_t)cache_config_default_s) < 0) > [...] I'm not a compatibility specialist, but note that elfutils is sometimes built on decade-old toolchains, where use of %lld and (long long) would certainly work. We have such in the code base already, whereas this would be the first %j. - FChE
According to 'man 3 printf' %j appeared in glibc 2.1 and seems to be C99 feature. That's decidedly ancient. And may I be allowed to suggest, unless elfutils is tested in upstream CI with decade-old toolchains, you should not be considering its compatibility with them. Alex On Thu, 25 Nov 2021 at 18:51, Frank Ch. Eigler <fche@redhat.com> wrote: > Hi - > > > Use intmax_t to print time_t > > [...] > > - if (dprintf(fd, "%ld", cache_config_default_s) < 0) > > + if (dprintf(fd, "%jd", (intmax_t)cache_config_default_s) < 0) > > [...] > > I'm not a compatibility specialist, but note that elfutils is sometimes > built on decade-old toolchains, where use of %lld and (long long) would > certainly work. We have such in the code base already, whereas this would > be the first %j. > > - FChE > >
Hi - > According to 'man 3 printf' %j appeared in glibc 2.1 and seems to be C99 > feature. That's decidedly ancient. OK. > And may I be allowed to suggest, unless elfutils is tested in upstream CI > with decade-old toolchains, you should not be considering its compatibility > with them. Deployment of elfutils is not limited to platforms that happen to be included in upstream CI that you see. RHEL7 uses glibc 2.17 from 2012; RHEL6 years before that. We do not wish to unnecessarily break them. - FChE
Hi, On Sun, Nov 21, 2021 at 11:14:11PM +0100, Alexander Kanavin via Elfutils-devel wrote: > From: Alexander Kanavin <alex.kanavin@gmail.com> > > Use intmax_t to print time_t > > time_t is platform dependent and some of architectures e.g. > x32, riscv32, arc use 64bit time_t even while they are 32bit > architectures, therefore directly using integer printf formats will not > work portably, use intmax_t to typecast time_t into printf family of > functions. OK, so there were some questions about whether using intmax_t and %jd are portable enough, but I think it is clear that everything these days support that. So that is good. > musl 1.2.0 and above uses time64 on all platforms; glibc 2.34 has added support for > time64 (which might be enabled by distro-wide CFLAGS), with possibly > 2.35 or 2.36 making it enabled by default. > > Use a plain int for scanning cache_config, as that's what the function > returns. So I think you are correct that printing/scanning/casting the time_t around is somewhat unfortunate because the size of time_t is not stable across architectures. Thanks for looking into this. I had no idea time_t was such a problematic data type. What makes it even more curious is that debuginfod_config_cache takes a long, not a time_t, while it is always called with a time_t argument. And then it returns an int... The result is interpreted as a negative errno number or is cast back to a time_t if it is positive. With this patch we write out the interval values "as big as possible" (intmax_t), but read it back in "as small as possible" (int). Would it make sense to also try to read it back in as intmax_t and then cast down to int? Or simply always cast down to int before writing it out, so reading and writing use the same data type? We seem to not expect these intervals to be much bigger than a week, so an int should always be big enough (even when stretched up to a whole year). Thanks, Mark
I'm not sure; the point of this patch is simply to ensure debuginfod builds everywhere without errors. Making the types consistent is perhaps better done as a followup? Alex On Sun, 5 Dec 2021 at 21:31, Mark Wielaard <mark@klomp.org> wrote: > Hi, > > On Sun, Nov 21, 2021 at 11:14:11PM +0100, Alexander Kanavin via > Elfutils-devel wrote: > > From: Alexander Kanavin <alex.kanavin@gmail.com> > > > > Use intmax_t to print time_t > > > > time_t is platform dependent and some of architectures e.g. > > x32, riscv32, arc use 64bit time_t even while they are 32bit > > architectures, therefore directly using integer printf formats will not > > work portably, use intmax_t to typecast time_t into printf family of > > functions. > > OK, so there were some questions about whether using intmax_t and %jd > are portable enough, but I think it is clear that everything these > days support that. So that is good. > > > musl 1.2.0 and above uses time64 on all platforms; glibc 2.34 has added > support for > > time64 (which might be enabled by distro-wide CFLAGS), with possibly > > 2.35 or 2.36 making it enabled by default. > > > > Use a plain int for scanning cache_config, as that's what the function > > returns. > > So I think you are correct that printing/scanning/casting the time_t > around is somewhat unfortunate because the size of time_t is not > stable across architectures. Thanks for looking into this. I had no > idea time_t was such a problematic data type. > > What makes it even more curious is that debuginfod_config_cache takes > a long, not a time_t, while it is always called with a time_t > argument. And then it returns an int... The result is interpreted as a > negative errno number or is cast back to a time_t if it is positive. > > With this patch we write out the interval values "as big as possible" > (intmax_t), but read it back in "as small as possible" (int). Would it > make sense to also try to read it back in as intmax_t and then cast > down to int? Or simply always cast down to int before writing it out, > so reading and writing use the same data type? > > We seem to not expect these intervals to be much bigger than a week, > so an int should always be big enough (even when stretched up to a > whole year). > > Thanks, > > Mark >
Hi Alexander, On Sun, 2021-12-05 at 21:45 +0100, Alexander Kanavin wrote: > I'm not sure; the point of this patch is simply to ensure debuginfod builds > everywhere without errors. Making the types consistent is perhaps better > done as a followup? I think the issue of the code not compiling in some environments is because of the inconsistent use of types. So I rather fix the build errors by fixing the used types than to simply cast the errors away. Cheers, Mark
Hi - > [...] > We seem to not expect these intervals to be much bigger than a week, > so an int should always be big enough (even when stretched up to a > whole year). Yes, ints are fine for these humane-number-of-seconds kinds of values in the cache configuration. There's no need for maximum length integers or even longs for purposes of storage/parse. In the later interval arithmetic related to time_t values, we can widen them to (time_t) then and there. - FChE
Alright, I just sent a patch that replaces time_t with long instead. I tested it on x86, x86-x32, x86-64. Alex On Wed, 8 Dec 2021 at 16:31, Mark Wielaard <mark@klomp.org> wrote: > Hi Alexander, > > On Sun, 2021-12-05 at 21:45 +0100, Alexander Kanavin wrote: > > I'm not sure; the point of this patch is simply to ensure debuginfod > builds > > everywhere without errors. Making the types consistent is perhaps better > > done as a followup? > > I think the issue of the code not compiling in some environments is > because of the inconsistent use of types. So I rather fix the build > errors by fixing the used types than to simply cast the errors away. > > Cheers, > > Mark >
diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c index c875ee62..df9737d2 100644 --- a/debuginfod/debuginfod-client.c +++ b/debuginfod/debuginfod-client.c @@ -231,15 +231,15 @@ debuginfod_config_cache(char *config_path, if (fd < 0) return -errno; - if (dprintf(fd, "%ld", cache_config_default_s) < 0) + if (dprintf(fd, "%jd", (intmax_t)cache_config_default_s) < 0) return -errno; } - long cache_config; + int cache_config; FILE *config_file = fopen(config_path, "r"); if (config_file) { - if (fscanf(config_file, "%ld", &cache_config) != 1) + if (fscanf(config_file, "%d", &cache_config) != 1) cache_config = cache_config_default_s; fclose(config_file); } @@ -272,7 +272,7 @@ debuginfod_init_cache (char *cache_path, char *interval_path, char *maxage_path) if (fd < 0) return -errno; - if (dprintf(fd, "%ld", cache_clean_default_interval_s) < 0) + if (dprintf(fd, "%jd", (intmax_t)cache_clean_default_interval_s) < 0) return -errno; /* init max age config file. */ @@ -280,7 +280,7 @@ debuginfod_init_cache (char *cache_path, char *interval_path, char *maxage_path) && (fd = open(maxage_path, O_CREAT | O_RDWR, DEFFILEMODE)) < 0) return -errno; - if (dprintf(fd, "%ld", cache_default_max_unused_age_s) < 0) + if (dprintf(fd, "%jd", (intmax_t)cache_default_max_unused_age_s) < 0) return -errno; return 0;