Hi, Le 10/11/2022 à 01:28, Paul Eggert via tz a écrit :
On 11/9/22 11:25, Tom Lane wrote:
So in the case in strftime(), Valgrind would only complain if mktime() actually tried to use any fields that had not been initialized by the caller of strftime(). Which is just what one would want.
True, and good point. And I understand why Valgrind wants to delay checking here: it wants to avoid false alarms in some programs. Unfortunately Valgrind's delay in reporting is problematic, because Valgrind sometimes neglects to report behavior that the C standard says is undefined. For example:
$ cat t.c int main (void) { int a, b=a; return b; } $ gcc t.c $ valgrind ./a.out [no error is reported]
Here I'm getting: $ valgrind ./a.out ==511562== Memcheck, a memory error detector ==511562== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==511562== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info ==511562== Command: ./a.out ==511562== ==511562== Syscall param exit_group(status) contains uninitialised byte(s) ==511562== at 0x4955DF1: _Exit (_exit.c:30) ==511562== by 0x48B1561: __run_exit_handlers (exit.c:136) ==511562== by 0x48B161F: exit (exit.c:143) ==511562== by 0x4896516: (below main) (libc_start_call_main.h:74) ==511562== ==511562== ==511562== HEAP SUMMARY: ==511562== in use at exit: 0 bytes in 0 blocks ==511562== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==511562== ==511562== All heap blocks were freed -- no leaks are possible ==511562== ==511562== Use --track-origins=yes to see where uninitialised values come from ==511562== For lists of detected and suppressed errors, rerun with: -s ==511562== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Conversely, as my previous email showed, Valgrind sometimes reports behavior that I think is a program failure that should be fixed, but the C standard says is well-defined behavior. Although Valgrind was pickier in that email than the C standard really allows, I wish Valgrind were a bit pickier still and reported each use of an uninitialized variable when it happens and not optionally later (by then, it may be difficult to debug), and I'd like tzcode to work with such a Valgrind-like system.
With --track-origins=yes : $ valgrind --track-origins=yes ./a.out ==511667== Memcheck, a memory error detector ==511667== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==511667== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info ==511667== Command: ./a.out ==511667== ==511667== Syscall param exit_group(status) contains uninitialised byte(s) ==511667== at 0x4955DF1: _Exit (_exit.c:30) ==511667== by 0x48B1561: __run_exit_handlers (exit.c:136) ==511667== by 0x48B161F: exit (exit.c:143) ==511667== by 0x4896516: (below main) (libc_start_call_main.h:74) ==511667== Uninitialised value was created by a stack allocation ==511667== at 0x109129: main (in /home/ydroneaud/src/test/a.out) ==511667== ==511667== ==511667== HEAP SUMMARY: ==511667== in use at exit: 0 bytes in 0 blocks ==511667== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==511667== ==511667== All heap blocks were freed -- no leaks are possible ==511667== ==511667== For lists of detected and suppressed errors, rerun with: -s ==511667== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) Using UBSan and MSan (requires clang) instead of valgrind would catch this too: $ clang -fsanitize=undefined,memory -fsanitize-memory-track-origins=2 -g t.c $ ./a.out ==511862==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x55a79df79b35 in main .../t.c:1:31 #1 0x7f686dc2350f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 #2 0x7f686dc235c8 in __libc_start_main csu/../csu/libc-start.c:381:3 #3 0x55a79def3294 in _start (.../a.out+0x1e294) (BuildId: 576806214712a462122845f7fa09af26e1237aee) Uninitialized value was stored to memory at #0 0x55a79df79adf in main .../t.c:1:26 #1 0x7f686dc2350f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 Uninitialized value was created by an allocation of 'a' in the stack frame of function 'main' #0 0x55a79df799a0 in main .../t.c:1 SUMMARY: MemorySanitizer: use-of-uninitialized-value .../t.c:1:31 in main Exiting Regards. -- Yann Droneaud OPTEYA