This is the mail archive of the
mailing list for the Cygwin project.
Re: Cygrunsrv and spawned processes
Corinna Vinschen wrote:
This tells me that cygrunsrv is not giving you a full environment within
which to run the app. I've looked into spawnlp() and the P_NOWAIT mode,
It gives you the system environment plus everything specified by the -e
option. Where else should it get its environment from?
Sorry, poor choice of words. Basically, cygrunsrv does not provide a
shell within which to run the app. Better? :-) I'm afraid I didn't
know quite how to word this.
Anyway, I'm grasping at straws. I'd just love to get this working
properly without leftover processes building up. Any more
thoughts/ideas I can try? I'll give anything a whack. :-)
I'm guessing that jabber is by default using fork/exec. Why didn't
you just leave it this way?
Actually, no, not in the DNS portion. Bear in mind I was working with
code written long before I got involved with Jabber/XMPP. Jabberd 1.4.x
relies on GNU Pth to do its threading, with 2 exceptions: one call in
the base portion of code, and one call in the dnsrv (DNS resolver)
portion. The base code (for Linux/BSD/etc.) does use fork(), but it
seems that--along with the lack of BIND/libresolv under Cygwin as a
package--fork() was problematic at the time, so the dnsrv code was
apparently overhauled for Cygwin, using spawnlp() instead of fork(),
with several other minor mods done.
Now, with the recent introduction of minires as a proper Cygwin package,
I tried again yesterday to build Jabberd v1.4.3 using the original code
(i.e., no Cygwin-specific source w/ spawnlp(), etc.). I _WAS_ able to
build Jabberd once I added -lresolv to LIBS and made a few minor
adjustments to Makefiles, notably adding an EXPORT value to the main
executable so the dnsrv module could 'see' certain variables.
Unfortunately, upon firing up Jabberd, I get...
C:\cygwin\tmp\jabberd-1.4.3\jabberd\jabberd.exe: *** heap allocated but
not at 0
972 [main] jabberd 1984 sync_with_child: child 1400(0x694) died
alization with status code 0x1
14134 [main] jabberd 1984 sync_with_child: *** child state waiting
20031205T22:35:39: [notice] (-internal): initializing server
20031205T22:35:39: [alert] (dnsrv): dnsrv failed to start, unable to
And it hangs so bad that CTRL-C will not kill it. I have to use the
Windows Task Manager to kill the process outright (I assume 'kill -9'
from another BASH shell would work as well).
It took me awhile to track this down to the fork() call in dnsrv, but
that is definitely where this occurred. I added some debug code just
before/after the fork(), then ran Jabberd in debug mode (its debug mode,
not gdb, where it outputs text to a file) to confirm. Tried Googling on
the error messages about heap allocation and sync_with_child, but not
much out there at all.
After noting some info about DLLs not loading where they should, I tried
using Jason Tishler's rebase tool (copy/rewritten version of 'rebaseall'
to rebase the DLLs in Jabber, not the one that only works on the Cygwin
DLLs), but no good. So any thoughts/ideas on where to look next would
be greatly appreciated.
A look into the jabberd sources should give a hint which signal is
expected. In theory there should be a signal handler which then cares
for jabberd's child process. Assuming it is a SIGHUP handler, send
SIGHUP from cygrunsrv.
Well, using signal() they have mapped functions to handle SIGHUP,
SIGINT, and SIGTERM. I've tried sending SIGINT (what you effectively do
when hitting CTRL-C), SIGHUP, SIGTERM, you name it. Also tried adding
every env var I could think of to the cygrunsrv --install command to
match the BASH shell, in case there was something there I was missing.
>Cygrunsrv has no idea about child processes
started from it's inferior process. It's the responsibility of that
process to care for its children. This is different from the situation
in the shell where a Ctrl-C results in a SIGINT sent to all processes
not detached from the console. A process started with spawn(_P_NOWAIT)
is not detached from the console.
BINGO! This is EXACTLY the reason then. So my statement stands. There
most definitely IS a difference between running a Cygwin app under a
shell vs. via cygrunsrv. And you just pointed it out.
This is what I wanted to know. Now the question is, is there any way to
get similar behavior to what you get with a shell like BASH? I've tried
having cygrunsrv run a shell within which to launch Jabberd, but all I
end up is the shell dying and BOTH jabberd.exe and jabadns.exe left
behind. So I'm guessing that sending a SIGINT from cygrunsrv to a BASH
shell is also different than doing it manually, as it does not propogate
(or whatever technical term you wish to throw at it). The BASH shell
does NOT react the same way under cygrunsrv as it does normally.
I realize one way is to modify the source to have the main process kill
the child, but that's a bit of code change.
I was wondering, how hard would it be to have cygrunsrv provide the same
functionality as a full shell? That is, this issue does not occur under
Linux, even when Jabberd is run as a daemon on startup, so it's
definitely a Cygwin/cygrunsrv-specific issue. Are there any plans to
offer such functionality? Just curious.
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html