Re: Catching signal errors
Re: Catching signal errors
- Subject: Re: Catching signal errors
- From: Pete Gontier <email@hidden>
- Date: Tue, 08 Feb 2005 11:04:54 -0800
I'd be surprised if this were reliable. From what I understand, one must
assume a signal may occur between any two machine instructions. This is not
quite the same thing as thread safety, for which there are per-thread
globals and such. It's possible the C++ runtime library has been carefully
engineered to tolerate this, but I'd be surprised.
In any case, the list of things one may do in a signal handler is so
restricted that I would not attempt to generalize it up to the C++ level
anyway. As soon as any destructor does anything as simple as call delete,
Bad ThingsĀ are likely to break loose from the ceiling and rain down around
your ears.
Then there is the possibility that the signal handler caller is itself
written in C++ and has its own exception stack which needs to be unwound
quite independently of your own and would be skipped over if your signal
handler were to throw its own exception. This is super-unlikely from a
practical standpoint, but from a theoretical standpoint it may give one an
idea of the sort of conflict this might create.
As a general rule, callback functions available to C programmers should
never allow C++ exceptions to escape.
circa 2/8/05 2:27 AM, "Paul Forgey" <email@hidden> wrote:
> Actually, I think you can, but I'm not sure how good an idea it really
> is. Derive what you throw from std::bad_exception. At your top level
> catch:
>
> catch (const std::bad_exception &e)
> {
> const char *what = e.what ();
> write (2, what, strlen (what));
> // or, better yet, abort () provided you aren't catching SIGABRT for
> this purpose
> _exit (1);
> }
>
> It's always bothered me that C++ exceptions aren't integrated into
> system signals, but that's a very old issue. There's a "d" programming
> language in development that actually addresses this.
>
> On Feb 7, 2005, at 9:31 PM, Rick Steele wrote:
>
>>> Matt Watson wrote:
>>>
>>>>> void fatalSigHandler(int sig, siginfo_t* info, void* context)
>>>>> {
>>>>> // We are very limited in what we are allowed to do in a signal
>>>>> handler. // Memory should not be allocated, and most libc
>>>>> functions should not be used.
>>>>> static char sig_message[] = "Aborting: Fatal signal occurred!\n";
>>>>>
>>>>> write(1, sig_message, sizeof(sig_message));
>>>>> exit(1);
>>>>> }
>>>>
>>>>
>>>> Never call exit() from a signal handler. You want _Exit() instead.
>>>> exit() will call atexit() handlers which will are likely not
>>>> signal-safe. And you probably want to use fd 2 (stderr), instead of
>>>> fd 1 in the write() call.
>>>
>>>
>>> Good suggestions. That's especially important when using dlopen or
>>> NSLinkModule on libraries. They could cause further signals or even
>>> signal deadlocks when they get unloaded.
>>>
>>>>
>>>> That said: if you're not going to add any more info in your signal
>>>> handler, or do any cleanup like unlink() files, it may just be best
>>>> to let it crash and generate a crash log.
>>>
>>>
>>> I assumed that he'd replace the handler with something else.
>>> One of the handlers I have for a project calls execv() to restart the
>>> daemon in case of a crash. That is after writing errors to a log and
>>> closing open file handles/resetting signal masks (as they are both
>>> inherited by the new process), and doing some other general cleanup
>>> of the daemon's lock/state files.
>>>
>>> -Kevin-
>>
>> Thanks everyone!!!!
>>
>> I hope no one minds if I take this one step further. Is there actually
>> a way to have it return to the offending code with an exception
>> triggered? For example, would the following snippet work...
>>
>> #define kMySigError -9999
>>
>> void fatalSigHandler(int sig, siginfo_t* info, void* context)
>> {
>> short pErr = kMySigError;
>> throw(pErr);
>> _Exit(1); //Not that this will ever be reached
>> }
>>
>> main(){
>> Ptr ptrFoo = nil;
>> char barrrr;
>> installSignalHandler(SIGSEGV, &fatalSigHandler);
>> installSignalHandler(SIGBUS, &fatalSigHandler);
>>
>> try{
>> barrrr = (*ptrFoo);
>> }catch(short err){
>> printf("Error %x", err);
>> }
>> ....continue
>> return(noErr);
>> }
>>
>> Rick
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Darwin-dev mailing list (email@hidden)
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Darwin-dev mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
--
Pete Gontier
http://www.m-audio.com/
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden