Catching a segfault in a Python library

D

Donn Ingle

Yo,
An app of mine relies on PIL. When PIL hits a certain problem font (for
unknown reasons as of now) it tends to segfault and no amount of try/except
will keep my wxPython app alive.

My first thought is to start the app from a bash script that will check the
return value of my wxPython app and could then launch a new app to help the
user grok what happened and fix it.

Do you think that's a good idea, or is there another way to handle stuff
like this? (perhaps a Python app launching another Python app?)

/d
 
P

Paul Rubin

Donn Ingle said:
Do you think that's a good idea, or is there another way to handle stuff
like this? (perhaps a Python app launching another Python app?)

Run your app under a debugger and figure out what is making it crash.
 
D

Donn Ingle

Run your app under a debugger and figure out what is making it crash.
Already done, the code within PIL is causing the crash. It gets ugly and out
of my remit. It's a freetype/Pil thing and I simply want to a way to catch
it when it happens.
Since a segfault ends the process, I am asking about "wrappers" around code
to catch a segfault.

\d
 
P

Paul Rubin

Donn Ingle said:
Already done, the code within PIL is causing the crash. It gets ugly and out
of my remit. It's a freetype/Pil thing and I simply want to a way to catch
it when it happens.
Since a segfault ends the process, I am asking about "wrappers" around code
to catch a segfault.

Well I think you should actually debug it, or at least reproduce it
and send a bug report to the PIL folks, but anyway you can use
os.wait() to get the exit status and recognize the seg fault.
 
D

Donn Ingle

Well I think you should actually debug it, or at least reproduce it
and send a bug report to the PIL folks,
It was a while ago, and if memory serves I did that, but memory fails.
but anyway you can use
os.wait() to get the exit status and recognize the seg fault.
Okay, that's a good start. Thanks, I'll go for a python starts wxpython
thing with os.wait() to sniff the outcome.


\d
 
P

Paul Rubin

Donn Ingle said:
Okay, that's a good start. Thanks, I'll go for a python starts wxpython
thing with os.wait() to sniff the outcome.

You may have to roll your own fork/exec to start the wxpython, instead
of using popen or the subprocess module. I'm not terribly conversant
in those modules but they may start a shell which would isolate your
program from the wxpython exit code.
 
D

Donn Ingle

You may have to roll your own fork/exec to start the wxpython, instead
of using popen or the subprocess module.  I'm not terribly conversant
in those modules but they may start a shell which would isolate your
program from the wxpython exit code.
Hrmm... Neither am I, that's why I asked here :) But I'll skin that Python
when I get to it.

Thanks.
\d
 
A

Ayaz Ahmed Khan

Donn said:
Already done, the code within PIL is causing the crash. It gets ugly and
out of my remit. It's a freetype/Pil thing and I simply want to a way to
catch it when it happens.
Since a segfault ends the process, I am asking about "wrappers" around
code
to catch a segfault.

\d

Wouldn't it be better to narrow down to what in your code is invoking PIL
in a manner in which PIL exhibits such behaviour, and handle it within
your code?

Just a thought!
 
P

Patrick Mullen

Wouldn't it be better to narrow down to what in your code is invoking PIL
in a manner in which PIL exhibits such behaviour, and handle it within
your code?

Just a thought!

I think the idea is, certain fonts in his collection may be corrupt,
and he wants to just scan through and load them, ignoring the ones
that make the program crash. The bug in this case lies with a third
party and isn't something he can easily fix (although he can file
reports to the third party (PIL)).

This has come up for me as well with loading meshes in a 3d
application. The user or someone may include a corrupt file, and it's
not nice for the application to just crash when that happens, asking
them if they want to debug it. I haven't really found a solution,
just have tried to prevent corrupted files in the system for now. Let
me know if you get this solved :)
 
D

Donn Ingle

I think the idea is, certain fonts in his collection may be corrupt,
and he wants to just scan through and load them, ignoring the ones
that make the program crash.  
Ya got me! Sheesh, I can't hide anywhere :D
The bug in this case lies with a third
party and isn't something he can easily fix (although he can file
reports to the third party (PIL)).
I've a bad memory and can't recall what I told PIL at the time. It might
have been a case of waiting to see what new versions can do.
not nice for the application to just crash when that happens, asking
them if they want to debug it.  
Zigactly! You can wrap try/except around the calls that (by debugging) you
know are the culprits, but a segfault is a segfault and bam! you are at the
command line again.
I haven't really found a solution,
just have tried to prevent corrupted files in the system for now.  Let
me know if you get this solved
I'll certainly pop a note. I think, though, that the answer may reside in
the basic theme of this thread:

runapp
result = runActualApp( )
while True:
if result == allokay: break
else:
<Start handling the horror>

Unless a segfault goes through that too, like Krypton through Superman.
\d
 
P

Paul Rubin

Donn Ingle said:
runapp
result = runActualApp( )
while True:
if result == allokay: break
else:
<Start handling the horror>

Unless a segfault goes through that too, like Krypton through Superman.

No you can't do it that way, when I say "run it under a debugger", I
mean run the entire Python interpreter under something like gdb, and
actually debug the seg fault. I can understand if you're reluctant to
make that effort. If it's for something critical then you should
certainly do it. If it's for something exposed to the internet or
used by potentially malicious users then you should certainly do it.
If it's for something throwaway and exposed only to trusted users,
then maybe your trap-and-restart approach can keep things usable for a
while.
 
D

Donn Ingle

Paul said:
then maybe your trap-and-restart approach can keep things usable for a
while.
Trap and restart gracefully is the road I want to take. If my app (FP)
chokes on a font (it will have made a note before doing what kills it,
because I know the 'danger' areas ) and then will die. The second layer
(launcher) app will then (hopefully) be returned to (after the segfault)
and it will then check the "badfont" file and start a wizard for the user
so that the fonts can be renamed/moved/killed.

This is mainly because I lack the skills to hack deeply into complex stuff
like PIL, even though a lot of it is Python, and also because the goals
keep changing as new versions of libs like PIL and Freetype come out. I'd
rather have a parachute than a scalpel :)

\d
 
D

Donn Ingle

MrJean1 said:
Try catching SIGSEGV using the Python signal module
<http://docs.python.org/lib/module-signal.html>
An example (for SIGALRM) is on the next page
<http://docs.python.org/lib/node546.html>
However, it may not work since a SIGSEGV fault is pretty much the end
of everything
Thanks for the lead -- I'll go have a look.

If I can just write a "BLOODYHELL" flag to a text file and then let it all
crash, the next time the app is run, it can go into "Dude, we have
issues..." mode.


\d
 
B

Brian Cole

Unfortunately this does not work for SIGSEGV: "Because the C signal
handler always returns, it makes little sense to catch synchronous
errors like SIGFPE or SIGSEGV"

The best approach I have seen for doing this the proper way is a bit
outdated: www.usenix.org/events/usenix01/full_papers/beazley/beazley.pdf
Also, do a Google search for "libwadpy".

This project needs reviving. Once I start full time in January I may
devote some time to this. Also, I have a friend in need of a computer
science senior project who may help.

The general question is why not build this directly into the
interpreter? The interpreter can automatically raise a seg fault
exception when SIGSEGV occurs. Easier said then done, but why not?

-Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top