This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author itsgk92
Recipients amaury.forgeotdarc, belopolsky, eryksun, itsgk92, meador.inge, paul.moore, steve.dower, tim.golden, zach.ware
Date 2020-06-19.08:11:04
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1592554265.43.0.20977014299.issue41021@roundup.psfhosted.org>
In-reply-to
Content
Hi, Thanks for response @eryksun

Sorry that I did not mention it is compiled for x86 and the crash happens in 32bit python. Yes, the dll is declared with stdcall and built for x86 with MSVC. It is tested with python 3.7.4 32bit which is successful and fails on python 3.8.2 32bit. I did not look into on x64 though. Below is the source code. I have also attached them as a zip.

>>> c/DummyCb.h

#pragma once
#include <Windows.h>
#include <iostream>

#define CALLBACK    __stdcall
#define WINAPI      __stdcall

#define EXFUNC(type) _declspec(dllexport) void WINAPI // export function
#define CBFUNC(type,func) typedef void (CALLBACK* func) // callback function

extern "C" CBFUNC(void, listen_cb)(int value, FILETIME ts );
extern "C" EXFUNC(void) subscribe_cb(listen_cb);


>>> c/DummyCb.cpp

#include "pch.h"
#include "DummyCb.h"
#include <stdio.h>

EXFUNC(void) subscribe_cb(listen_cb cb)
{
	
	int i = 0;
	while (true) {
		FILETIME systime;
		GetSystemTimeAsFileTime(&systime);
		i++;
		Sleep(1000);
		cb(i, systime);
   }
}


>>> c/CbClient.cpp

#include <iostream>
#include "DummyCb.h"
#include <stdio.h>
#include <Windows.h>

void __stdcall lis(int a, FILETIME ts) {

	printf("calling back %d, %d, %d \n", a,ts.dwHighDateTime, ts.dwLowDateTime);
}


int main()
{
	subscribe_cb(&lis);
}



>>> CbClient.py


from ctypes import *
from time import sleep


class FT(Structure):
    _fields_ = [("dwLowDateTime", c_ulong, 32),
                ("dwHighDateTime", c_ulong, 32)]


@WINFUNCTYPE(c_void_p, c_int, FT)
def cb(val, ft):
    print(f"callback {val} {ft.dwLowDateTime} {ft.dwHighDateTime}")


lib = WinDLL(r"c/DummyCb.dll")

lib.subscribe_cb(cb)

while 1:
    sleep(5)


>>> Traceback on python 

    lib.subscribe_cb(cb)
OSError: exception: access violation writing 0xCA35789B


>>> Native Debug traceback

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. 

>>> Further analysis

change the callback declaration to a pointer of structure and it has same crash on python 3.7 32 bit. 

@WINFUNCTYPE(c_void_p, c_int, POINTER(FT))
def cb(val, ft):
    print(f"callback {val} {ft.contents}")

Which makes me correlate is it something to do with vector calling on python 3.8 which makes callabck as *cb (a pointer) instead of a plain object call (just a thought, did not investigate change logs). Though its interesting to note that it did not fail on x64 with cdecl calling convention. That explains why our larger code base din't crash on Linux x86 linked as a .SO .


cheers.
History
Date User Action Args
2020-06-19 08:11:05itsgk92setrecipients: + itsgk92, paul.moore, amaury.forgeotdarc, belopolsky, tim.golden, meador.inge, zach.ware, eryksun, steve.dower
2020-06-19 08:11:05itsgk92setmessageid: <1592554265.43.0.20977014299.issue41021@roundup.psfhosted.org>
2020-06-19 08:11:05itsgk92linkissue41021 messages
2020-06-19 08:11:04itsgk92create