[Bug 48891] Bash from Cygwin/msys2 terminates after first command
WineHQ Bugzilla
wine-bugs at winehq.org
Sat May 9 01:01:34 CDT 2020
https://bugs.winehq.org/show_bug.cgi?id=48891
--- Comment #16 from Damjan Jovanovic <damjan.jov at gmail.com> ---
Cygwin's "strace" command turned out to be very useful:
strace -o ../strace.txt command
What we see, comparing dofork() in code with logging output, is that this line:
syscall_printf ("%R = fork()", res);
logs:
... forkme 1023 ... dofork(): 0 = fork();
... forkme 1024 ... dofork(): 0 = fork();
So both the parent and the child think they are the child. Interestingly the
parent can't write to the terminal, but if you make a sample application in
which the child from fork() creates a file with the return value from
GetCurrentProcessId() in the filename, 2 files get created.
fork() calls dofork(), whose res comes from:
---snip---
if (!ischild)
res = grouped.parent (stackp);
else
{
res = grouped.child (stackp);
in_forkee = false;
ischild = true; /* might have been reset by fork mem copy */
}
---snip---
It's grouped.parent() that return 0 for the parent, and we know ischild is
correct because strace logging from grouped.parent() happens and happens only
once.
grouped.parent() is the frok::parent() method, which always return -1 on
failure. It returned 0, so it doesn't think it failed. The success return value
comes from child_pid, which is set by:
---snip---
child_pid = cygwin_pid (pi.dwProcessId);
---snip---
pi.dwProcessId is definitely valid. What does cygwin_pid() do, that results in
it returning 0?
---snip---
/* Convert Windows WINPID into Cygwin PID. Utilize the "winpid.WINPID"
symlinks created for each process. The symlink contains the Cygwin
PID as target. Return 0 if no "winpid.WINPID" symlink exists for
this WINPID. */
pid_t
cygwin_pid (DWORD dwProcessId)
{
WCHAR sym_name[24];
WCHAR pid_name[12];
UNICODE_STRING sym_str;
UNICODE_STRING pid_str;
OBJECT_ATTRIBUTES attr;
HANDLE sym_hdl;
NTSTATUS status;
__small_swprintf (sym_name, L"winpid.%u", dwProcessId);
RtlInitUnicodeString (&sym_str, sym_name);
InitializeObjectAttributes (&attr, &sym_str, OBJ_CASE_INSENSITIVE,
get_shared_parent_dir (), NULL);
status = NtOpenSymbolicLinkObject (&sym_hdl, SYMBOLIC_LINK_QUERY, &attr);
if (!NT_SUCCESS (status))
return 0;
RtlInitEmptyUnicodeString (&pid_str, pid_name,
sizeof pid_name - sizeof (WCHAR));
status = NtQuerySymbolicLinkObject (sym_hdl, &pid_str, NULL);
NtClose (sym_hdl);
if (!NT_SUCCESS (status))
{
system_printf ("NtOpenSymbolicLinkObject: %y, PID %u, ret 0",
status, dwProcessId);
return 0;
}
pid_str.Buffer[pid_str.Length / sizeof (WCHAR)] = L'\0';
pid_t ret = (pid_t) wcstoul (pid_str.Buffer, NULL, 10);
return ret;
}
---snip---
There are 3 paths out of the function. The middle one would log an
NtOpenSymbolicLinkObject failure (it's a typo, it's actually
NtQuerySymbolicLinkObject fails), but that's not visible in the strace.
Therefore it's the first or the last return that returned 0.
So one of the following took place:
1. NtOpenSymbolicLinkObject() failed, returning 0 without logging anything.
2. NtQuerySymbolicLinkObject() succeeded but returned "0" which was parsed to 0
by wcstoul() and return to the caller, either due to a Wine bug in it, or
another Wine bug when the symbolic link was created/stored.
--
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.
More information about the wine-bugs
mailing list