Bug#1067453: gnat: Ada.Calendar.Clock crashes on time_t64 architectures
Source: gcc-13 Followup-For: Bug #1067453 The gettimeofday import issue seems specific to the time_t 64 transition in Debian. When building C on armhf, a #define replaces gettimeofday with __gettimeofday64 so the linker finds the 64 bits version in the libc. When linking Ada code, the linker searches for the gettimeofday symbol and links with the 32 bits version, as demonstrated by the reproducer script below. Here is the output. ./c_part timeval size: 128 tv_sec offset: 0 size: 64 value: 662A7756 tv_usec offset: 8 size: 64 value: 1C54 56 77 2A 66 00 00 00 00 54 1C 00 00 00 00 00 00 ./ada_part timeval size: 128 tv_sec offset: 0 size: 64 value:16#27A9662A7756# tv_usec offset: 8 size: 64 value:-16#80B1C0708345E00# 56 77 2A 66 A9 27 00 00 00 A2 CB F7 F8 E3 F4 F7 Changing the External_Name from "gettimeofday" to "__gettimeofday64" fixes the mismatch (except for the lower microseconds of course). ./c_part 81 76 2A 66 00 00 00 00 0F E2 0C 00 00 00 00 00 ./ada_part 81 76 2A 66 00 00 00 00 CB EC 0C 00 00 00 00 00 So we have two possible work-arounds. * build a C source with a __gnat_gettimeofday wrapper. This option, implemented by my last commit, patches gcc/ada/Makefile.rtl gcc/ada/cal.c gcc/ada/gcc-interface/Makefile.in gcc/ada/libgnat-s-osprim__posix.adb and interfers with the previous commit. * simply patch gcc/ada/libgnat/s-osprim__posix.adb with - pragma Import (C, gettimeofday, "gettimeofday"); + pragma Import (C, gettimeofday, "__gettimeofday64"); This seems better, but must only be applied on targets affected by the t64 transition. I do not know which one is the best, but at least the second one explains why the first one did work. Just in case, here is the reproducer script: -- #!/bin/sh set -efuv cat > hexdump.h < hexdump.c < #include "hexdump.h" void hexdump(char* p, int length) { while (length--) { printf(" %02hhX", *p++); } printf("\n"); } EOF cat > c_part.c < #include #include #include #include "hexdump.h" int main(int argc, const char* argv[]) { struct timeval tv; if (argc == 1) { printf(" gettimeofday returned %i\n", gettimeofday(, NULL)); printf(" timeval size: %lli\n", (long long int)( CHAR_BIT * sizeof(tv))); printf(" tv_sec"); printf(" offset: %lli", (long long int)((char*)(&(tv.tv_sec)) - (char*)())); printf(" size: %lli", (long long int)(CHAR_BIT * sizeof(tv.tv_sec))); printf(" value: %llX", (long long int)tv.tv_sec); printf("\n"); printf(" tv_usec"); printf(" offset: %lli", (long long int)((char*)(&(tv.tv_usec)) - (char*)())); printf(" size: %lli", (long long int)(CHAR_BIT * sizeof(tv.tv_usec))); printf(" value: %llX", (long long int)tv.tv_usec); printf("\n"); hexdump((char*)(), sizeof(tv)); } else { printf(" time_t_bits : constant := %lli;\n", (long long int)(CHAR_BIT * sizeof(tv.tv_sec))); printf(" suseconds_t_bits : constant := %lli;\n", (long long int)( CHAR_BIT * sizeof(tv.tv_usec))); } return EXIT_SUCCESS; } EOF cat > ada_part.adb < C; type suseconds_t is range -2**(suseconds_t_bits - 1) .. 2**(suseconds_t_bits - 1) - 1 with Convention => C; type timeval is record tv_sec : time_t; tv_usec : suseconds_t; end record with Convention => C; function gettimeofday (tv : access timeval; tz : Address) return int with Import, Convention => C, External_Name => "gettimeofday"; -- Here Tv : aliased timeval; function Offset (A, B : Address) return String is (Long_Long_Integer'Image (Long_Long_Integer'Value (A'Img) - Long_Long_Integer'Value (B'Img))); I : constant int := gettimeofday(Tv'Access, Null_Address); procedure hexdump(p : Address; count : Integer) with Import, Convention => C, External_Name => "hexdump"; begin Put_Line (" gettimeofday returned" & I'Img); Put_Line (" timeval size:" & Integer'Image (Tv'Size)); Put (" tv_sec offset:" & Offset (Tv.tv_sec'Address, Tv'Address) & " size:" & Integer'Image (Tv.tv_sec'Size) & " value:"); Put (Long_Long_Integer (Tv.tv_sec), Width => 0, Base => 16); New_Line; Put (" tv_usec offset:" & Offset (Tv.tv_usec'Address, Tv'Address) & " size:" & Integer'Image (Tv.tv_usec'Size) & " value:"); Put (Long_Long_Integer (Tv.tv_usec), Width => 0, Base => 16); New_Line; hexdump (Tv'Address, Tv'Size / 8); end Ada_Part; EOF gcc -c -Wall -Wextra hexdump.c -o hexdump.o gcc -Wall -Wextra c_part.c hexdump.o -o c_part gnatmake -gnat2022 -gnatwa -gnatya ada_part.adb -largs hexdump.o ./c_part ./ada_part
Bug#1067453: gnat: Ada.Calendar.Clock crashes on time_t64 architectures
Source: gcc-13 Followup-For: Bug #1067453 Sorry for the poor summary. Here is what I have built and tested. * native build on ppc46el (not amd64) * gcc-source 13.2.0-19 from Debian * libgnat-timet64.diff unapplied (pr114065-proposed.diff should be unapplied for -20 and later) * commits 1/8 to 8/8 from bug114065attempt3.tar.gz applied (Debian only needs 1-3, 4-8 should only affect style). * ada-lib-info-source-date-epoch.diff adapted as described in #1067453 (disabling it for a while is also an option) * debian/rules binary-arch cat > demo.adb <
Bug#1067453: gnat: Ada.Calendar.Clock crashes on time_t64 architectures
Nicolas, which package version are you working with? On 05.04.24 18:45, Nicolas Boulenguez wrote: Source: gcc-13 Followup-For: Bug #1067453 Hello. In case anyone tries to build attempt3 at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114065 in Debian, please: * disable debian/patches/libgnat-time64.diff in debian/rules.patch this has been replaced in -23 with https://salsa.debian.org/toolchain-team/gcc/-/blob/gcc-13-debian/debian/patches/pr114065-proposed.diff what Eric Botcazou suggested to do. * adapt the current ada-lib-info-source-date-epoch.diff without the first patch in pr114065, that will ftbfs on armhf. or are you suggesting any further patches? thanks, Matthias
Bug#1067453: gnat: Ada.Calendar.Clock crashes on time_t64 architectures
Source: gcc-13 Followup-For: Bug #1067453 Hello. In case anyone tries to build attempt3 at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114065 in Debian, please: * disable debian/patches/libgnat-time64.diff in debian/rules.patch * adapt the current ada-lib-info-source-date-epoch.diff --- a/debian/patches/ada-lib-info-source-date-epoch.diff +++ b/debian/patches/ada-lib-info-source-date-epoch.diff @@ -62,24 +62,26 @@ Author: Nicolas Boulenguez end File_Stamp; function File_Stamp (Name : Path_Name_Type) return Time_Stamp_Type is -@@ -3261,4 +3276,28 @@ begin +@@ -3261,4 +3276,30 @@ begin Osint.Initialize; end Initialization; + Set_Source_Date_Epoch : declare ++ -- See comments in OS_Time_To_GNAT_Time. ++ use type CRTL.int64; ++ function To_Ada is new Ada.Unchecked_Conversion (CRTL.int64, OS_Time); + Env_Var : String_Access := Getenv ("SOURCE_DATE_EPOCH"); -+ Epoch : time_t range 0 .. time_t'Last := 0; -+ Digit : time_t range 0 .. 9; ++ Epoch : CRTL.int64 range 0 .. CRTL.int64'Last := 0; ++ Digit : CRTL.int64 range 0 .. 9; + begin + if 0 < Env_Var.all'Length then + -- Calling System.Val_LLI breaks the bootstrap sequence. -+ -- First convert to time_t because OS_Time is private. + for C of Env_Var.all loop +if C not in '0' .. '9' then + goto Finally; +end if; -+Digit := time_t (Character'Pos (C) - Character'Pos ('0')); -+if (time_t'Last - Digit) / 10 < Epoch then ++Digit := CRTL.int64 (Character'Pos (C) - Character'Pos ('0')); ++if (CRTL.int64'Last - Digit) / 10 < Epoch then + goto Finally; +end if; +Epoch := Epoch * 10 + Digit;
Bug#1067453: gnat: Ada.Calendar.Clock crashes on time_t64 architectures
Control: forwarded -1 https://gcc.gnu.org/PR114424
Bug#1067453: gnat: Ada.Calendar.Clock crashes on time_t64 architectures
Package: gnat-13 Version: 13.2.0-19 Severity: normal X-Debbugs-Cc: lbre...@debian.org Control: affects -1 pcscada libalog dbusada anet ahven libgmpada libgtkada libgnatcoll-db libncursesada libaunit adacgi liblog4ada libtexttools libtemplates-parser libxmlezout libgnatcoll-bindings libgnatcoll gprbuild Hello. Most Ada packages randomly FTBFS on 32 bit architectures with gprbuild: raised CONSTRAINT_ERROR : a-calend.adb:371 overflow check failed The problem originates in the gcc-13 switch to time_t64. gcc/ada/libgnat/s-os_prim__posix.adb is affected by two apparently distinct issues. * s-os_prim.adb allocates 3Long_Integer=3void*=3*32 bits for the timeval C struct, while 2*64bits = 2Long_Long_Integer are now needed. This issue affects other files, but is easy to find and fix. * The switch breaks the call from Ada to the C gettimeofday function. Can anyone explain this, and ideally provide a real fix instead of the ugly work-around below? cat > mycal.c < int mygettimeofday(struct timeval *restrict tv, struct timezone *restrict tz) { return gettimeofday(tv, tz); } EOF cat > foo.adb <