Recover from segfault in Python

2024/11/14 18:14:01

I have a few functions in my code that are randomly causing SegmentationFault error. I've identified them by enabling the faulthandler. I'm a bit stuck and have no idea how to reliably eliminate this problem.

I'm thinking about some workaround. Since the functions are crashing randomly, I could potentially retry them after a failure. The problem is that there's no way to recover from SegmentationFault crash.
The best idea I have for now is to rewrite these functions a bit and run them via subprocess. This solution will help me, that a crashed function won't crash the whole application, and can be retried.

Some of the functions are quite small and often executed, so it will significantly slow down my app. Is there any method to execute function in a separate context, faster than a subprocess that won't crash whole program in case of segfault?

Answer

I had some unreliable C extensions throw segfaults every once in a while and, since there was no way I was going to be able to fix that, what I did was create a decorator that would run the wrapped function in a separate process. That way you can stop segfaults from killing the main process.

Something like this: https://gist.github.com/joezuntz/e7e7764e5b591ed519cfd488e20311f1

Mine was a bit simpler, and it did the job for me. Additionally it lets you choose a timeout and a default return value in case there was a problem:

#! /usr/bin/env python3# std imports
import multiprocessing as mpdef parametrized(dec):"""This decorator can be used to create other decorators that accept arguments"""def layer(*args, **kwargs):def repl(f):return dec(f, *args, **kwargs)return replreturn layer@parametrized
def sigsev_guard(fcn, default_value=None, timeout=None):"""Used as a decorator with arguments.The decorated function will be called with its input arguments in another process.If the execution lasts longer than *timeout* seconds, it will be considered failed.If the execution fails, *default_value* will be returned."""def _fcn_wrapper(*args, **kwargs):q = mp.Queue()p = mp.Process(target=lambda q: q.put(fcn(*args, **kwargs)), args=(q,))p.start()p.join(timeout=timeout)exit_code = p.exitcodeif exit_code == 0:return q.get()logging.warning('Process did not exit correctly. Exit code: {}'.format(exit_code))return default_valuereturn _fcn_wrapper

So you would use it like:


@sigsev_guard(default_value=-1, timeout=60)
def your_risky_function(a,b,c,d):...
https://en.xdnf.cn/q/71928.html

Related Q&A

python and using self in methods

From what I read/understand, the self parameter is similiar to this.Is that true?If its optional, what would you do if self wasnt passed into the method?

How to extract only characters from image?

I have this type of image from that I only want to extract the characters.After binarization, I am getting this image img = cv2.imread(the_image.jpg) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) thresh…

connect to Azure SQL database via pyodbc

I use pyodbc to connect to my local SQL database which works withoout problems.SQLSERVERLOCAL=Driver={SQL Server Native Client 11.0};Server=(localdb)\\v11.0;integrated security = true;DATABASE=eodba; c…

Generator function for prime numbers [duplicate]

This question already has answers here:Simple prime number generator in Python(28 answers)Closed 9 years ago.Im trying to write a generator function for printing prime numbers as followsdef getPrimes(n…

`ValueError: too many values to unpack (expected 4)` with `scipy.stats.linregress`

I know that this error message (ValueError: too many values to unpack (expected 4)) appears when more variables are set to values than a function returns. scipy.stats.linregress returns 5 values accord…

Django prefetch_related from foreignkey with manytomanyfield not working

For example, in Django 1.8:class A(models.Model):x = models.BooleanField(default=True)class B(models.Model):y = models.ManyToManyField(A)class C(models.Model):z = models.ForeignKey(A)In this scenario, …

Running SimpleXMLRPCServer in separate thread and shutting down

I have a class that I wish to test via SimpleXMLRPCServer in python. The way I have my unit test set up is that I create a new thread, and start SimpleXMLRPCServer in that. Then I run all the test, and…

Clean Python multiprocess termination dependant on an exit flag

I am attempting to create a program using multiple processes and I would like to cleanly terminate all the spawned processes if errors occur. below Ive wrote out some pseudo type code for what I think …

Any limitations on platform constraints for wheels on PyPI?

Are there any limitations declared anywhere (PEPs or elsewhere) about how broad a scope the Linux wheels uploaded to PyPI should have? Specifically: is it considered acceptable practice to upload li…

Match set of dictionaries. Most elegant solution. Python

Given two lists of dictionaries, new one and old one. Dictionaries represent the same objects in both lists. I need to find differences and produce new list of dictionaries where will be objects from n…