TIL: Debugging Python segfaults with faulthandler
Introduction
Recently, I encountered regular segfaults in one of the Python applications I was working on. During my investigation, I discovered a simple yet remarkable utility called faulthandler
, which is included in Python's standard library. I'd like to demonstrate how this utility can assist in diagnosing segfault issues within your Python applications.
Breaking things
Let's start with breaking some things. The small snippet below will produce a nasty segfault whenever you run it.
import ctypes
def inner():
ctypes.string_at(0)
def outer():
inner()
def main():
outer()
if __name__ == '__main__':
main()
Assuming that we have the above code in segfault.py
file, the result of running it should look more or less like this:
[1] 33003 segmentation fault python segfault.py
Unfortunately, that does not look very useful, but our new friend faulthandler
can unravel more information for us.
Figuring out what happened
Using faulthandler
is very simple. It can be enabled in a few ways, the simples one being setting PYTHONFAULTHANDLER
environment variable.
PYTHONFAULTHANDLER=1 python segfault.py
The output should be a bit more interesting now:
PYTHONFAULTHANDLER=1 python segfault.py
Fatal Python error: Segmentation fault
Current thread 0x0000000102790580 (most recent call first):
File "/Users/xxx/.pyenv/versions/3.9.7/lib/python3.9/ctypes/__init__.py", line 517 in string_at
File "/Users/xxx/snippets/segfault.py", line 4 in inner
File "/Users/xxx/snippets/segfault.py", line 7 in outer
File "/Users/xxx/snippets/segfault.py", line 10 in main
File "/Users/xxx/snippets/segfault.py", line 13 in <module>
[1] 33547 segmentation fault PYTHONFAULTHANDLER=1 python segfault.py
Now we see a nice traceback that gives us great hints about the source of our segfault.
There are also other ways of enabling faulthandler
, I recommend checking out docs for all the configuration options that faulthandler
supports.
Summary
Segmentation faults in our apps can cause a lot of headaches. Today we learned how we can leverage faulthandler
module to help us find the root causes for these segfaults. Thanks for reading and until next time!