0

I have an .so file with a simple function returning a number * 2. That .so file is inside a .zip archive. From a python script, I'm trying to extract the .so file to a temporary location, and execute the function from it. The trouble is that the second time I am trying to do that, I get a segmentation fault.

It's probably clearer from code, so here are the cases I've tried:

Case I - failing

import ctypes
import zipfile
import tempfile

def foo():
    archive = zipfile.ZipFile("test.zip")
    lib_path = archive.extract("secret.so", tempfile.gettempdir())
    archive.close()

    secret = ctypes.CDLL(lib_path)
    print(secret.secret_calculation(3))

foo()
foo() # <--- SegFault when calling secret.secret_calculation

Case II - working (extract to different folders every time)

import ctypes
import zipfile
import tempfile

def foo():
    archive = zipfile.ZipFile("test.zip")
    lib_path = archive.extract("secret.so", tempfile.mkdtemp()) # <--- mkdtemp creates a new folder every time 
    archive.close()

    secret = ctypes.CDLL(lib_path)
    print(secret.secret_calculation(3))

foo()
foo() # <--- NO SegFault

Case III - working (loading the so without calling into it)

import ctypes
import zipfile
import tempfile

def foo():
    archive = zipfile.ZipFile("test.zip")
    lib_path = archive.extract("secret.so", tempfile.gettempdir())
    archive.close()

    secret = ctypes.CDLL(lib_path)
    # print(secret.secret_calculation(3))

foo()
foo() # <--- NO SegFault

Case IV - working (calling into the .so twice, without extracting it first)

import ctypes
import zipfile
import tempfile

def foo():
    # archive = zipfile.ZipFile("test.zip")
    # lib_path = archive.extract("secret.so", tempfile.gettempdir())
    # archive.close()

    secret = ctypes.CDLL("/tmp/secret.so")
    print(secret.secret_calculation(3))

foo()
foo() # <--- NO SegFault

Python version: 2.7.12

Any ideas why do I get this behavior?

Andrei
  • 100
  • 2
  • 11
  • 1
    your .so is probably corrupted during the successive extraction operations in the same folder, and the value of the entry point of your `secret_calculation function` is altered which produces a segmentation fault. Try to call `del secret` to unload your `.so` before next `foo ()` call – Landstalker Mar 03 '20 at 13:58
  • @Landstalker Thanks for the reply! I've printed the file hash after each extraction, and it's the same. As for `del secret`, it didn't work, but it lead me to a fix (see https://stackoverflow.com/questions/359498/how-can-i-unload-a-dll-using-ctypes-in-python) . I have to manually unload the library, which is not ideal, but it works. – Andrei Mar 04 '20 at 05:55
  • ok, but wht i don't understend in your case is that we cannot overwrite a file wich is already used (loaded). When your .so il loaded, we cannot overwrite it when we extract zip file for the second time. I don't know how this can be possible – Landstalker Mar 04 '20 at 08:05
  • @Landstalker What I expected is that, since the file is already loaded, it doesn't matter that I overwrite it on disk. Then I expect second time I call ctypes.CDLL("..."), to load it just as it did the first time, and not crash when calling a function from it. Or, if python is smart, see that the same library is already loaded, and just reuse it. Maybe it tries to reuse it, but some internal pointers change even if the file is the same, so it segfaults. Anyway, I refactored the code to go around the problem, I would just like to understand why it happens. – Andrei Mar 04 '20 at 10:25

0 Answers0