Hi, Calling 'fts_close' immediately after 'fts_open' causes error in valgrind: $ valgrind --track-origins=yes --tool=memcheck --leak-check=yes --show-reachable=yes ./ftstest ==76510== Memcheck, a memory error detector ==76510== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==76510== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==76510== Command: ./ftstest ==76510== ==76510== Conditional jump or move depends on uninitialised value(s) ==76510== at 0x4EA2297: fts_close (in /lib/libc.so.7) ==76510== by 0x4008D9: main (in /root/fts/ftstest) ==76510== Uninitialised value was created by a heap allocation ==76510== at 0x4C245B1: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so) ==76510== by 0x4EA1F01: fts_open (in /lib/libc.so.7) ==76510== by 0x40089E: main (in /root/fts/ftstest) ==76510== ==76510== ==76510== HEAP SUMMARY: ==76510== in use at exit: 0 bytes in 0 blocks ==76510== total heap usage: 5 allocs, 5 frees, 2,647 bytes allocated ==76510== ==76510== All heap blocks were freed -- no leaks are possible ==76510== ==76510== For counts of detected and suppressed errors, rerun with: -v ==76510== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) ftstest.c ========= #include <fts.h> #include <stdio.h> #include <sys/stat.h> int main(void) { FTS *fts; FTSENT *e; char *path = "/etc"; char * const path_argv[] = { path, NULL }; if ((fts = fts_open(path_argv, FTS_LOGICAL, NULL)) == NULL) { printf("fts_open error: %s\n", path); return (1); } fts_close(fts); return (0); } If 'fts_read' is called before 'fts_close' no complaints from vagrind. + while ((e = fts_read(fts)) != NULL) { + printf("name: %s, mtime: %ld\n", e->fts_name, e->fts_statp->st_mtime); + } I don't know if its related but I found same issue in GNU maillist: https://lists.gnu.org/archive/html/bug-gnulib/2018-05/msg00117.html
With a debug build of libc I get ==1494== Conditional jump or move depends on uninitialised value(s) ==1494== at 0x48F29D7: fts_close (lib/libc/gen/fts.c:256) ==1494== by 0x2019B6: main (ftstest.c:17) ==1494== Uninitialised value was created by a heap allocation ==1494== at 0x484CBC4: malloc (vg_replace_malloc.c:397) ==1494== by 0x48F2606: fts_alloc (lib/libc/gen/fts.c:1022) ==1494== by 0x48F2606: fts_open (lib/libc/gen/fts.c:195) ==1494== by 0x20197E: main (ftstest.c:13) fts_open does this struct _fts_private *priv; if ((priv = calloc(1, sizeof(*priv))) == NULL) return (NULL); sp = &priv->ftsp_fts; if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL) where the first member of _fts_private is FTS ftsp_fts; meaning p[riv and sp are equivalent addresses. And the error code is if (sp->fts_cur) { for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { // ERROR It's what p points to that is not initialized: gdb) p p $5 = (FTSENT *) 0x54652d0 (gdb) p sizeof(*p) $6 = 152 (gdb) mo check_memory defined 0x54652d0 152 Address 0x54652D0 len 152 not defined: Uninitialised value at 0x54652D0 was created by a heap allocation ==1649== at 0x484CBC4: malloc (vg_replace_malloc.c:397) ==1649== by 0x48F2606: fts_alloc (lib/libc/gen/fts.c:1022) ==1649== by 0x48F2606: fts_open (lib/libc/gen/fts.c:195) ==1649== by 0x20197E: main (ftstest.c:13) Address 0x54652d0 is 0 bytes inside a block of size 377 alloc'd ==1649== at 0x484CBC4: malloc (vg_replace_malloc.c:397) ==1649== by 0x48F2606: fts_alloc (lib/libc/gen/fts.c:1022) ==1649== by 0x48F2606: fts_open (lib/libc/gen/fts.c:195) ==1649== by 0x20197E: main (ftstest.c:13) [using vgdb and the monitor command] As far as I'm concerned it's a bug in fts_open.