- faulthandler действительно полезен для получения обратной трассировки, где произошел сбой сегмента, но он не позволяет правильно его обработать.
faulthandler.enable()
import ctypes
try:
# Windows fatal exception: access violation
# Current thread 0x00001334 (most recent call first):
# File "c:\Users\Andrej\Desktop\pomoika\test.py", line 6 in
ctypes.c_byte.from_address(0).value
print('never printed')
except:
print('never printed')
- настройка обработчика с помощью Singal.signal - это сработало, как упоминалось в документации и в этом вопросе, обработчик Код Python никогда не выполняется, поскольку обработка segfault также вызывает segfault рекурсивно.
import signal
class AccessError(Exception):
pass
def handler(signum, frame):
raise AccessError("Memory access violation")
def is_safe(address: int) -> bool:
try:
# Set signal handler for segmentation faults
signal.signal(signal.SIGSEGV, handler)
v = ctypes.c_uint.from_address(address)
a = v.value
return True
except AccessError:
return False
finally:
# Reset signal handler to default behavior
signal.signal(signal.SIGSEGV, signal.SIG_DFL)
# Test the function
print('before')
print(is_safe(0)) # Should print False or True depending on the address
print('after')
- Проверяем в отдельной теме. Это вроде работает, но в Windows возвращает False, True, False, так что я думаю, это не кроссплатформенно.
import multiprocessing
def check_address(queue, address):
try:
ctypes.c_byte.from_address(address).value
queue.put(True)
except Exception:
queue.put(False)
def is_safe(address: int, timeout: float = 1.0) -> bool:
queue = multiprocessing.Queue()
process = multiprocessing.Process(target=check_address, args=(queue, address))
process.start()
process.join(timeout)
if process.exitcode is None:
process.terminate()
raise Exception(f"Process is stuck (it took longer than {timeout}).")
elif process.exitcode == 0:
process.terminate()
process.join()
v = queue.get()
return v
return False
if __name__ == "__main__":
print(0, is_safe(0)) # False
print("id(object)", is_safe(id(object))) # True
a = object()
print("a", is_safe(id(a))) # True
Подробнее здесь: https://stackoverflow.com/questions/784 ... ing-python