-
Notifications
You must be signed in to change notification settings - Fork 183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pthread_create possible leak #552
Comments
It can be reproduced with a super minimal Lua module that does the same as the bare Libuv test code above: libuv_test.c #include <lua.h>
#include <lauxlib.h>
#include <uv.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
static void stat_cb(uv_fs_t* req) {
if (req->result < 0) {
printf("error %ld\n", req->result);
} else {
uv_stat_t* stat = &req->statbuf;
printf("size %" PRIu64 "\n", stat->st_size);
}
uv_fs_req_cleanup(req);
}
static int libuv_test(lua_State *L)
{
uv_fs_t req;
int ret;
ret = uv_fs_stat(uv_default_loop(), &req, "test.lua", stat_cb);
printf("stat %d\n", ret);
ret = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
printf("run %d\n", ret);
uv_loop_close(uv_default_loop());
return 0;
}
int luaopen_libuv_test(lua_State *L)
{
lua_pushcfunction(L, libuv_test);
return 1;
} test.lua local libuv_test = require('libuv_test')
libuv_test() Maybe related to dynamic library loading? Not sure what the difference would be otherwise. |
Does look to be libuv_dl.c #include <uv.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
static void stat_cb(uv_fs_t* req) {
if (req->result < 0) {
printf("error %ld\n", req->result);
} else {
uv_stat_t* stat = &req->statbuf;
printf("size %" PRIu64 "\n", stat->st_size);
}
uv_fs_req_cleanup(req);
}
void libuv_test(void) {
uv_fs_t req;
int ret;
ret = uv_fs_stat(uv_default_loop(), &req, "test.lua", stat_cb);
printf("stat %d\n", ret);
ret = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
printf("run %d\n", ret);
uv_loop_close(uv_default_loop());
} main.c #include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
int main() {
void *handle;
void (*libuv_test_fn)(void);
char *error;
handle = dlopen ("./libuv_dl.so", RTLD_NOW|RTLD_LOCAL);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}
libuv_test_fn = dlsym(handle, "libuv_test");
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(1);
}
(*libuv_test_fn)();
dlclose(handle);
} Also possibly of interest: |
The leak can be fixed in the example in the previous comment (#552 (comment)) by creating a thread from (note: simply linking against Not sure exactly what this means or how we should treat this. Still unsure why it wasn't being reported previously, will try testing with Valgrind 3.13.0 (the version that was being used on Travis CI previously) to see if it's reported there. EDIT: Valgrind 3.13.0 has a bug that makes it incompatible with newer versions of glibc, so I'm not able to test this easily. "fixed" main.c #include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <pthread.h>
void* thread_func(void * arg)
{
return NULL;
}
int main(int argc, char **argv) {
void *handle;
void (*libuv_test_fn)(void);
char *error;
pthread_t thread_id;
pthread_create(&thread_id, NULL, &thread_func, NULL);
pthread_join(thread_id, NULL);
handle = dlopen ("./libuv_dl.so", RTLD_NOW|RTLD_LOCAL);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}
libuv_test_fn = dlsym(handle, "libuv_test");
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(1);
}
(*libuv_test_fn)();
dlclose(handle);
} Valgrind output:
|
Yeah, seems to be fixed. 👍 |
In setting up CI with Github Actions (#551), the valgrind step is reporting leaks (and I can reproduce the leaks locally). It happens with multiple tests (not sure of everything that triggers it yet), and is not only related to the thread bindings. For example, here's the reported leak after running
test-fs.lua
(with luajit):This can also be reproduced with a minimal file:
However, I cannot reproduce it with a theoretically similar test case when using Libuv directly:
I'm really unsure what's happening here, or why it's just showing up now. For now, I've added a suppression for these possible leaks in the CI just to get that passing, but it would be nice to figure out if this is a real leak that we should be addressing.
The text was updated successfully, but these errors were encountered: