<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=text/html;charset=gb2312 http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 8.00.7600.16466"></HEAD>
<BODY style="PADDING-LEFT: 10px; PADDING-RIGHT: 10px; PADDING-TOP: 15px"
id=MailContainerBody leftMargin=0 topMargin=0 CanvasTabStop="true"
name="Compose message area">
<DIV><FONT face=Calibri>keywords: _PyVerify_fd __pioinfo _msize</FONT></DIV>
<DIV><FONT face=Calibri></FONT> </DIV>
<DIV><FONT face=Calibri>PyPy can not pass this test:<BR> pytest.py
--cc=mingw32-gcc
pypy\rlib\test\test_rposix.py::TestPosixUnicode::()::test_is_valid_fd<BR>After 2
days of hard work, I finally realise why. Patch file attached.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Calibri>The problem is in _PyVerify_fd:<BR> FILE* f =
fopen("d:\\55.txt","w");<BR> int no = fileno(f);<BR> int flg1 =
_PyVerify_fd(no);<BR> fclose(f);<BR> int flg2 =
_PyVerify_fd(no);<BR> printf("flg1 %d should be 1, flg2 %d should be 0",
flg1, flg2)</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Calibri>in file rposix.py, source of function _PyVerify_fd is
write to a c file, and will be compile to a Windows<BR>DLL file. In this
function, it use <BR> extern __declspec(dllimport) char *
__pioinfo[];<BR>__pioinfo as a global variable.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Calibri>I find use __pioinfo in a DLL file is not safe. the
__pioinfo and _msize may export from many
DLL:<BR> msvcrt.dll<BR> msvcr90.dll<BR> msvcr90d.dll<BR> or
maybe msvcr70.dll ...<BR>If we fopen and fileno in a EXE file, and call
_PyVerify_fd in a DLL file, its very danger. The EXE<BR>and DLL may reference
different __pioinfo and get error.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Calibri>So I think
test_rposix.py::TestPosixUnicode::()::test_is_valid_fd can pass in MSVC is only
a coincidence.<BR>_PyVerify_fd in a DLL and use dllimport __pioinfo is not
safe.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Calibri>In my fix, I do not assume any DLL we should use. I try
to find the current DLL which export __pioinfo already<BR>loaded. Sure this is
not very good. But I think if we must place _PyVerify_fd in a DLL, no good
solution.</FONT></DIV>
<DIV><FONT face=Calibri></FONT> </DIV>
<DIV><FONT face=Calibri>After this path, this tests are pass:</FONT></DIV>
<DIV><FONT face=Calibri> pytest.py --cc=mingw32-gcc
pypy\rlib\test\test_rposix.py</FONT></DIV>
<DIV>
<DIV><FONT
face=Calibri> pytest.py pypy\rlib\test\test_rposix.py</FONT></DIV>
<DIV><FONT face=Calibri></FONT> </DIV>
<DIV><FONT face=Calibri>-----------</FONT></DIV>
<DIV><FONT face=Calibri></FONT> </DIV>
<DIV><FONT face=Calibri>diff -crN pypy-pypy-4a38b43757e3/_pytest/config.py
pypy-pypy-4a38b43757e3.bookaa/_pytest/config.py<BR>***
pypy-pypy-4a38b43757e3/_pytest/config.py Tue May 22 14:03:20 2012<BR>---
pypy-pypy-4a38b43757e3.bookaa/_pytest/config.py Sat May 26 20:47:43
2012<BR>***************<BR>*** 157,162 ****<BR>--- 157,164
----<BR> for arg in args +
[current]:<BR>
if hasattr(arg, 'startswith') and
arg.startswith("--"):<BR>
continue<BR>+
if arg.find('::') !=
-1:<BR>+
arg =
arg[:arg.find('::')]<BR>
anchor = current.join(arg,
abs=1)<BR>
if anchor.check(): # we found some file
object<BR>
self._path2confmods[None] = self.getconftestmodules(anchor)<BR>diff -crN
pypy-pypy-4a38b43757e3/pypy/conftest.py
pypy-pypy-4a38b43757e3.bookaa/pypy/conftest.py<BR>***
pypy-pypy-4a38b43757e3/pypy/conftest.py Tue May 22 14:03:20 2012<BR>---
pypy-pypy-4a38b43757e3.bookaa/pypy/conftest.py Sat May 26 20:59:51
2012<BR>***************<BR>*** 33,38 ****<BR>--- 33,42
----<BR> raise
ValueError("%s not in %s" % (value,
PLATFORMS))<BR> set_platform(value,
None)<BR> <BR>+ def _set_compiler(opt, opt_str, value, parser): #add
by bookaa<BR>+ from pypy.translator.platform import
set_platform<BR>+ set_platform('host', value)<BR>+
<BR> def pytest_addoption(parser):<BR> group
= parser.getgroup("pypy options")<BR>
group.addoption('--view', action="store_true", dest="view",
default=False,<BR>***************<BR>*** 46,51 ****<BR>--- 50,58
----<BR> group.addoption('-P', '--platform',
action="callback",
type="string",<BR>
default="host",
callback=_set_platform,<BR>
help="set up tests to use specified platform as compile/run
target")<BR>+ group.addoption('--cc', action="callback",
type="string", #add by
bookaa<BR>+
default="host",
callback=_set_compiler,<BR>+
help="set up tests to use specified compiler")
<BR> group = parser.getgroup("JIT
options")<BR> group.addoption('--viewloops',
action="store_true",<BR>
default=False, dest="viewloops",<BR>diff -crN
pypy-pypy-4a38b43757e3/pypy/rlib/rposix.py
pypy-pypy-4a38b43757e3.bookaa/pypy/rlib/rposix.py<BR>***
pypy-pypy-4a38b43757e3/pypy/rlib/rposix.py Tue May 22 14:03:20 2012<BR>---
pypy-pypy-4a38b43757e3.bookaa/pypy/rlib/rposix.py Sat May 26 20:51:13
2012<BR>***************<BR>*** 24,34 ****<BR>
separate_module_sources
=['''<BR> /* Lifted
completely from CPython 3.3 Modules/posix_module.c
*/<BR> #include
<malloc.h> /* for _msize
*/<BR> typedef struct
{<BR>
intptr_t
osfhnd;<BR>
char osfile;<BR> }
my_ioinfo;<BR>! extern
__declspec(dllimport) char *
__pioinfo[];<BR> #define
IOINFO_L2E 5<BR> #define
IOINFO_ARRAY_ELTS (1 <<
IOINFO_L2E)<BR> #define
IOINFO_ARRAYS 64<BR>--- 24,35 ----<BR>
separate_module_sources
=['''<BR> /* Lifted
completely from CPython 3.3 Modules/posix_module.c
*/<BR> #include
<malloc.h> /* for _msize
*/<BR>+ #include
<windows.h><BR>
typedef struct
{<BR>
intptr_t
osfhnd;<BR>
char osfile;<BR> }
my_ioinfo;<BR>! //extern
__declspec(dllimport) char *
__pioinfo[];<BR> #define
IOINFO_L2E 5<BR> #define
IOINFO_ARRAY_ELTS (1 <<
IOINFO_L2E)<BR> #define
IOINFO_ARRAYS 64<BR>***************<BR>*** 36,41 ****<BR>--- 37,58
----<BR> #define FOPEN
0x01<BR> #define
_NO_CONSOLE_FILENO (intptr_t)-2<BR>
<BR>+ char** Get_pioinfo(void**
pp)<BR>+
{<BR>+ HMODULE
hm;<BR>+ hm =
GetModuleHandleA("msvcr90.dll");<BR>+
if (hm ==
0)<BR>+
hm =
GetModuleHandleA("msvcr90d.dll");<BR>+
if (hm ==
0)<BR>+
hm =
GetModuleHandleA("msvcrt.dll");<BR>+
if (hm)<BR>+
{<BR>+
void * p = GetProcAddress(hm,
"__pioinfo");<BR>+
*pp = GetProcAddress(hm,
"_msize");<BR>+
return
(char**)p;<BR>+
}<BR>+ return
0;<BR>+
}<BR> /* This function
emulates what the windows
CRT<BR>
does to validate file handles
*/<BR>
int<BR>***************<BR>*** 45,56
****<BR>
const int i2 = fd & ((1 << IOINFO_L2E) - 1);<BR>
<BR>
static size_t sizeof_ioinfo = 0;<BR>
<BR>
/* Determine the actual size of the ioinfo
structure,<BR>
* as used by the CRT loaded in
memory<BR>
*/<BR>
if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL)
{<BR>!
sizeof_ioinfo = _msize(__pioinfo[0]) /
IOINFO_ARRAY_ELTS;<BR>
}<BR>
if (sizeof_ioinfo == 0)
{<BR>
/* This should not happen... */<BR>--- 62,77
----<BR>
const int i2 = fd & ((1 << IOINFO_L2E) - 1);<BR>
<BR>
static size_t sizeof_ioinfo =
0;<BR>+
int (*my_msize)(char*) =
0;<BR>+
char** __pioinfo =
Get_pioinfo((void**)&my_msize);<BR>+
if (__pioinfo ==
0)<BR>+
return 0;<BR>
<BR>
/* Determine the actual size of the ioinfo
structure,<BR>
* as used by the CRT loaded in
memory<BR>
*/<BR>
if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL)
{<BR>!
sizeof_ioinfo = my_msize(__pioinfo[0]) /
IOINFO_ARRAY_ELTS;<BR>
}<BR>
if (sizeof_ioinfo == 0)
{<BR>
/* This should not happen... */<BR>***************<BR>*** 75,80 ****<BR>---
96,105
----<BR>
return 0;<BR>
}<BR> ''',]<BR>+ from
pypy.translator.platform import platform<BR>+ if
platform.name == 'mingw32':<BR>+
separate_module_sources[0] = '''#include <stdint.h> /* for intptr_t
*/<BR>+ ''' +
separate_module_sources[0]<BR> export_symbols =
['_PyVerify_fd']<BR> else:<BR>
separate_module_sources = []<BR>diff -crN
pypy-pypy-4a38b43757e3/pypy/rpython/tool/rfficache.py
pypy-pypy-4a38b43757e3.bookaa/pypy/rpython/tool/rfficache.py<BR>***
pypy-pypy-4a38b43757e3/pypy/rpython/tool/rfficache.py Tue May 22 14:03:20
2012<BR>---
pypy-pypy-4a38b43757e3.bookaa/pypy/rpython/tool/rfficache.py Sat May 26
20:47:42 2012<BR>***************<BR>*** 13,19 ****<BR> from
pypy.tool.gcc_cache import build_executable_cache<BR> <BR> def
ask_gcc(question, add_source=""):<BR>! includes =
['stdlib.h', 'stdio.h', 'sys/types.h']<BR> if
os.name != 'nt':<BR>
includes += ['inttypes.h']<BR> include_string =
"\n".join(["#include <%s>" % i for i in includes])<BR>--- 13,23
----<BR> from pypy.tool.gcc_cache import build_executable_cache<BR>
<BR> def ask_gcc(question, add_source=""):<BR>!
from pypy.translator.platform import platform<BR>! if
platform.name == 'mingw32':<BR>!
includes = ['stdlib.h', 'stdio.h', 'sys/types.h',
'stdint.h']<BR>!
else:<BR>! includes =
['stdlib.h', 'stdio.h', 'sys/types.h']<BR> if
os.name != 'nt':<BR>
includes += ['inttypes.h']<BR> include_string =
"\n".join(["#include <%s>" % i for i in includes])<BR>diff -crN
pypy-pypy-4a38b43757e3/pypy/translator/platform/posix.py
pypy-pypy-4a38b43757e3.bookaa/pypy/translator/platform/posix.py<BR>***
pypy-pypy-4a38b43757e3/pypy/translator/platform/posix.py Tue May 22
14:03:20 2012<BR>---
pypy-pypy-4a38b43757e3.bookaa/pypy/translator/platform/posix.py Sat May 26
20:47:42 2012<BR>***************<BR>*** 55,60 ****<BR>--- 55,62 ----<BR>
<BR> if
relto:<BR>
response_file =
relto.bestrelpath(response_file)<BR>+
if self.name ==
'mingw32':<BR>+
return ["-Wl,--export-all-symbols,--version-script=%s" %
(response_file,)]<BR>
return ["-Wl,--export-dynamic,--version-script=%s" % (response_file,)]<BR>
<BR> def _link(self, cc, ofiles, link_args,
standalone, exe_name):<BR></FONT></DIV>
<DIV><FONT face=Calibri></FONT> </DIV></DIV></BODY></HTML>