Closed radj closed 7 years ago
Does it exit properly when you use the -t
ssh paramerter (Force pseudo-terminal allocation)?
Ex: ssh -t root@localhost 'Clutch -d 1'
@eschultz That worked! It exits with an extra message that goes Connection to localhost closed.
but it's good enough for me.
This is not really resolved then. Clutch should work over SSH without a pseudo-terminal.
@Tatsh I see. I closed it as it was sufficient enough for me. Can you guide me how to fix this? Would love to fork and contribute but I am not that familiar with TTY and pseudo-terminal concepts although I am a little familiar with pipes and EOF.
Keep trying with SSH without -t
. Put debug lines in the code. Something in Clutch is making a call that requires a PTY.
See man 3 isatty
. isatty(STDOUT_FILENO)
(and STDERR_FILENO
) will return 0
(false) when there is no PTY.
Thanks. Should be enough to get me started.
This is because Clutch is leaving file handles open to stdin, stderr, stdout. OpenSSH will not exit until every single handle to these is closed on the process that ran, even after the process exits.
If you modify main.m
and main()
to have this:
int main (int argc, const char * argv[])
{
fclose(stdin);
fclose(stderr);
fclose(stdout);
// ...
}
Then you will get no output, and SSH will exit properly once Clutch is done. Putting these lines at the end of main()
does not work. My theory on that is that the operation queue is also leaving open handles in any threads, even after they exit. Every *Operation
class must be modified to close these handles and maybe then it will work? That includes anything else that is launched in a thread and prints to stdout/sterr (whether that is using printf
, NSLog
, etc).
self.completionBlock = ^{
fclose(stdin);
fclose(stderr);
fclose(stdout);
};
With the existing version, to not use -t
, you can use < /dev/null >& /dev/null
after your clutch
command: ssh root@localhost -p 2222 './clutch -d 115 < /dev/null >& /dev/null'
. This is mainly if you are limited by an API that does not support an equivalent to -t
. Otherwise use -t
with ssh
.
More details: http://www.snailbook.com/faq/background-jobs.auto.html
This is fixed with #153. Re-exploring the issue can be another TODO.
True fix is something to do with how NSOperationQueue
works. I thought it used normal threads, but now it appears it's akin to forking. In any case, when the multitude of things (frameworks, etc) are dumped (via the forking mechanism), those background processes (regardless of success) exit without closing stdout/stderr descriptors, and this makes SSH hang.
When frameworks are involved, this is where Clutch is re-invoked: https://github.com/Tatsh/Clutch/blob/master/Clutch/FrameworkDumper.m#L218
Should be reopened as this is not solved for iOS 9.3.3. Solved for iOS 10.1.1.
I no longer have an iOS 9 device. This issue seems to be gone with iOS 10.
If running Clutch from inside an SSH session, it works fine and exits. However, if I use Clutch as parameter to SSH, it doesn't seem to quit. Ex:
ssh root@localhost Clutch -d 1
When done this way,
Finished dumping com.app.bundle.id in x.x seconds
is printed but nothing happens after that and thessh
call doesn't exit. While the ssh call is still blocking, I tried opening another separatessh
session and checkedps -ax
but Clutch process is no longer there. The only way to exit the blocking ssh call is to press Ctrl+C.