This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Cygrunsrv and spawned processes


Corinna Vinschen wrote:

*snip*

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?

Hey Corinna,


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...
____________________________________________________________
$ ./jabberd/jabberd.exe
C:\cygwin\tmp\jabberd-1.4.3\jabberd\jabberd.exe: *** heap allocated but not at 0
x100F0000
972 [main] jabberd 1984 sync_with_child: child 1400(0x694) died before initi
alization with status code 0x1
14134 [main] jabberd 1984 sync_with_child: *** child state waiting for longjmp


20031205T22:35:39: [notice] (-internal): initializing server
20031205T22:35:39: [alert] (dnsrv): dnsrv failed to start, unable to fork and/or
create pipes
____________________________________________________________


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
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]