-
-
Notifications
You must be signed in to change notification settings - Fork 317
Potential AV on TPythonEngine.DoOpenDll (Linux) #376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
In Linux I think you have to specify the DllName and DllPath as well as set the UseLastKnownVersion to False. The auto-detection unfortunately does not work. e.g. but these depend on the Linux distribution. Same is true for MacOS // PythonEngine.DllName := 'libpython3.7.dylib'; from the test files. |
Actually autodetection works for me on Linux and macOS as well. The only problem is that if it fails (eg no libpython installed) then the reported condition raised |
Good to know that autodetection works in Linux and MacOS. Where does the AV occur? In SysVersionFromDLLName or in TDynamicDll.DoOpenDll? Could you look at the stack trace of the exception. DllName is initialized in TPythonInterface.Create. There is no reason to be empty. If UseLastKnownVersion is true then every known version will be tried and then in addition the inherited DoOpenDLL will be called with DLLName, which should do no harm. Note that if FatalAbort is true and LoadDLL fails the program exits the hard way. |
It seems that empty DLLName is a problem on Linux. I will test again morning. |
How come it is empty? The constructor adds a default value (the dll name of the latest version). |
I added some trace messages into TDynamicDll.OpenDll and tested on fresh installs
Ubuntu 20.04 Ubuntu 18.04 Ubuntu 20.04 after “sudo apt-get -y install libpython3.8-dev” |
I don't get it.
Is the PythonEngine component DllName property empty? |
I am thinking of changing TPythonEngine.DoOpenDll to procedure TPythonEngine.DoOpenDll(const aDllName : string);
var
i : Integer;
begin
if UseLastKnownVersion then
for i:= Integer(COMPILED_FOR_PYTHON_VERSION_INDEX) downto 1 do
begin
RegVersion := PYTHON_KNOWN_VERSIONS[i].RegVersion;
inherited DoOpenDll(PYTHON_KNOWN_VERSIONS[i].DllName);
if IsHandleValid then
begin
DllName := PYTHON_KNOWN_VERSIONS[i].DllName;
APIVersion := PYTHON_KNOWN_VERSIONS[i].APIVersion;
Exit;
end;
end
else
begin
RegVersion := SysVersionFromDLLName(aDllName);
inherited;
end;
end; Does this work OK? |
Sorry I copy edited code 'name'->'DllName'. The crash happens in 'inherited' so the output is not recorded My initial proposal is the same as yours and it fixed the problem. |
I am still puzzled. See above. OpenDLL should be called only once. Also, is the PythonEngine component DllName property equal to an empty string? inherited calls TDynamicDll.DoOpenDll cannot you debug your program to see the exact statement causing the crash? |
I am reluctant to change the code since as it stands, it gives P4D an extra chance of finding a python dll with a DLLName different than then standard names, which could be useful in Linux. |
I eventually implemented the suggested change. |
DoOpenDl loop for all PYTHON_KNOWN_VERSIONS defined versions. But if the version is not found then inherited is called with an empty name which causes AV. Inherited should be called only if UseLastKnownVersion is false.
`procedure TPythonEngine.DoOpenDll(const aDllName : string);
var
i : Integer;
begin
if UseLastKnownVersion then
for i:= Integer(COMPILED_FOR_PYTHON_VERSION_INDEX) downto 1 do
begin
RegVersion := PYTHON_KNOWN_VERSIONS[i].RegVersion;
inherited DoOpenDll(PYTHON_KNOWN_VERSIONS[i].DllName);
if IsHandleValid then
begin
DllName := PYTHON_KNOWN_VERSIONS[i].DllName;
APIVersion := PYTHON_KNOWN_VERSIONS[i].APIVersion;
Exit;
end;
end
else begin
RegVersion := SysVersionFromDLLName(aDllName);
inherited; <--- HERE
end;
end;'
The text was updated successfully, but these errors were encountered: