Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Out of file descriptors should be handled more gracefully #1510

Closed
LinuxJedi opened this issue Oct 2, 2014 · 8 comments
Closed

Out of file descriptors should be handled more gracefully #1510

LinuxJedi opened this issue Oct 2, 2014 · 8 comments

Comments

@LinuxJedi
Copy link

If you call uv_loop_new() and are out of file descriptors there is a chance it will either return NULL or abort(). It should return NULL every time (preferably have some kind of error to handle too) and let the application deal with the problem.

You should be able to reproduce this by calling uv_loop_new() in an endless loop, but there is a chance you could run an application using libuv when you are near the FD limit.

@txdv
Copy link
Contributor

txdv commented Oct 2, 2014

I won't ask what operating system you are using, because it is quite obvious since your name is @LinuxJedi, but please people, provide this kind of information.

And... you probably have already written a test case, the simple while loop. Why not throw it in here?

@LinuxJedi
Copy link
Author

I apologise, I was in a rush to file this whilst it was still in my head and had to go out.

Yes, it is Arch Linux with libuv 0.10.28 (although a quick browse of code shows it is probably still a problem with the 1.0.0rc).

I have a complicated test case, I'll quickly knock up a simple one for you now

@LinuxJedi
Copy link
Author

Here we go. This will trigger the abort every time for me, increasing "ulimit -n" lets this run for longer.

#include <uv.h>
#include <stdio.h>
#include <stddef.h>

int main(void)
{
  int counter= 0;
  while(1)
  {
    counter++;
    printf("Loop iteration %d\n", counter);
    if (uv_loop_new() == NULL)
    {
      printf("Loop alloc failed\n");
    }

  }
}

What I would expect is when the FD limit is hit uv_loop_new() would return NULL, and in some cases (an odd number of FDs remaining for example), it does happen. That is difficult to get in a repeatable test case.

Actual output (using gdb) with an FD limit of 2048 is:

...
Loop iteration 511

Program received signal SIGABRT, Aborted.
0x00007ffff7843967 in raise () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff7843967 in raise () from /usr/lib/libc.so.6
#1  0x00007ffff7844d3a in abort () from /usr/lib/libc.so.6
#2  0x00007ffff7bc06d5 in uv__loop_init (loop=0xbb5f10, default_loop=0)
    at src/unix/loop.c:76
#3  0x00007ffff7bbb9a3 in uv_loop_new () at src/unix/core.c:249
#4  0x0000000000400722 in main ()

@LinuxJedi
Copy link
Author

for me, "ulimit -n 2048" will trigger the abort, "ulimit -n 2047" will behave as I would expect.

@saghul
Copy link
Contributor

saghul commented Oct 3, 2014

We could indeed do a bit better here. Are you up for writing a patch? Note that we might need to initialize some stuff a bit earlier to avoid creating handles, since we need to destroy the loop.

Also, as a side note, uv_loop_new is deprecated in 1.0, you should use uv_loop_init now.

@LinuxJedi
Copy link
Author

sure, but I might not be able to get it done until early next week.

I do want to migrate libAttachSQL to use libuv 1.0 eventually, but a majority of current Linux distros are still on the 0.10 series so it could cause additional packaging headaches for me if I upgrade now.

@saghul
Copy link
Contributor

saghul commented Oct 3, 2014

No worries. I'd say this is a "bug fix" so we can apply it when ready.

@saghul
Copy link
Contributor

saghul commented Nov 26, 2014

Closing, continues on #1522

@saghul saghul closed this as completed Nov 26, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants