X-Recipient: archive-cygwin AT delorie DOT com X-Spam-Check-By: sourceware.org Message-ID: <47D6056B.6000805@tlinx.org> Date: Mon, 10 Mar 2008 21:07:07 -0700 From: Linda Walsh User-Agent: Thunderbird 2.0.0.12 (Windows/20080213) MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Re: Bug: C-prog from Win dies in fork; gdb.exe also won't run References: <47D4A7E4 DOT 5070509 AT tlinx DOT org> <47D4B7D2 DOT 1F78DADB AT dessent DOT net> <47D4E892 DOT 1090305 AT tlinx DOT org> <47D50BB6 DOT EFB28302 AT dessent DOT net> In-Reply-To: <47D50BB6.EFB28302@dessent.net> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Brian Dessent wrote: > Linda Walsh wrote: > >> Perhaps -- you don't, but my first symptom of a problem was a simple cygwin >> program refusing to run from cmd.exe. At the same time, I'm having >> problems with 'bash' (or 'ash') as launched from windows as well -- in both >> cases, the programs "used to work", and now I see a cmd-window come up, > > I agree that it is potentially a bug if fork() spews errors, unless of > course it is being molested by some kind of BLODA type of interference. === It is Windows. It's most certainly being molested. I don't know anyone named BLODA. Was he the guy responsible for blowing off YODA? (don't know of any dark-side sys-call interfering progs either, but I admit to not being up on my latest knowledge of dark-siders). > However that is a different issue than the one that is the subject of > this message -- I still think we're talking about two totally unrelated > phenomina. ---- Willing to grant you that. Just coincidental that the fork "behavior" (how's that...) or however you spawn it is at the heart of the matter in both cases, though one's from a lack of proper fork etiquette, while the other's more choking on cygwin's imitation of a fork. >> So I'll go back to my first posted problem. Why can't I fork when >> running from cmd.exe if the binary I am running is in "\windows" or >> "\windows\system32" I'm not aware of there being special cases for \windows >> or \windows\system32 in Posix either. The Cygwin "bin" dir is first in my >> path, so cygwin libraries should be accessible via the path. > > I'm still not clear on the details here. --- Not clear?! With my elegant, concise and crystal description!?! But but but...it's on windows, so it has to be clear. (hey...if you can non sequitur, so can I). > You have a Cygwin wrapper > program that forks and execs a native Win32 binary, then itself exits. > This fails with fork errors if the wrapper is located in %windir% but > works otherwise? --- Well fails if in %windir%, or %windir%/system32 (originally ran into it when I tried putting in the dir, but doesn't work in "/windows" either. But also -- and this is important -- only fails if called directly by a Windows App. (no intervening cygwin program). I first ran into it when I was in (1)"WinZip (the GUI)" and opened a text file. A slight flicker of a CMD window with some hastily spit out error text, and the window closes...all in about a 3ms. Just slightly shorter than my attentionspan...or rather ability to read even 1 word in the window-blink. (2) Next tried same command in a Bash window. That worked "properly. (3) Next: start "cmd.exe" in the 'Bash' window (cmd launched -!- 'spawned' by bash...(that's just wrong...bash spawning win cmd.exe's ... *shiver*)). That worked -- no furking errors. (4) Next tried launching gvim on a ".txt" file sitting on my Desktop (so in ~/Desktop). Tried filenames (4a) with and (4b) without spaces in the filename, as I didn't know if that was related. Both gave me the flickering cmd window with some err-text in it (no help). So tried (5)'Run' -- another 'flicker' cmd window. Then tried running a (6) cmd.exe window direct from win (no intervening bash or cygwin 'protection' layer). That duplicated the error message in a non-disappearing window! Progress! It would give the error when invoking the program from either of the win dirs (win or sys32). The CWD seems to make no difference -- just the location of the binary file. So I wondered if the binary was munged. Went to the source dir where I had a copy of the "application" in question (the redirector). The md5's of the binaries (in /win, ..sys32, my appdir ("~/c/gvim"), were all the same. (6) Running the app under cmd.exe worked in my appdir. (7) I tried recompiling it; ("cc -Os gvim.c -s -o gvim.exe") -- making sure I had binary corresponding to source. Named it "mygvim.exe". It (7a) worked in my appdir, but if I copied it to and ran it in either of the winsys dirs (7b,c)(/win...or ../system32), it would fail. Next I verified (8) ash and (9) tcsh by invoking both from cmd.exe, then running the failure cases -- both locations. Both locations worked with both shells. So running any cygwin shell before running the "app", makes the fork problem "go away". Of course, running with strace (10) also "works" (spawns gvim window and exits). HOWEVER...attempting to run (11) "gdb" on mygvim FAILS, but in a different way. May be a different bug, but it is *related*. If I run (12) gdb directly on top of cmd.exe, (doesn't seem to matter what dir, it never gets to the program name). In fact, just invoking "gdb" directly under cmd gives a popup error window: "The application failed to initialize properly (0xc0000022). Click on OK to terminate the appliction". Trying to strace gdb also gives an immediate failure: C:\bin>strace gdb.exe --- Process 3600, exception C0000022 at 7C964ED1 There...now you've done it. You had me break 'gdb'. > Does it work if you use a native (MinGW) wrapper that > consists of just _execv("c:/path/to/vim.exe", argv)? What about a > simple shell wrapper that consists of "#!/bin/sh\ncygstart > /path/to/vim"? ---- The shell wrapper is going to work since it involves a cygwin shell layer. I'm 90% certain that the native _execv will work, since I have had no problems once I get past the fork...but...(getting out x86-abacus..) and changing only 1 thing at a time: using: char * const path="/Prog/Vim/gvim.exe"; execv(path,argv); fprintf(stderr, "Error exec'ing %s, errno=%d\n",path,errno); exit(2); // } // parent, hopefully, quietly exits.... exit(0); -------- "works" with no error message displayed". I could try a mingw version too, but since the cygwin version works, I'd be even more confident (98%) that it would work as well .... >> That is a "non-sequitur". > > Okay, let me rephrase: Often software that has a native Win32 port will > contain remnants of Unix terminology or features that do not work. --- Ah, thank you...separated by a common language...I tend to still use fork as a verb on windows, even though I've known, at least since the "90's" that Windows required spawning instead of forking to get a new process (and also, to get a "TRUE" fork, would be a a royal pain, involving duplicating all of the user's address space and creating a clone of the process -- basically writing all of the machinery of 'fork' manually -- not even being able to rely on paging in of files based off of "open" file descriptors, since MS-Win does it's binary locking based on disk-sectors. You'd have to find all of the current process's open files (open for being paged from, and their current name on disk (which may have changed since starting the original program, as "rename" works on active libraries and executables. I haven't done it, but can imagine it would be a major pain to get right. > Process creation on Windows is centered around the notion of creating a > new process with new PID and completely separate VM address space. I'll > call this primitive *spawning* from here on to avoid confusion. --- Ug...I really don't like fish that much. Between that and "spawn of the devil", it hasn't ever been a favorite syscall. > "in the background" is not a very precise technical term. In Win32, > when spawning a child the parent gets to choose: > .... > - whether to wait and block on the child terminating or to continue > executing independently > Note the last point is I think the crutial one here: it's the parent > that decides whether to wait or continue. The child has no control over > the behavior of the parent. ---- The child doesn't have much control over the parent on linux either. The parent can wait or not, can choose what to share (via clone), etc. > But as to "forking", what specifically does not exist anywhere in Win32, > and what Cygwin has to go through enormous hoops to emulate, is the > notion of *replacing* one process by another (exec) or *duplicating* one > process into two (fork). These have very different semantics than > spawning a new process, so that's why I find it very wrong to say that a > native Win32 program does anything resembling a "fork". ---- I hear what you are saying...yet did you know that MS improved fork and exec performance by 30% in their SFU Unix-compat layer? :-). I wonder what 'pains' they go through -- they might have it easier and just use straight NT calls rather than Win32. Dunno... > The exec() that Windows does have is just an elaboration of *spawning* > followed by the parent *exiting*. On the surface this may seem to be > the same as the POSIX exec but it's not -- the main difference being > that the child has a new and distinct PID as well as potentially other > per-process attributes[1]. In other words, the child was created as a > separate and new process, it did not take over in the shoes of the > parent. === Good point...exec doesn't change the PID. >> I'm pretty sure the "&" addendum in cmd.exe does something similar to this >> within cmd. The functionality seems to be there despite that the function >> may not be called "fork" nor have the exact same semantics of "fork". > > I think you're conflating what the parent does after the new process has > been created (i.e. whether to wait and block on the child to terminate > or not) with how the process was created. --- Since "Cmd.exe" is mostly a "blackbox" to me, any behavior occurring within Cmd, that "looks like" similar behavior in a linshell, is likely to be 'conflated. I don't know if cmd uses the 10-argument "CreateProcess", or does a "_spawnX(NOWAIT, prog, args....)". > >> It is not immediately evident where the splitting of the GUI >> process off into the background is done: whether in in cmd.exe or >> every windows program that can interactively launch processes, >> or in the processes themselves. > > I'm not sure I follow. Say you are a Win32 GUI executable. --- I'll try not to be insulted. :-) > You start > up, you create your windows, you interact with the user. At no point do > you control anything about the process that created you. Whether it > wants to wait or not for you to terminate is not something you (vim in > this case) have any control over. --- True, but cmd can choose to do a "spawn+wait" or it can choose to do a "spawn" w/nowait. The user either sees cmd effectively stopped, or sees an immediate return. For example, if I type run "wmined" (under bash), even though "wmined" can't control whether the parent waits or not -- it "effectively" does, by "spawning" off a "no-wait copy of itself and it exits. The effect or appearance is that "wmined" has controlled whether or not the shell "waits" by returning a "bogus" exiting process. > Well, two things. First, the reason you can't just ^Z is because you're > mixing native and Cygwin apps. If you used a Cygwin gvim (X11) then it > should work just as on *nix. ---- Well......I just tried a cygwin "find" on /prog for my name, pressed control-z several times -- it didn't stop until it finished. (it did respond to control-c, but I had cases where control-c didn't see to work either -- but those cases may have been winapps). Certainly, control-z didn't suspend. > Second, if typing is the issue then: alias gvim='gvim &' --- Might not be a bad idea -- though I'd rather hmmmm.... Well... at the very least, it would be nice to know why gdb and my baby-redirector both die. I mean the baby-redirect is pretty simple...but gdb doesn't even load (but does, of course, under any cygwin shell... >> Right -- I want the graphical program to launch and return control >> to the shell no matter what shell I am in without having to type &. "&" is >> embedded in my brain as "launch a long running process in background while >> I go do something in foreground. Editing doesn't fit into that paradigm. > > Then a wrapper script/wrapper program seems like the correct solution if > shell aliases are out. ---- May not be ... might be best solution ... my 'redirector' can still exec the gvim in the correct location (without the fork). > >> I hesitate to even suggest this, but maybe bash and other shells >> should have an option to detect non-cygwin GUI programs and launch them >> in background? It would give a consistent shell presentation on windows >> as well as between linux-and-cygwin. As it stand now, givm launched on >> linux launches in background. gvim launched via cmd.exe or the windows >> shell launches in background. The only place gvim doesn't launch >> automatically into the background is under a cygwin shell. > > Oh god no. That is going in the opposite direction of consistency with > linux. ---- I *did* say I was hesitating...:-). Let's put the gvim "mostly" on the back burner. At this point I'll just ask if you have an idea why 'gdb' won't start. From a 'completeness' point of view, I'm still wondering why I can't call fork in a cygwin program from windows. .. (have been a bit rushed today (and am now, so have to end this)...) I agree on this, though... >> If cygwin is intended to follow the linux in behavior, I assert, >> in this case, it is not and would be more compatible if it new a launched >> binary was a Windows-GUI program that would normally be launched in >> on windows (or, with its equivalent posix-GUI, on linux). > > You're trying to fix the wrong thing. Cygwin is acting exactly as *nix, > it's that native gvim that's out of line. On *nix if gvim had the > MAY_FORK stuff disabled you'd be in the same exact situation, except > that there is no shell on *nix that somehow sniffs binaries to see if > they are linked with X11 client libs. ---- Well -- I wasn't trying to fix the wrong thing "initially" -- I was trying to use cygwin to do the fork and then exec the windows application. I got hosed because of some weird error that appears to be within the cygwin library that caused the program to die instead of 'fork'.... So don't put me in a corner trying to fix the "wrong" thing. I thought a wrapper program was a perfect solution (as you seem to suggest as well). It just didn't work. FYI...here's that intransigent 'C' program: #include #include extern int errno; char * const path="/Prog/Vim/gvim.exe"; int main (int argc,char * const argv[]) { int p; p=fork(); if (p<0) { fprintf(stderr, "Error forking, errno=%d\n",errno); exit(1); } if (!p) { /* in child */ execv(path,argv); fprintf(stderr, "Error exec'ing %s, errno=%d\n",path,errno); exit(2); } // parent, hopefully, quietly exits.... exit(0); } And here is the path (with some line-breaks after the semi's) as it is setup in windows (before running any cygwin programs): C:\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem; C:\Prog\XP-Support Tools;C:\Prog\sysinternals;C:\Prog\Codeplay; C:\Prog\Common Files\GTK\2.0\bin;C:\Prog\QuickTime\QTSystem\; C:\bin\Windows;C:\Prog\SecureCRT\;C:\Prog\Microsoft Visual Studio\Tools Note -- "gdb" was executed with the same path listed above. -l -- 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/