Message371851
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. |
|
Date |
User |
Action |
Args |
2020-06-19 08:11:05 | itsgk92 | set | recipients:
+ itsgk92, paul.moore, amaury.forgeotdarc, belopolsky, tim.golden, meador.inge, zach.ware, eryksun, steve.dower |
2020-06-19 08:11:05 | itsgk92 | set | messageid: <1592554265.43.0.20977014299.issue41021@roundup.psfhosted.org> |
2020-06-19 08:11:05 | itsgk92 | link | issue41021 messages |
2020-06-19 08:11:04 | itsgk92 | create | |
|