[issue38748] 32 bit ctypes stdcall callback fails to restore stack pointer
David Heffernan added the comment: @Steve as a user of Python rather than a Python developer, I don't know what the process here. I understand the need for a test, and then a fix. And I would not be surprised if the act of fixing the issue led to a broadening of the test if the scope of the defect turns out to be wider than noted in the comments so far. What is the process for a resolution to the issue being found. You've outlined the steps required, but how will they happen? -- ___ Python tracker <https://bugs.python.org/issue38748> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38748] 32 bit ctypes stdcall callback fails to restore stack pointer
New submission from David Heffernan : Starting with Python 3.8 certain ctypes callbacks fail to restore the stack pointer. In the repo below, when the DLL is compiled with MSVC under default debug settings, running the Python script leads to a debug error dialog which says: Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. It appears that when the C code calls the callback function, the value of ESP is 4 greater than it should be. This problem does not occur with older versions of Python. **DLL code** #include BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } typedef void (__stdcall *MYCALLBACK)(int, double); extern "C" { __declspec(dllexport) void __stdcall foo(MYCALLBACK callback) { callback(1, 11); callback(2, 21); callback(3, 31); } } **Python code** import ctypes import ctypes.wintypes def CallbackType(restype, *argtypes): def from_param(cls, obj): if obj is None: return obj return ctypes._CFuncPtr.from_param(obj) result = ctypes.WINFUNCTYPE(restype, *argtypes) result.from_param = classmethod(from_param) return result MYCALLBACK = CallbackType( None, ctypes.c_int, ctypes.c_double ) def callback(handle, time): print(handle, time) mycallback = MYCALLBACK(callback) lib = ctypes.WinDLL(r'path\to\dll\foo.dll') func = getattr(lib, '_foo@4') func.restype = None func.argtypes = MYCALLBACK, func(mycallback) -- components: ctypes messages: 356249 nosy: David Heffernan priority: normal severity: normal status: open title: 32 bit ctypes stdcall callback fails to restore stack pointer type: crash versions: Python 3.8 ___ Python tracker <https://bugs.python.org/issue38748> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39243] CDLL __init__ no longer supports name being passed as None when the handle is not None
New submission from David Heffernan : When creating an instance of CDLL (or indeed WinDLL) for a DLL that is already loaded, you pass the HMODULE in the handle argument to the constructor. In older versions of ctypes you could pass None as the name argument when doing so. However, the changes in https://github.com/python/cpython/commit/2438cdf0e932a341c7613bf4323d06b91ae9f1f1 now mean that such code fails with a NoneType is not iterable error. The relevant change is in __init__ for CDLL. The code inside the if _os.name == "nt" block sets up mode, but this is pointless is handle is not None. Because the mode variable is never used, rightly so because the DLL is already loaded. The issue could be resolved by changing if _os.name == "nt": to if _os.name == "nt" and handle is not None: The following program demonstrates the issue: import ctypes handle = ctypes.windll.kernel32._handle print(handle) lib = ctypes.WinDLL(name=None, handle=handle) print(lib._handle) This runs to completion in Python 3.7 and earlier, but fails in Python 3.8 and later: Traceback (most recent call last): File "test.py", line 5, in lib = ctypes.WinDLL(name=None, handle=handle) File "C:\Program Files (x86)\Python\38\lib\ctypes\__init__.py", line 359, in __init__ if '/' in name or '\\' in name: TypeError: argument of type 'NoneType' is not iterable -- components: Windows, ctypes messages: 359501 nosy: David Heffernan, paul.moore, steve.dower, tim.golden, zach.ware priority: normal severity: normal status: open title: CDLL __init__ no longer supports name being passed as None when the handle is not None type: behavior versions: Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue39243> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39243] CDLL __init__ no longer supports name being passed as None when the handle is not None
David Heffernan added the comment: Personally I'd hang this off whether handle has been specified. It seems pointless to set the mode if you are never going to use it. -- ___ Python tracker <https://bugs.python.org/issue39243> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39243] CDLL __init__ no longer supports name being passed as None when the handle is not None
David Heffernan added the comment: I would approve of that On Tue, 7 Jan 2020, 20:43 Steve Dower, wrote: > > Steve Dower added the comment: > > In that case, we should refactor the init method to check whether handle > has been specified earlier, so that it's obvious that the two conditional > blocks are never executed in that case. > > -- > > ___ > Python tracker > <https://bugs.python.org/issue39243> > ___ > -- ___ Python tracker <https://bugs.python.org/issue39243> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue16865] ctypes arrays >=2GB in length causes exception
David Heffernan added the comment: I just ran into this issue. I'm trying to write code like this: (ctypes.c_char*bufferLen).from_buffer(buffer) where buffer is a bytearray. When bufferLen is greater than 2GB I fail foul of this code in _ctypes.c long length; length = PyLong_AsLongAndOverflow(length_attr, &overflow); if (overflow) { PyErr_SetString(PyExc_OverflowError, "The '_length_' attribute is too large"); Py_DECREF(length_attr); goto error; } Surely this should not be forcing long on us. Can't it use PyLong_AsSsize_t or perhaps PyLong_AsLongLongAndOverflow? -- nosy: +David Heffernan ___ Python tracker <http://bugs.python.org/issue16865> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue16865] ctypes arrays >=2GB in length causes exception
David Heffernan added the comment: Erik, As you can no doubt guess, this is related to the questions I have been asking on SO that you have so expertly been answering. Thank you! When I solved the latest problem, getting at the internal buffer of a bytearray, I used the code in my previous comment, which came from a comment (now deleted) of yours to the question. Looking at this more closely I realise that, as you said in your answer, the array length is not important for my specific needs, to it is fine to use zero. That side steps this issue completely. Thanks again. -- ___ Python tracker <http://bugs.python.org/issue16865> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue26108] Calling PyInitialize with 2.7.11 on Windows x64 terminates process
New submission from David Heffernan: Environment: - Python 2.7.11 from python.org, x64. - Windows 10 or Windows 8.1 - MSVC 2015 I compiled the most basic embedding example, taken from the Python docs: #include int main(int argc, char *argv[]) { Py_SetProgramName(argv[0]); /* optional but recommended */ Py_Initialize(); PyRun_SimpleString("from time import time,ctime\n" "print 'Today is',ctime(time())\n"); Py_Finalize(); return 0; } When run the call to Py_Initialize does not return and the process is terminated. -- components: Windows messages: 258194 nosy: David Heffernan, paul.moore, steve.dower, tim.golden, zach.ware priority: normal severity: normal status: open title: Calling PyInitialize with 2.7.11 on Windows x64 terminates process type: crash versions: Python 2.7 ___ Python tracker <http://bugs.python.org/issue26108> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue26108] Calling PyInitialize with 2.7.11 on Windows x64 terminates process
David Heffernan added the comment: Note that I've just listed the Windows versions on which I have tested this. I have not tested on Windows 7 or Vista so do not know whether or not the issue exists there. -- ___ Python tracker <http://bugs.python.org/issue26108> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue26108] Calling PyInitialize with 2.7.11 on Windows x64 terminates process
David Heffernan added the comment: Thanks Eryk, everything you described happens exactly as you describe it. Much appreciated. As it happens, I'm not distributing Python because I want to give my users the flexibility to use whatever version they please, and with whatever third party modules they want. So I'll just advise them to avoid 2.7.11. -- ___ Python tracker <http://bugs.python.org/issue26108> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue26108] Calling PyInitialize with 2.7.11 on Windows x64 terminates process
David Heffernan added the comment: Why was this closed as "not a bug"? Shouldn't it have been closed as a duplicate? -- ___ Python tracker <http://bugs.python.org/issue26108> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue26108] Calling PyInitialize with 2.7.11 on Windows x64 terminates process
David Heffernan added the comment: Thanks for following up Steve, and thanks for changing resolution to dupe. As for 3.5 and embedding the docs are much the same as 2.7 in that the example code at https://docs.python.org/3/extending/embedding.html doesn't explicitly set Python home. Anyway, I'm very happy with how this report has been dealt with. Thank you all. -- ___ Python tracker <http://bugs.python.org/issue26108> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com