-
-
Notifications
You must be signed in to change notification settings - Fork 661
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
execve() requires parent process to be cosmo program on windows #1253
Comments
I see the same error message as well trying to double click. It seems certain calls just don't work: #1329 (reply in thread) Somehow whenever you try to call up another executable from the system directly it faults like this. |
Have you tried doing this with a hello world binary? I just compiled with msvc the program |
The only way this does work is opening a cmd first and running Test.exe, then the last system call will return the expected help text from dotnet.exe, but using double click method that call produces an error as marked in the comments. Normally, for a path registered application like dotnet.exe just running the associated |
Calling notepad.exe works fine. Tried calling cmd.exe, powershell.exe, py.exe, all fail with that error. Tried calc.exe, works. It would appear any gui apps work just fine. It's the stuff that runs shells or open one that fail. Like I can't even get it to spawn another cmd.exe instance, but only when doing double click, from existing cmd it's working totally fine. So I figured I'd try creating a shortcut to cmd.exe and tell that to run my Test.exe and yeah that predictable works fine as well. Something about it directly trying to open a cmd with a double click just makes it upset, but that's kind of a useful functionality to have. For me anyways. |
OK I'm able to reproduce this error if I run the following on the Cosmopolitan Bash shell:
Investigating... |
Also for what it's worth, 0xc0000142 means |
OK if you call execve() then the parent process needs to be a program you've compiled using cosmo. I'm 99% certain that execv() isn't the API you wanted. You almost certainly want to be using either |
posix might work for my case, once I figure out how to use it (not a C dev). My use case is simple. On windows: Double click Start.exe -> spawn a cmd.exe or linux terminal -> run Doing a It does create a new cmd window when double clicking it, but the environment in it is missing something so when calls for another cmd.exe or powershell.exe are made they fail to start with that error. From what I'm reading posix or fork might "break out" of that environment down to the base system, which then might be able to run dotnet. Did I understand that correctly? In other words I'm basically doing what a windows shortcut to cmd.exe with |
Goodness I think I broke my brain, but yes indeed posix does work!
Yes you may beat me for that, C is really not my thing, but I have double click start working and both cli run too(falling back to system call on linux). Thanks for all the help :) |
If you don't mind it going a tiny bit slower, you can always say: if (!fork()) {
execv("prog.exe", (char *[]){"prog.exe", "arg", 0});
_Exit(127);
}
wait(0); |
There's also: systemvpe("cmd.exe", (char *[]){"cmd.exe", "/c", "echo hi", 0}, environ); Which will do a path search. |
I tried that, but it would not compile saying the function doesn't exist. Same with the environ variable. |
You need to include cosmo.h (and I also recommend passing |
Oh yes that compiles, thank you :) I tried Doing |
I ran into a similar issue where using #include "libc/cosmo.h"
#include <stdlib.h>
int main(int argc, char *argv[]) {
systemvpe("cmd.exe", (char *[]){"cmd.exe", "/c", "echo Hi", 0}, environ);
return 0;
} ... which, turned into an APE using the current cosmo release and run on Windows 11 in a vanilla cmd.exe shell/session, produces this result: C:\Users\Johannes\Downloads>exectest.com
C:\Users\Johannes\Downloads>exectest.com --strace
SYS 2140 1916 1'918'795 mmap(0x6fe000000, 65'536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0) → 0x6fe000000 (8'835'072 bytes total)
SYS 2140 1916 2'042'418 getenv("_COSMO_FDS_V2") → NULL
SYS 2140 1916 2'062'902 getenv("COSMOPOLITAN_DISABLE_ZIPOS") → NULL
SYS 2140 1916 2'083'307 issetugid() → 0
SYS 2140 1916 2'100'380 getenv("COSMOPOLITAN_INIT_ZIPOS") → NULL
SYS 2140 1916 2'117'747 GetProgramExecutableName() → "/C/Users/Johannes/Downloads/exectest.com"
SYS 2140 1916 2'283'683 mmap(0, 16, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) → 0xe6293900000 (8'839'168 bytes total)
SYS 2140 1916 2'345'046 mmap(0, 40, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED, -1, 0) → 0xe6293910000 (8'843'264 bytes total)
SYS 2140 1916 2'391'137 openat(AT_FDCWD, "/C/Users/Johannes/Downloads/exectest.com", O_RDONLY) → 3
SYS 2140 1916 2'535'686 fstat(3, [{.st_size=274'578, .st_blocks=278'528/512, .st_mode=0100775, .st_uid=11638, .st_gid=11638, .st_dev=0xd6d2675e, .st_ino=0x13000000003293, .st_flags=20}]) → 0
SYS 2140 1916 2'618'828 mmap(0, 274'578, PROT_READ, MAP_SHARED, 3, 0) → 0xe6293920000 (9'121'792 bytes total)
SYS 2140 1916 2'676'530 mmap(0, 8, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) → 0xe6293970000 (9'125'888 bytes total)
SYS 2140 1916 2'736'032 munmap(0xe6293910000, 40) → 0 (9'121'792 bytes total)
SYS 2140 1916 2'790'007 munmap(0xe6293900000, 16) → 0 (9'117'696 bytes total)
SYS 2140 1916 2'843'245 close(3) → 0
SYS 2140 1916 2'887'210 __zipos_get("/C/Users/Johannes/Downloads/exectest.com") → 0
SYS 2140 1916 2'930'495 GetSymbolTableFromZip() → 0
SYS 2140 1916 2'974'527 issetugid() → 0
SYS 2140 1916 3'017'495 getenv("COMDBG") → NULL
SYS 2140 1916 3'059'794 GetProgramExecutableName() → "/C/Users/Johannes/Downloads/exectest.com"
SYS 2140 1916 3'155'841 openat(AT_FDCWD, "/C/Users/Johannes/Downloads/exectest.com.dbg", O_RDONLY|O_CLOEXEC) → -1 ENOENT
SYS 2140 1916 3'237'292 openat(AT_FDCWD, "/C/Users/Johannes/Downloads/exectest.com.com.dbg", O_RDONLY|O_CLOEXEC) → -1 ENOENT
SYS 2140 1916 3'367'379 mmap(0, 16, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) → 0xe6293980000 (9'121'792 bytes total)
SYS 2140 1916 3'432'503 mmap(0, 40, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED, -1, 0) → 0xe6293990000 (9'125'888 bytes total)
SYS 2140 1916 3'483'940 openat(AT_FDCWD, "/C/Users/Johannes/Downloads/exectest.com", O_RDONLY|O_CLOEXEC) → 3
SYS 2140 1916 3'541'653 lseek(3, 0, SEEK_END) → 274'578
SYS 2140 1916 3'610'192 mmap(0, 274'578, PROT_READ, MAP_PRIVATE, 3, 0) → 0xe62939a0000 (9'404'416 bytes total)
SYS 2140 1916 3'659'218 OpenSymbolTable() ENOEXEC
SYS 2140 1916 3'713'437 munmap(0xe62939a0000, 274'578) → 0 ENOEXEC (9'125'888 bytes total)
SYS 2140 1916 3'768'488 munmap(0xe6293990000, 40) → 0 ENOEXEC (9'121'792 bytes total)
SYS 2140 1916 3'824'203 munmap(0xe6293980000, 16) → 0 ENOEXEC (9'117'696 bytes total)
SYS 2140 1916 3'875'081 close(3) → 0 ENOEXEC
SYS 2140 1916 3'898'858 getenv("HOME") → "/C/Users/Johannes"
SYS 2140 1916 3'915'790 getenv("TMPDIR") → NULL
SYS 2140 1916 3'931'216 getenv("TERM") → "xterm-256color"
SYS 2140 1916 3'959'720 mmap(0, 65'536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) → 0xe62939f0000 (9'183'232 bytes total)
SYS 2140 1916 4'025'533 getenv("PATH") → "/C/WINDOWS/system32:/C/WINDOWS:/C/WINDOWS/System32/Wbem:/C/WINDOWS/System32/WindowsPowerShell/v1.0/:/C/WINDOWS/System32/OpenSSH/:/C/Users/Johannes/AppData/Local/Microsoft/WindowsApps:"
SYS 2140 1916 4'157'576 faccessat(AT_FDCWD, "/C/WINDOWS/system32/cmd.exe", 04000000000, 0) → 0 ENOENT
SYS 2140 1916 4'226'115 fstatat(AT_FDCWD, "/C/WINDOWS/system32/cmd.exe", [{.st_size=339'968, .st_blocks=339'968/512, .st_mode=0100775, .st_nlink=2, .st_uid=11638, .st_gid=11638, .st_dev=0xd6d2675e, .st_ino=0x1500000000ac25, .st_flags=20}], 0) → 0 ENOENT
SYS 2140 1916 4'250'367 sigprocmask(SIG_BLOCK, {INT,QUIT,CHLD}, [{}]) → 0
SYS 2140 1916 4'269'633 pthread_atfork(prepare, 423990)
SYS 2140 1916 4'286'926 pthread_atfork(prepare, 4147d0)
SYS 2140 1916 4'343'042 mmap(0, 192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) → 0xe6293a00000 (9'252'864 bytes total)
SYS 2140 1916 4'395'276 GetProgramExecutableName() → "/C/Users/Johannes/Downloads/exectest.com"
SYS 2140 1916 22'315'473 pthread_atfork(parent, 414770)
SYS 2140 1916 22'490'353 pthread_atfork(parent, 4239c0)
SYS 2140 1916 22'539'177 fork() → 9132 (took 48613 us)
SYS 2140 1916 22'567'193 sigaction(SIGINT, {.sa_handler=SIG_IGN}, [{.sa_handler=SIG_DFL}]) → 0
SYS 2140 1916 22'591'833 sigaction(SIGQUIT, {.sa_handler=SIG_IGN}, [{.sa_handler=SIG_DFL}]) → 0
SYS 9132 9848 12'772'255 pthread_atfork(child, 4145c0)
SYS 9132 9848 12'867'126 pthread_atfork(child, 423960)
SYS 9132 9848 12'953'992 fork() → 0 (child of 2140; took 51101 us)
SYS 9132 9848 12'996'680 sigprocmask(SIG_SETMASK, {}, [NULL]) → 0
SYS 9132 9848 13'081'637 execve("cmd.exe", {"cmd.exe", "/c", "echo Hi", NULL}, {"=::=::\\", "=C:=C:\\Users\\Johannes\\Downloads", "=ExitCode=00000000", "ALLUSERSPROFILE=/C/ProgramData", "APPDATA=/C/Users/Johannes/AppData/Roaming", "CLIENTNAME=ryzealot", "COMMONPROGRAMFILES=/C/Program Files/Common Files", "COMMONPROGRAMFILES(X86)=/C/Program Files (x86)/Common Files", "COMMO...)
SYS 2140 2272 22'337'199 mmap(0, 4'032, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) → 0xe6293a10000 (9'256'960 bytes total)
SYS 9132 9848 13'241'966 execve("cmd.exe") failed -1 ENOENT
SYS 9132 9848 13'305'979 _Exit(127)
SYS 2140 1916 26'078'652 wait4(9132, [0x7f00], 0, 0) → 9132
SYS 2140 1916 26'150'820 sigaction(SIGQUIT, {.sa_handler=SIG_DFL}, [NULL]) → 0
SYS 2140 1916 26'178'339 sigaction(SIGINT, {.sa_handler=SIG_DFL}, [NULL]) → 0
SYS 2140 1916 26'203'565 sigprocmask(SIG_SETMASK, {}, [NULL]) → 0
SYS 2140 1916 26'233'198 exit(0)
SYS 2140 1916 26'299'743 _Exit(0) ... with the relevant line, I guess, being Executing I am not sure what's wrong or going on - could my Windows 11 environment I am trying this in somehow be borked? Is the minimal example I tried to get to run wrong? Is there a problem in I'd be very keen to read your thoughts on the issue. |
Thanks for reporting this. I just pushed a fix for systemvpe() and added a test too. |
I've changed my mind. We shall fix execve() so that it lingers when process reparenting isn't possible. |
Contact Details
jcbhmr@outlook.com
What happened?
When running a binary (ex.
execvnode.exe
) that usesexecv()
in the PowerShell terminal on Windows 10 it doesn't print anything. However, if I spawn the binary as a subprocess then suddenly the output does appear, but only after the main process has finished.Here's an example
main.c
file:In theory this should act sorta like a symlink to run Node.js on Windows. I could open up PowerShell and run
.\execvnode.exe --version
and it would spit out the version, right?It doesn't. It also exits with an error but with no output text.
If you run it via a cmd terminal instead you get a weird error message. Though I think that's the
node.exe
binary from the title of the alert box? But somehow it breaks in cmd...but ONLY when its the top-level cmd. Using
cmd
in PowerShell window to start a cmd session inside the powershell graphical window successfully runs it but does a weird print-after-exit thing.if you spawn it as a double subprocess it seems to print its own output after it has exited somehow.
Note that the "v20.11.0" is after the parent PowerShell process has already printed the next prompt line.
Example real-world scenario using
ptime
(atime
similar-ish command for Windows https://community.chocolatey.org/packages/ptime)Note that the "v20.11.0" is after the parent PowerShell process has already printed the next prompt line.
This is even more apparent when using
--strace
or other stdout logging vs theexecv()
-ed processes stdout which appears to print to the parent processes stdout (that's my best guess as to what's happening but I really have no idea)👆
ptime .\execvnode.exe --strace --version
Note that the normal process output (from --strace) is all normal but the execv()-ed node.exe is after. idk.
This post-exit process printing thing also breaks stdio capturing.
Version
cosmocc (GCC) 14.1.0
What operating system are you seeing the problem on?
Windows
Relevant log output
The text was updated successfully, but these errors were encountered: