Skip to content
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

Closed
jcbhmr opened this issue Aug 8, 2024 · 17 comments
Closed

execve() requires parent process to be cosmo program on windows #1253

jcbhmr opened this issue Aug 8, 2024 · 17 comments
Labels
accepted We intend to address this issue.

Comments

@jcbhmr
Copy link
Contributor

jcbhmr commented Aug 8, 2024

Contact Details

jcbhmr@outlook.com

What happened?

When running a binary (ex. execvnode.exe) that uses execv() 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:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int err = execv("/C/Program Files/nodejs/node.exe", argv);
    if (err) {
        printf("error %d\n", err);
        return err;
    }
}
cosmocc -o execvnode.exe main.c

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.

image

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

image

...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.

image

if you spawn it as a double subprocess it seems to print its own output after it has exited somehow.

image

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 (a time similar-ish command for Windows https://community.chocolatey.org/packages/ptime)

image

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 the execv()-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)

image

👆 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.

image

Version

cosmocc (GCC) 14.1.0

What operating system are you seeing the problem on?

Windows

Relevant log output

i used screenshots since i think they convey the context and lack of output and position of text & cursor stuff a bit better than text does. let me know if i should include transcriptions and id be happy to

here's the --strace of ".\execvnode.exe --strace --version"

SYS   5076  11768          3'217'479 CreateFileMapping(-1, 0, kNtPageExecuteReadwrite, 65'536, NULL) → 268
SYS   5076  11768          6'476'456 MapViewOfFileEx(268, kNtFileMapWrite|kNtFileMapExecute, 0, 65'536, 0) → 0xf0000
SYS   5076  11768          6'670'288 VirtualProtect(0xf0000, 65'536, kNtPageReadwrite, [kNtPageExecuteReadwrite]) → true
SYS   5076  11768          6'870'788 CreateFileMapping(-1, 0, kNtPageExecuteReadwrite, 65'536, NULL) → 208
SYS   5076  11768          7'028'714 MapViewOfFileEx(208, kNtFileMapWrite|kNtFileMapExecute, 0, 65'536, 0x6fe000000) → 0x6fe000000
SYS   5076  11768          7'179'510 VirtualProtect(0x6fe000000, 65'536, kNtPageReadwrite, [kNtPageExecuteReadwrite]) → true
SYS   5076  11768          7'316'001 mmap(0x6fe000000, 65'536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0) → 0x6fe000000 (8'769'536 bytes total)
SYS   5076  11768          7'722'341 getenv("_COSMO_FDS_V2") → NULL
SYS   5076  11768          7'834'480 getenv("COSMOPOLITAN_DISABLE_ZIPOS") → NULL
SYS   5076  11768          7'989'145 issetugid() → 0
SYS   5076  11768          8'690'313 getenv("COSMOPOLITAN_INIT_ZIPOS") → NULL
SYS   5076  11768          9'280'138 GetProgramExecutableName() → "/C/Users/jcbhm/Downloads/execvnode.exe"
SYS   5076  11768          9'954'953 GetFileAttributes(u"C:\\Users\\jcbhm\\Downloads\\execvnode.exe") → kNtFileAttributeArchive
SYS   5076  11768         10'489'241 CreateFile(u"C:\\Users\\jcbhm\\Downloads\\execvnode.exe", kNtFileGenericRead|kNtGenericExecute|kNtFileWriteEa|kNtFileWriteAttributes, kNtFileShareRead|kNtFileShareWrite|kNtFileShareDelete, 4405168, kNtOpenExisting, kNtFileAttributeNotContentIndexed|kNtFileFlagOverlapped, 0) → {276, 0}
SYS   5076  11768         11'127'161 CreateFileMapping(-1, 0, kNtPageExecuteReadwrite, 16, NULL) → 212
SYS   5076  11768         11'651'556 MapViewOfFileEx(212, kNtFileMapWrite|kNtFileMapExecute, 0, 16, 0xf4cb1640000) → 0xf4cb1640000
SYS   5076  11768         12'244'086 VirtualProtect(0xf4cb1640000, 16, kNtPageReadwrite, [kNtPageExecuteReadwrite]) → true
SYS   5076  11768         12'846'441 mmap(0, 16, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) → 0xf4cb1640000 (8'773'632 bytes total)
SYS   5076  11768         13'488'273 CreateFileMapping(-1, 4405168, kNtPageExecuteReadwrite, 24, NULL) → 280
SYS   5076  11768         14'104'046 MapViewOfFileEx(280, kNtFileMapWrite|kNtFileMapExecute, 0, 24, 0xf4cb1650000) → 0xf4cb1650000
SYS   5076  11768         14'776'391 VirtualProtect(0xf4cb1650000, 24, kNtPageReadwrite, [kNtPageExecuteReadwrite]) → true
SYS   5076  11768         15'484'057 mmap(0, 24, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED, -1, 0) → 0xf4cb1650000 (8'777'728 bytes total)
SYS   5076  11768         16'073'718 openat(AT_FDCWD, "/C/Users/jcbhm/Downloads/execvnode.exe", O_RDONLY) → 3
SYS   5076  11768         16'869'421 fstat(3, [{.st_size=538'644, .st_blocks=540'672/512, .st_mode=0100700, .st_uid=27294, .st_gid=27294, .st_dev=0xb0e7e721, .st_ino=0x2dd0000000042dc, .st_flags=20}]) → 0
SYS   5076  11768         17'364'659 CreateFileMapping(276, 4405168, kNtPageExecuteRead, 538'644, NULL) → 284
SYS   5076  11768         17'888'151 MapViewOfFileEx(284, kNtFileMapRead|kNtFileMapExecute, 0, 538'644, 0xf4cb1660000) → 0xf4cb1660000
SYS   5076  11768         18'659'957 VirtualProtect(0xf4cb1660000, 538'644, kNtPageReadonly, [kNtPageExecuteRead]) → true
SYS   5076  11768         22'876'578 mmap(0, 538'644, PROT_READ, MAP_SHARED, 3, 0) → 0xf4cb1660000 (9'318'400 bytes total)
SYS   5076  11768         23'512'477 CreateFileMapping(-1, 0, kNtPageExecuteReadwrite, 24, NULL) → 288
SYS   5076  11768         24'071'454 MapViewOfFileEx(288, kNtFileMapWrite|kNtFileMapExecute, 0, 24, 0xad231b70000) → 0xad231b70000
SYS   5076  11768         24'651'348 VirtualProtect(0xad231b70000, 24, kNtPageReadwrite, [kNtPageExecuteReadwrite]) → true
SYS   5076  11768         25'239'632 mmap(0, 24, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) → 0xad231b70000 (9'322'496 bytes total)
SYS   5076  11768         25'995'063 UnmapViewOfFile(0xf4cb1650000) → true
SYS   5076  11768         26'437'840 munmap(0xf4cb1650000, 24) → 0 (9'318'400 bytes total)
SYS   5076  11768         27'169'289 UnmapViewOfFile(0xf4cb1640000) → true
SYS   5076  11768         27'767'218 munmap(0xf4cb1640000, 16) → 0 (9'314'304 bytes total)
SYS   5076  11768         28'353'836 close(3) → 0
SYS   5076  11768         28'846'056 __zipos_get("/C/Users/jcbhm/Downloads/execvnode.exe") → 0
SYS   5076  11768         29'380'741 CreateFileMapping(-1, 0, kNtPageExecuteReadwrite, 49'152, NULL) → 276
SYS   5076  11768         29'911'631 MapViewOfFileEx(276, kNtFileMapWrite|kNtFileMapExecute, 0, 49'152, 0xad231b80000) → 0xad231b80000
SYS   5076  11768         30'671'975 VirtualProtect(0xad231b80000, 49'152, kNtPageReadwrite, [kNtPageExecuteReadwrite]) → true
SYS   5076  11768         31'293'657 mmap(0, 49'152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) → 0xad231b80000 (9'363'456 bytes total)
SYS   5076  11768         32'515'541 inflate([u"SYMT☺   ╛♦       └       └        @     "...], 49'152, u"φ£y|T╒┘°☼A♣½ò *╘♪\\┴♪┬&╕T◘╔ä♦ÆL╠$$╪Ωd2s3↓"..., 17'485) → 0
SYS   5076  11768         32'714'841 GetSymbolTableFromZip() → 0xad231b80000
SYS   5076  11768         33'455'062 getenv("HOME") → "/C/Users/jcbhm"
SYS   5076  11768         33'876'088 getenv("TMPDIR") → NULL
SYS   5076  11768         34'559'707 getenv("TERM") → "xterm-256color"
SYS   5076  11768         35'246'759 CreateFileMapping(-1, 0, kNtPageExecuteReadwrite, 65'536, NULL) → 280
SYS   5076  11768         38'552'245 MapViewOfFileEx(280, kNtFileMapWrite|kNtFileMapExecute, 0, 65'536, 0xad231b90000) → 0xad231b90000
SYS   5076  11768         39'168'855 VirtualProtect(0xad231b90000, 65'536, kNtPageReadwrite, [kNtPageExecuteReadwrite]) → true
SYS   5076  11768         39'725'555 mmap(0, 65'536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) → 0xad231b90000 (9'428'992 bytes total)
SYS   5076  11768         40'314'757 execve("/C/Program Files/nodejs/node.exe", {"/C/Users/jcbhm/Downloads/execvnode.exe", "--version", NULL}, {"=::=::\\", "ALLUSERSPROFILE=/C/ProgramData", "APPDATA=/C/Users/jcbhm/AppData/Roaming", "CHOCOLATEYINSTALL=/C/ProgramData/chocolatey", "CHOCOLATEYLASTPATHUPDATE=133515754319390407", "COMMONPROGRAMFILES=/C/Program Files/Common Files", "COMMONPROGRAMFILES(X86)=/C/Program Files (x86)/Common Files", .)
SYS   5076  11768         41'026'370 OpenProcess(kNtProcessCreateProcess|kNtProcessDupHandle, false, 12400) → 212
SYS   5076  11768         41'744'158 CreateFile(!!2d4c20, kNtFileGenericRead, kNtFileShareRead|kNtFileShareWrite|kNtFileShareDelete, 0, kNtOpenExisting, kNtFileAttributeNormal|kNtFileFlagBackupSemantics, 0) → {292, 0}
SYS   5076  11768         43'844'628 CreateProcess(u"C:\\Program Files\\nodejs\\node.exe", u"C:\\Users\\jcbhm\\Downloads\\execvnode.exe --version", 0, 0, true, 590880, 0x2e541e, NULL, 0x7000007de8f0, 0x7000007dea78) → true
@jcbhmr jcbhmr added the medium severity Used to report medium severity bugs (e.g. Malfunctioning Features but still useable) label Aug 8, 2024
@jcbhmr jcbhmr changed the title Bug: execv() on Windows doesn't print in PowerShell Bug: execv() on Windows doesn't print in PowerShell, has "Application Error" in cmd Aug 8, 2024
@jcbhmr jcbhmr changed the title Bug: execv() on Windows doesn't print in PowerShell, has "Application Error" in cmd Bug: execv() on Windows doesn't print output Aug 8, 2024
@Tampa
Copy link

Tampa commented Dec 24, 2024

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.

@jart
Copy link
Owner

jart commented Dec 24, 2024

Have you tried doing this with a hello world binary? I just compiled with msvc the program cl hello.c and then modified your example to run hello.exe. It worked fine, on cosmopolitan bash, on command prompt, and on powershell. Try doing that. Also try passing the --strace flag to your program.

@Tampa
Copy link

Tampa commented Dec 24, 2024

./bin/cosmocc -o Test.exe test.c -mtiny

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  execv("dotnet", argv); // Returns blank
  while (getchar() != '\n');
  execv("\"C:\\Program Files\\dotnet\\dotnet.exe\"", argv); // Returns blank
  while (getchar() != '\n');
  system("\"C:\\Program Files\\dotnet\\dotnet.exe\""); // Causes 0xc0000142 error
  while (getchar() != '\n');
  system("\"/C/Program Files/dotnet/dotnet.exe\""); // Causes 0xc0000142 error
  while (getchar() != '\n');
}

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 dotnet command should be enough on either linux or windows to get the help text output. Calling the absolute path should not be necessary at all.

@Tampa
Copy link

Tampa commented Dec 24, 2024

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.

@jart
Copy link
Owner

jart commented Dec 24, 2024

OK I'm able to reproduce this error if I run the following on the Cosmopolitan Bash shell:

exec /c/Windows/System32/cmd.exe

Investigating...

@jart
Copy link
Owner

jart commented Dec 24, 2024

Also for what it's worth, 0xc0000142 means STATUS_DLL_INIT_FAILED

@jart jart changed the title Bug: execv() on Windows doesn't print output execve() requires parent process to be cosmo program Dec 24, 2024
@jart jart changed the title execve() requires parent process to be cosmo program execve() requires parent process to be cosmo program on windows Dec 24, 2024
@jart jart closed this as completed in cc8a9eb Dec 24, 2024
@jart
Copy link
Owner

jart commented Dec 24, 2024

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_spawn() or to use fork() + execv() together. If you know for certain that you want to use execve() to replace a process that was spawned by a non-cosmo program, then could you please explain the use case? Otherwise, I recommend downloading cosmo bash from https://cosmo.zip/pub/cosmos/bin/ and using that shell for launching your program that calls execv().

@jart jart added wontfix This will not be worked on and removed medium severity Used to report medium severity bugs (e.g. Malfunctioning Features but still useable) labels Dec 24, 2024
@Tampa
Copy link

Tampa commented Dec 24, 2024

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 dotnet Program.dll in it

Doing a ./Start.exe on linux, for example, already works, probably because there is already a terminal with an environment that can run dotnet, but when double clicking, on windows, the environment isn't setup to even know what dotnet is. When using absolute paths the error shows up, likely due to the difference in environments.

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 /c dotnet Program.dll would do, just as a cosmo app in order to have the dotnet call be system independent. Probably don't even need C code for that, an emulated bash script likely does work as well for this, but I was curious about learning some C in the process.

@Tampa
Copy link

Tampa commented Dec 24, 2024

Goodness I think I broke my brain, but yes indeed posix does work!

	char *dotnet = "C:\\Program Files\\dotnet\\dotnet.exe";
	size_t commandLen = strlen(dotnet) + 4;
	char *command = (char*)malloc(commandLen);
	snprintf(command, commandLen, "\"%s\"", dotnet);
	
	char *dllPath = "Program.dll";
	int pid;
	posix_spawn_file_actions_t *file_actions = NULL;
	posix_spawnattr_t *attrp = NULL;
	char *envp[] = {NULL};
	char *argu[] = {"/c", command, dllPath, NULL};
	posix_spawnp(&pid, "cmd.exe", file_actions, attrp, argu, envp);
	while (getchar() != '\n');

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 :)

@jart
Copy link
Owner

jart commented Dec 25, 2024

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);

@jart
Copy link
Owner

jart commented Dec 25, 2024

There's also:

systemvpe("cmd.exe", (char *[]){"cmd.exe", "/c", "echo hi", 0}, environ);

Which will do a path search.

@Tampa
Copy link

Tampa commented Dec 25, 2024

I tried that, but it would not compile saying the function doesn't exist. Same with the environ variable.

@jart
Copy link
Owner

jart commented Dec 25, 2024

You need to include cosmo.h (and I also recommend passing cosmocc -mcosmo) to get systemvpe(). I think you can get environ by including stdlib.h.

@Tampa
Copy link

Tampa commented Dec 25, 2024

Oh yes that compiles, thank you :)

I tried
systemvpe("cmd.exe", (char *[]){"cmd.exe", "/c", "dotnet", "--version", 0}, environ);
and
systemvpe("dotnet", (char *[]){"dotnet", "--version", 0}, environ);
which does not produce errors, but I also get no visible output or "command not found".

Doing systemvpe("C:\\Program Files\\dotnet\\dotnet.exe", (char *[]){"C:\\Program Files\\dotnet\\dotnet.exe", "--version", 0}, environ); brings the 0xc0000142 error, so I think posix might be the way to go.

@jtru
Copy link

jtru commented Jan 2, 2025

I ran into a similar issue where using execv() on Windows "suddenly" (I don't use Windows often, but realized that one of my executables did not behave as expected in an up-to-date Windows 11 box after not having tried that for maybe a year or so) stopped behaving as expected/I was used to, and rewriting the simple wrapper to use systemvpe(), as suggested here, did not fix things. So I created this minimal example as per the below:

#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 SYS 9132 9848 13'241'966 execve("cmd.exe") failed -1 ENOENT, even though iterating over the entries in PATH earlier appears to have succeeded at locating the cmd.exe interpreter.

Executing cmd.exe /c "echo Hi" in the same cmd.exe session produces the expected result ("Hi" printed on stdout), btw.

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 systemvpe()? Anything else that might be the culprit?

I'd be very keen to read your thoughts on the issue.

jart added a commit that referenced this issue Jan 2, 2025
@jart
Copy link
Owner

jart commented Jan 2, 2025

Thanks for reporting this. I just pushed a fix for systemvpe() and added a test too.

@jart jart added accepted We intend to address this issue. and removed wontfix This will not be worked on labels Jan 5, 2025
@jart jart reopened this Jan 5, 2025
@jart
Copy link
Owner

jart commented Jan 5, 2025

I've changed my mind. We shall fix execve() so that it lingers when process reparenting isn't possible.

@jart jart closed this as completed in 42a3bb7 Jan 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted We intend to address this issue.
Projects
None yet
Development

No branches or pull requests

4 participants