Is wordexp in libc on OSX 10.9.5 known to leak?

2019-07-06 03:34发布

问题:

Is wordexp on OSX 10.9.5 known to leak memory? And if not, what is wrong with my code?

On my own local machine running OSX 10.10.5 I run my code through Valgrind and get no lost bytes.

No leaks on my Ubuntu Linux machine either.

However, when I turned on valgrind checks on my travis-ci account that uses OSX 10.9.5 I suddenly get a leak from memory allocated inside of wordexp even though I free it using wordfree as the man page describes:

==8968== LEAK SUMMARY:
==8968==    definitely lost: 1,024 bytes in 1 blocks
==8968==    indirectly lost: 0 bytes in 0 blocks
==8968==      possibly lost: 0 bytes in 0 blocks

OSX 10.9.5 uname output:

Darwin 13.4.0 Darwin Kernel Version 13.4.0: Sun Aug 17 19:50:11 PDT 2014; root:xnu-2422.115.4~1/RELEASE_X86_64 x86_64

OSX 10.9.5 sw_vers output:

ProductName:    Mac OS X
ProductVersion: 10.9.5
BuildVersion:   13F34

OSX 10.9.5 libc version 1197.1.1 otool -L /usr/lib/libSystem.dylib:

/usr/lib/libSystem.dylib:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

OSX 10.10.5 libc version 1213.0.0:

/usr/lib/libSystem.dylib:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)

Relevant code (Please use the link to the full code below if compiling): https://github.com/JoakimSoderberg/wordexp_test

static void xfree(void *p)
{
    void **pp;
    assert(p);

    pp = (void **)p;

    if (*pp)
    {
        free(*pp);
        *pp = NULL;
    }
}

char **test_wordexp(const char *cmdline, int *argc)
{
    char **argv = NULL;
    size_t i;
    int ret;
    wordexp_t p;
    memset(&p, 0, sizeof(p));

    // Note! This expands shell variables.
    if ((ret = wordexp(cmdline, &p, 0)))
    {
        fprintf(stderr, "wordexp error %d: '%s'\n", ret, cmdline);
        return NULL;
    }

    *argc = p.we_wordc;

    if (!(argv = calloc(*argc, sizeof(char *))))
    {
        fprintf(stderr, "Out of memory!\n");
        goto fail;
    }

    for (i = 0; i < p.we_wordc; i++)
    {
        if (!(argv[i] = strdup(p.we_wordv[i])))
        {
            fprintf(stderr, "Out of memory!\n");
            goto fail;
        }
    }

    wordfree(&p);

    return argv;

fail:
    wordfree(&p);

    if (argv)
    {
        for (i = 0; i < (size_t)*argc; i++)
        {
            xfree(&argv[i]);
        }

        free(argv);
    }

    return NULL;
}

Full code: https://github.com/JoakimSoderberg/wordexp_test

Travis job with failed OSX but successful Linux:

https://travis-ci.org/JoakimSoderberg/wordexp_test/builds/83194932

Exact line of OSX Travis job with leak error:

https://travis-ci.org/JoakimSoderberg/wordexp_test/jobs/83194937#L78

The wordexp is known on OSX for having used Perl in its implementation. But apparently doesn't any more.

  • Perl version
  • New verison

Also I did not manage to find the exact source code links that I know is found in the involved libc versions mentioned above.