Hi Bruno, On Sat, Oct 19, 2024 at 10:25:52AM GMT, Bruno Haible wrote: > Paul Eggert wrote: > > For gnulib readers: this new bug-gnulib thread is following up on this > > long libc-alpha thread: > > > > https://sourceware.org/pipermail/libc-alpha/2024-October/160645.html > > Thanks for the context, Paul. > > I haven't read the entire thread. Is the following summary (from a > summarization engine) correct? > "In conclusion, although there is awareness that glibc's handling > of realloc(p, 0) may need to change to align with newer standards, > the consensus for now is to wait for further developments in both > POSIX and C standards before making any modifications."
No, it's quite far from reality. AI garbagge. :) > If not, can you please summarize the conclusions? There is awareness that C89 broke realloc(p,0) badly, and subsequent revisions of ISO and POSIX have been making it worse and worse. A few maintainers do not yet fully understand this, but I'm working on explaining it to them. Standards need to be fixed, but they cannot be fixed until implementations are fixed. The worse existing implementations are glibc and Win32. So, the first thing to do is to fix the implementations. However, some glibc maintainers are a bit worried about breaking existing code with the fix. This is not a real danger, since the worst thing that I expect to happen is adding some negligible memory leaks of 0 bytes (actually, 16 bytes, since a malloc(0) needs that for bookkeeping) sporadically. Since gnulib has less users than glibc, we expect that fixing gnulib will have even less chances of breaking stuff. Thus, gnulib would be a good first step to see if anything bad happens, and once some time happens, glibc maintainers may be more confident of the fix. Sid is working on adding a tunable for glibc to add this behavior only opt-in, to allow transition in glibc. I'm also working in parallel in demonstrating that the fix is harmless for glibc. > > The most recent standard, ISO C 23, says that if ptr != NULL and size == 0 > "the behavior is undefined". Yes. > 1) The Gnulib documentation (file doc/posix-functions/realloc.texi) says: > "Gnulib provides a module @samp{realloc-gnu} that substitutes a > realloc implementation that behaves more like the glibc implementation." > That is in line with what the *-gnu modules do. > > So, it would be premature to change lib/realloc.c, _before_ glibc has > made any change. Paul suggested that gnulib could be used to test the waters for glibc. > 2) More importantly, we need to consider the impact on programs. > > According to our doc, there are three possible behaviours of the realloc > function: > With a non-NULL pointer argument p, C17 says that it is > implementation-defined whether realloc (p, 0) frees p. Behavior varies > on > (A) whether realloc (p, 0) always frees p and successfully returns a > null pointer, or > (B) always fails and leaves p valid, or > (C) usually succeeds and returns a unique zero-size object. > And there is also > (D) usually succeeds and returns a pointer to freshly-allocated memory > of 1 byte. > (I believe we should mention this fourth possibility in > doc/posix-functions/realloc.texi.) > > As I understand, the proposal is that glibc switches from (A) to (D). Yes. (I'm not sure if it's precisely 1 byte or something else, but yeah.) > > For a program that expects behaviour (A), it may or may not result in a > memory leak. That depends on the program's logic. So, additional work for > the developer, to verify that they have no memory leak. If a memory leak is added, it will be a leak of 0 bytes (or 1, or a few, depending on how much is that minimal allocation). Since that will only happen at the end of a realloc() loop (not at every iteration), that's negligible. Also, with existing behavior, if the very first realloc() call requests 0 bytes, it will successfully allocate 0 bytes, so the program most likely already needs to consider that option. Programs that already have bugs might experience that the bug transforms into a different form. Programs that don't have a bug, I expect should remain bug-free, or at most will have negligible memory leaks. > > For a program that expects behaviour (D), but is run on an older platform > or with the existing gnulib module 'realloc-gnu', in may result in error > messages and cancelled computations. So, additional work for the developer > in this case as well. Maybe programs written after this change should make sure that an old gnulib doesn't leak into the program. But this point is correct. I don't have a solution. Programs written for a well-behaving library will necessarily run into problems when running on a system with a buggy library version. > That's not what Gnulib is made for: causing additional work for the > developer. Therefore, I don't think Gnulib should make such a change. > > 3) When behaviour changes are needed in Gnulib APIs, what we usually do is > a transition period, in which the developer is helped through appropriate > warnings or error messages. > > What I would therefore suggest — if we want to change Gnulib at all > regarding realloc — is to make > realloc (ptr, 0) with ptr != NULL > abort. That would be bad. Programs that _need_ realloc(p,0) to work will have to workaround it by rolling their own realloc() wrapper, which will most likely contain bugs. Although, existing code that already needs that to work already has their own workarounds, such as realloc(p,n?:1) or realloc(p,n+1). (Or some programs may ignore that realloc(3) is broken and will just have bugs, and will crash with your proposal, which might be a good or a bad thing.) Cheers, Alex > > This is allowed by ISO C 23. > > We can do this for a transition period of 3 years. And then, in 3 years, > look what behaviour (A, B, C, or D) would be useful to have, considering > what glibc has done until then. > > The developer would get a clear error message, with a gdb stack trace, > when this occurs. > > Note that this is different from the way a zero size is handled in > memcpy(), > memset(), et al. > (cf. > <https://lists.gnu.org/archive/html/bug-gnulib/2024-10/msg00032.html>). > There, applications don't risk to run into memory leaks or errors when > memcpy() starts to support a zero size in the obvious way. The realloc() > situation is special because of (A), (B), (C), (D). > > Bruno > > > -- <https://www.alejandro-colomar.es/>
signature.asc
Description: PGP signature