This is the mail archive of the
cygwin-talk
mailing list for the cygwin project.
Re: Design mixed 32 and 64 bit systems.
- From: Warren Young <warren at etr-usa dot com>
- To: The Vulgar and Unprofessional Cygwin-Talk List <cygwin-talk at cygwin dot com>
- Date: Mon, 02 Dec 2013 12:35:00 -0700
- Subject: Re: Design mixed 32 and 64 bit systems.
- Authentication-results: sourceware.org; auth=none
- References: <6CF2FC1279D0844C9357664DC5A08BA21D7054 at MLBXV06 dot nih dot gov>
- Reply-to: The Vulgar and Unprofessional Cygwin-Talk List <cygwin-talk at cygwin dot com>
On 11/27/2013 13:11, Buchbinder, Barry (NIH/NIAID) [E] wrote:
My question is why 64 bit wasn't named cygwin2.dll?
While I agree that there is justification for that on "different ABI"
grounds, it doesn't solve the core problem.
That being, the Cygwin DLL maintains a bunch of shared data structures
to provide the POSIX emulation that Cygwin programs require. Different
DLLs mean different memory spaces, which means two *independent* sets of
these data structures.
Consider a simple case: parent PID. A 64-bit Cygwin program launches a
32-bit Cygwin program. What goes getppid(2) return in the child?
Take a second and think about it.
Got your guess? Okay, now put the two attached C++ files into a
directory that both Cygwins can see (/cygdrive/c for example) and build
them. The easiest way to do that is to say "make child32" from Cygwin
32 and "make parent64" from Cygwin 64.
Now from Cygwin 64, run parent64. Does the output match your guess? I
bet you'll find it surprising!
------- BEGIN SPOILER --------
This happens because POSIX PIDs are in a table that lives in
cygwin1.dll's memory space, and because there are two DLLs, there are
two different PID tables.
-------- END SPOILER ---------
You don't run into this problem on "real" 32/64-bit OSes because there
is only one kernel, and the 32 vs 64 bit differences are abstracted away
by the syscall layer, so that everything becomes 64-bit within kernel
space. There is no single central entity in Cygwin, since Cygwin runs
entirely in user space.
Perhaps one could build a special 32-bit cygwin1.dll that worked like
Wow64[*]. It may not be possible without kernel level support, from a
driver at least. On the other hand, it can't be any more tricky than
building something like VirtualBox. The question then is whether it's
worth the effort.
[*] http://goo.gl/oYbLwg
#include <iostream>
#include <unistd.h>
int main()
{
std::cout << "My PID is " << getpid() << "; my parent's PID is " <<
getppid() << '.' << std::endl;
}
#include <iostream>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main()
{
std::cout << "My PID is " << getpid() << "; " << std::flush;
switch (int pid = fork()) {
case -1: // error
std::cout << "ERROR: " << strerror(errno) << std::endl;
break;
case 0: { // child
const char* cmd = "./child32";
execl(cmd, cmd, 0);
break;
}
default: // parent
std::cout << "created child PID " << pid << std::endl;
}
}