Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Release UDP port used by dead process on OS X

I am on OS X 10.11.6 and trying to run a program that normally listens on UDP port 8008 upon startup.

This program normally also spawns a couple of helper child processes during its operation, but the port is bound by the parent process.

Unfortunately when exiting the program, sometimes the port remains open, even though the program (parent + children) no longer exist.

When this happens, if I try to run the program again it naturally fails with a EADDRINUSE error, and in these cases no matter what I try, the only solution I found was to reboot the machine.

I'm having a hard time believing that I cannot release the port without a reboot.

Here are some diagnostics that I ran so far (I ran all of these with and without sudo):

Find the process using port 8008 with lsof:

$ lsof -i -n -P | grep UDP | grep 8008 

But surprisingly doesn't return any results.

However, I had more luck with netstat:

$ netstat -tulnvp udp | grep 8008 udp4  0  0  *.8008    *.*    196724   9216  47205   0 

So, the port is indeed bound, and the culprit is pid 47205, however:

$ ps aux | grep 47205 

Doesn't return anything. The same thing for PIDs 47206 and 47207 (most certainly the PIDs assigned to the children). I also tried other variations of the grep (program name, path, etc).

I also looked for any process reporting 47205 as its parent:

$ ps -axo pid,ppid,command | grep 47205 

So the children processes are also clearly dead.

Not being able to kill anything, I tried to SIGHUP launchd in the hope that it might remove any zombie child processes:

$ sudo kill HUP 1 $ sudo kill -s HUP 1 

But alas, netstat still shows the port bound.

Lastly, I tried to restart the loopback interface:

$ sudo ifconfig lo down $ sudo ifconfig lo up 

But again, to no effect.

I have waited several hours since the program last ran, so I'm pretty sure any timeout would have happened by now, but the port just won't get released.

Any ideas on how to force release the port without a reboot?

Edit:

  • The program in question is the electron-wrapped Patchwork.
  • This question originates from this github issue.
  • Although finding a solution/bugfix that prevents the issue from ocurring in the first place would be ideal, I'm also interested in ways to manually close that port from the terminal
like image 909
ktorn Avatar asked Nov 09 '16 17:11

ktorn


People also ask

How do you know which process is running on a port in Mac?

You can find out what is running on a specific port by running the command lsof -i with the port number, :<PortNumber> .


1 Answers

In your code, after you create the socket, but before the bind call, invoke the following:

int val = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); 

Then call bind. The above will allow the socket bind to succeed even if the port is in use.

Two processes, attempting a recvfrom on the same port, will result in one of the processes receiving the packet, but not the other. And it's not deterministic which one will. So make sure you don't actually have two processes legitimately running and sharing the port.

like image 158
selbie Avatar answered Oct 05 '22 14:10

selbie