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