There's an example in newlocale man page that calls freelocale before calling exit(). It looks like uselocale is taking ownership of the loc object and is freeing it during process destruction. It can be seen by running the example under valgrind. ==8895== Invalid read of size 8 ==8895== at 0x4FB0188: _nl_locale_subfreeres (in /lib64/libc-2.27.so) ==8895== by 0x4FAFF08: free_mem (in /lib64/libc-2.27.so) ==8895== by 0x4FB0879: __libc_freeres (in /lib64/libc-2.27.so) ==8895== by 0x4A2968C: _vgnU_freeres (vg_preloaded.c:77) ==8895== by 0x4E74891: __run_exit_handlers (in /lib64/libc-2.27.so) ==8895== by 0x4E748C9: exit (in /lib64/libc-2.27.so) ==8895== by 0x108B08: main (tmp.c:68) ==8895== Address 0x596a320 is 0 bytes inside a block of size 238 free'd ==8895== at 0x4C3011B: free (vg_replace_malloc.c:530) ==8895== by 0x108AFE: main (tmp.c:67) ==8895== Block was alloc'd at ==8895== at 0x4C2EEEF: malloc (vg_replace_malloc.c:299) ==8895== by 0x4E68A5A: newlocale (in /lib64/libc-2.27.so) ==8895== by 0x1089B3: main (tmp.c:27) I guess that "freelocale(loc);" line should be removed from the example. OS: Gentoo Linux glibc version: 2.27-r6
FWIW if the same test is run in a thread one will need to call freelocale. Maybe the locale should be changed before it's freed. Maybe the cleanup code should look as follows: uselocale(LC_GLOBAL_HANDLE); freelocale(loc); exit(EXIT_SUCCESS);
(In reply to piotr from comment #1) > FWIW if the same test is run in a thread one will need to call freelocale. > Maybe the locale should be changed before it's freed. Maybe the cleanup code > should look as follows: > uselocale(LC_GLOBAL_HANDLE); > freelocale(loc); > > exit(EXIT_SUCCESS); Thanks for the report and that further info. It looks like you are correct. Grepping the Fedora package source code, I see a number of instances of that pattern. I applied the patch below. Closing this report now. --- a/man3/newlocale.3 +++ b/man3/newlocale.3 @@ -366,6 +366,7 @@ main(int argc, char *argv[]) /* Free the locale object */ + uselocale(LC_GLOBAL_HANDLE); /* So 'loc' is no longer in use */ freelocale(loc); exit(EXIT_SUCCESS);