Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to recover from a crash? #8

Closed
pseidemann opened this issue May 7, 2020 · 5 comments
Closed

how to recover from a crash? #8

pseidemann opened this issue May 7, 2020 · 5 comments

Comments

@pseidemann
Copy link

hi,
my app crashed for the first time while using this library (nil pointer dereference) so it couldn't call Unwatch() on all the buttons nor gpio.Close().
when the app is now started again, I get the error that the pin is already in use.
what is the proper way to claim a pin again? I actually want to "force use" the pin because the application must always "just work".

@warthog618
Copy link
Owner

The gpio library does not allow you to force use a pin. If it sees a pin locked it assumes another app already has it. If your app has left it locked then you need to release the pin yourself. That is done using

echo pin > /sys/class/gpio/unexport

where pin is the pin number.

That is using the sysfs GPIO interface which the gpio library uses for watches and which is reporting the pin in use.

In general you can can catch signals that cause your app to exit and call the Unwatch in the signal handler. Refer to the watcher example which does just that. It doesn't catch a SIGSEGV though - and I'm not sure that approach works for a SIGSEGV. You can always try it by adding syscall.SIGSEGV to the list of signals.

And most importantly, fix your app so it doesn't SIGSEGV.

@pseidemann
Copy link
Author

I'm already catching signals to clean up everything. however, if there is for example a panic() inside the watch handler, the app will crash, leaving pins locked.

I don't think a go app can SIGSEGV unless you are using the unsafe package maybe. afaik panic() is just like an exception. maybe I'm missing something?

would it be possible to add something like gpio.Unexport() or maybe the watcher can defer Unwatch() inside the internal handler go routine so that it would be cleaned up even when some code in the handler from the lib consumer panics? this would be similar to how the http server is handling panics inside handlers: https://github.com/golang/go/blob/master/src/net/http/server.go#L81.

@pseidemann
Copy link
Author

pseidemann commented May 7, 2020

this shows that no real segmentation fault is happening in go: https://play.golang.org/p/SzaWnRlE5-k

@warthog618
Copy link
Owner

Yeah, I realised that as I was going to sleep. Sorry, I've been working in C and the context switch took a while. In Go you get a panic, not a SIGSEGV. So shoot me.

I wont be adding anything to this library, and certainly not an unexport. When I wrote this lib I decided not to expose an unexport as it just allows users to easily override locks. And then locks become pointless. It is intentionally hard to override a lock - you need to write to that file yourself. Which isn't really that hard. You are welcome to add something yourself if you think that is the best way to solve your problem.

I don't think the lib should be trying to recover from a panic - you can easily wrap your handler in something that recovers from panics if you want. The HTTP server case is different. They chose to assume the panic is confined to the handler so they can keep the app, and the potentially thousands of connections, running. This library plays with hardware and I chose to play it safe and assume that if you have a panic then it is time to leave - hopefully before the smoke starts coming out. But there is nothing stopping you wrapping your existing handler with some recovery if you disagree. Personally, I'd fix the panic.

@pseidemann
Copy link
Author

yes that makes sense. thanks for the input!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants