October 02, 2013 Re: ctrl+c and destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On Tue, Oct 01, 2013 at 06:44:05PM +0200, deadalnix wrote: > On Tuesday, 1 October 2013 at 14:53:24 UTC, H. S. Teoh wrote: > >On Tue, Oct 01, 2013 at 02:06:12PM +0200, deadalnix wrote: > >>On Monday, 30 September 2013 at 22:55:22 UTC, H. S. Teoh wrote: > >>>On Mon, Sep 30, 2013 at 08:44:36PM +0200, deadalnix wrote: > >>>>On Monday, 30 September 2013 at 02:13:47 UTC, H. S. Teoh wrote: > >>>>>Well, ctrl-C can be handled, so the way I'd do it is to set up a signal handler for SIGINT and have it write something to a self-pipe read by the event handler, then the event handler can throw an Exception (which should cause dtors to run as the stack unwinds). > >>>>> > >>>> > >>>>No you can't. > >>>> > >>>>But you somehow can, if you want to use some black magic : http://www.deadalnix.me/2012/03/24/get-an-exception-from-a-segfault-on-linux-x86-and-x86_64-using-some-black-magic/ > >>> > >>>We were talking about SIGINT, not SIGSEGV. > >>> > >> > >>That isn't relevant here. > > > >Huh? The OP was talking about cleaning up after ctrl-C, not after a segfault. I already know you can't throw exceptions from a segfault (except with heavy trickery, and yes I remember the post you linked and I know how it works). > > > >SIGINT is different because it can be handled, and the signal handler can just write a byte to a pipe read by the main event loop, outside of signal handler context. > > > > The signal handler cannot throw exception. If you want to do so, you need the same scafolding. I know that. :) All I said was that the signal handler writes a byte to a pipe, which gets read by the event loop (OUTSIDE of signal handler context), and then the event loop does the throw. Now, having *druntime* throw an exception upon ctrl-C is something totally different, and yes it will require some kind of scaffolding/hack to make it work, 'cos the exception must propagate outside of signal handler context. T -- Notwithstanding the eloquent discontent that you have just respectfully expressed at length against my verbal capabilities, I am afraid that I must unfortunately bring it to your attention that I am, in fact, NOT verbose. |
October 02, 2013 Re: ctrl+c and destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On Tuesday, 1 October 2013 at 11:48:51 UTC, w0rp wrote: > This is a really good question, I think! Python has a KeyboardInterrupt exception for this purpose. Should we perhap try something similar? Perhaps as a library solution? I think a function like some_module.registerInterruptExceptions() would be cool to have. If someone knows a way to do that, that would be cool. I'm looking at deadalnix... I don't like where this is headed. Converting signals into exceptions is a bad idea. In a multithreaded program, which thread should get the exception thrown? The main thread? Every thread? What if main already terminated? The InterruptException must be anticipated in lots of places and most people will forget about it. Basically, the issues are very similar to killing threads [0]. Throwing exception anywhere without any relation to the code at that point is a recipe for disaster. [0] http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html |
October 02, 2013 Re: ctrl+c and destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On 02.10.2013 01:59, deadalnix wrote:
> On Tuesday, 1 October 2013 at 23:32:38 UTC, Paulo Pinto wrote:
>> s/Linux/UNIX/g
>
> The described technique use some OS specific features. It can be adapted
> to OSX as far as I know, but POSIX do not guarantee to have all required
> features to implement this.
That is why I was rephrasing Maxim's statement to mean "UNIX signals handlers as error mechanism is a complete disaster."
I don't do UNIX system programming at C level since 2002, but my POSIX memories, is that it is as portable as C, with its share of undefined behaviors and OS specific extensions.
And if I recall correctly the behavior of what was allowed to do in the signal handler, and how UNIX/libc functions would behave upon interruption was not that stable across multiple UNIX variants.
--
Paulo
|
October 02, 2013 Re: ctrl+c and destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to qznc | On Wednesday, 2 October 2013 at 09:16:44 UTC, qznc wrote:
> On Tuesday, 1 October 2013 at 11:48:51 UTC, w0rp wrote:
>> This is a really good question, I think! Python has a KeyboardInterrupt exception for this purpose. Should we perhap try something similar? Perhaps as a library solution? I think a function like some_module.registerInterruptExceptions() would be cool to have. If someone knows a way to do that, that would be cool. I'm looking at deadalnix...
>
> I don't like where this is headed. Converting signals into exceptions is a bad idea.
>
> In a multithreaded program, which thread should get the exception thrown? The main thread? Every thread? What if main already terminated?
>
> The InterruptException must be anticipated in lots of places and most people will forget about it.
>
> Basically, the issues are very similar to killing threads [0]. Throwing exception anywhere without any relation to the code at that point is a recipe for disaster.
>
>
> [0] http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
The whole point of Exception is that you care about them only if you know how to handle them.
Exception are the way a piece of code can say "Fuck that shit, I have no clue how to proceed with that"
|
October 02, 2013 Re: ctrl+c and destructors | ||||
---|---|---|---|---|
| ||||
On Oct 1, 2013, at 10:12 PM, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
>
> Now, having *druntime* throw an exception upon ctrl-C is something totally different, and yes it will require some kind of scaffolding/hack to make it work, 'cos the exception must propagate outside of signal handler context.
I believe the way this currently works is by dynamically modifying code at the point the SEGV occurred, which first patches up the code that was modified and then throws. But if the SEGV was inside a system call, you could be in serious trouble, since that code isn't exception safe.
|
October 02, 2013 Re: ctrl+c and destructors | ||||
---|---|---|---|---|
| ||||
On Wed, Oct 02, 2013 at 10:36:08AM -0700, Sean Kelly wrote: > On Oct 1, 2013, at 10:12 PM, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote: > > > > Now, having *druntime* throw an exception upon ctrl-C is something totally different, and yes it will require some kind of scaffolding/hack to make it work, 'cos the exception must propagate outside of signal handler context. > > I believe the way this currently works is [...] Wait, this *currently* works?! > [...] by dynamically modifying code at the point the SEGV occurred, which first patches up the code that was modified and then throws. I thought the hack posted in the thread deadalnix linked to was to have the signal handler "corrupt" the stack -- i.e., modify it so that the return address is redirected to a segfault handler. Thus, as soon as the signal handler returns (and leaves signal handler context), instead of returning to its original caller it "returns" to the segfault handler instead, which can then set things up properly for stack unwinding and throw an exception (or Error as the case may be). Though, granted, since segfaults can happen anywhere, including inside nothrow functions, there is no guarantee dtors will run or things will properly cleanup, etc.. All the usual caveat emptors apply. > But if the SEGV was inside a system call, you could be in serious trouble, since that code isn't exception safe. Well, SEGV itself is already serious trouble. :P I don't think there's any safe way to "recover" from a SEGV, since it indicates that something has gone horribly wrong in a way the code can't handle. I think the OP's original point was how to ensure certain cleanups always ran (e.g. switch terminal back to normal teletype mode when the program has been running in ncurses mode). Well, there is no guarantee that it will run, due to the nature of segfaults, but assuming that the dtors concerned are high enough up the call stack to not be affected by Errors bypassing dtors due to being inside nothrow functions, it *should* work in the general case. Obviously, the program should never try to catch a SegfaultError and attempt to "recover" from it, since the program is already horribly screwed up by that point. T -- It said to install Windows 2000 or better, so I installed Linux instead. |
October 02, 2013 Re: ctrl+c and destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paulo Pinto | On Oct 2, 2013, at 3:34 AM, Paulo Pinto <pjmlp@progtools.org> wrote:
> I don't do UNIX system programming at C level since 2002, but my POSIX memories, is that it is as portable as C, with its share of undefined behaviors and OS specific extensions.
Posix is super portable largely because the spec is very loose. Not many functions actually have to be declared, and of those that must be declared, some can actually return an error when called that indicates they aren't implemented. And what's allowed in signal handlers, for example, is very limited as well, for similar reasons. This is one area where Windows really did things right. As Don has noted in the past, SEH is really fantastic. I still do systems level C programming as my primary job responsibility, and my dislike of signals is nearly boundless at this point. Even for things that make sense like SIGCHLD, the limited options available within signal handlers make actually doing anything useful surprisingly hard. I really wish Posix routines were required to use critical sections to delay signals until handling them wouldn't break anything.
|
October 02, 2013 Re: ctrl+c and destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Oct 1, 2013, at 7:30 PM, Walter Bright <newshound2@digitalmars.com> wrote:
> On 10/1/2013 3:37 PM, Jonathan M Davis wrote:
>> On Tuesday, October 01, 2013 23:17:01 deadalnix wrote:
>>> It shouldn't in a language that have nullable type as default.
>>
>> I don't see why that's relevant. If you hit a segfault - regardless of whether it's because of a memory corruption or a null pointer or whatever - it's an error that should terminate your program. If we checked for null pointers and threw NullPointerError instead of segfaulting, it would be no different except that it would be an Error being thrown. Both it and segfaults are supposed to kill your program without doing cleanup.
>
> Right. A null pointer dereference is a logic bug in your program, and hence the program needs to stop immediately, not execute "cleanup" code.
>
> If there's one notion I'd like to terminate with prejudice, it's the notion that a running program can "recover" from bugs in itself.
I worked on a system whose design was specifically built around trapping and recovering from segfaults (great design, and sadly, patented). Things like this are one of the primary reasons to use a systems programming language. So while I agree in the general sense, I don't think it's appropriate for the language to make a hard and fast assertion here. I think we should choose a reasonable, safe default, but make it overridable. That's pretty much the design philosophy of Druntime.
|
October 02, 2013 Re: ctrl+c and destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxim Fomin | On Oct 1, 2013, at 1:16 PM, Maxim Fomin <maxim@maxim-fomin.ru> wrote:
>
> Druntime can catch SIGINT and throw the exception. This means that D runtime can be easily broken by silly C code which uses its own signal handlers. I didn't tested, but believe this is already the case with respect to SIGUSR1 and SIGUSR2 which are used by druntime, so any simple code hijacking the signals can break runtime. Linux signals handlers as error mechanism is a complete disaster.
Unix signal handlers in general are a complete disaster. The core idea is good, but the Posix requirements surrounding them are so loose as to render them nearly unusable.
I wasn't aware of pthread_suspend and it appears to be quite new. Does anyone know if it's implemented in Linux yet? A StackThreads discussion I found from a few years ago said it isn't, but a lot can change in a few years. I would absolutely love to do away with using signals for coordinating garbage collection wherever possible.
|
October 02, 2013 Re: ctrl+c and destructors | ||||
---|---|---|---|---|
| ||||
On Oct 2, 2013, at 11:08 AM, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote: > On Wed, Oct 02, 2013 at 10:36:08AM -0700, Sean Kelly wrote: >> On Oct 1, 2013, at 10:12 PM, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote: >>> >>> Now, having *druntime* throw an exception upon ctrl-C is something totally different, and yes it will require some kind of scaffolding/hack to make it work, 'cos the exception must propagate outside of signal handler context. >> >> I believe the way this currently works is [...] > > Wait, this *currently* works?! Oops. I thought the hack for this was integrated ages ago, but I don't see it. >> [...] by dynamically modifying code at the point the SEGV occurred, which first patches up the code that was modified and then throws. > > I thought the hack posted in the thread deadalnix linked to was to have the signal handler "corrupt" the stack -- i.e., modify it so that the return address is redirected to a segfault handler. Thus, as soon as the signal handler returns (and leaves signal handler context), instead of returning to its original caller it "returns" to the segfault handler instead, which can then set things up properly for stack unwinding and throw an exception (or Error as the case may be). Yes. >> But if the SEGV was inside a system call, you could be in serious trouble, since that code isn't exception safe. > > Well, SEGV itself is already serious trouble. :P I don't think there's any safe way to "recover" from a SEGV, since it indicates that something has gone horribly wrong in a way the code can't handle. It depends why and where, really. See my reply to Walter. > I think the OP's original point was how to ensure certain cleanups always ran (e.g. switch terminal back to normal teletype mode when the program has been running in ncurses mode). Well, there is no guarantee that it will run, due to the nature of segfaults, but assuming that the dtors concerned are high enough up the call stack to not be affected by Errors bypassing dtors due to being inside nothrow functions, it *should* work in the general case. Obviously, the program should never try to catch a SegfaultError and attempt to "recover" from it, since the program is already horribly screwed up by that point. Yes, trying to recover from a thrown Error is rarely a good idea. About the only one I'd consider trying to recover from is an OutOfMemoryError, and even then I'd be more inclined to assume a memory leak and just let the process die and restart. |
Copyright © 1999-2021 by the D Language Foundation