Feature request, warnings for non safe calls within signal handlers

David Brown david@westcontrol.com
Thu Mar 15 09:44:00 GMT 2012


On 15/03/2012 06:01, Jens Bauer wrote:
> Hi Jon and Ian,
>
> On Wed, 14 Mar 2012 19:54:48 -0700, Ian Lance Taylor wrote:
>> Jonathan Andrews<jon@jonshouse.co.uk>  writes:
>>
>>> Would it be possible to add a warning to gcc C when code in an
>>> signal handler (alarm) uses non thread safe calls.
>>
>> Your request for a warning is reasonable, I just don't see a way
>> to implement it such that it is useful.
>
> I like that idea. When compiling applications on Apple's Mac OS X,
> they have keywords to inform about "deprecated" functions at
> compile-time. A similar solution might be possible, providing that
> the authors of the libraries and functions being called, mark those
> as "thread_safe" or "interrupt_safe". Ofcourse, a compiler might be
> able to recursively go through functions and hunt for things that
> identifies whether or not a function is thread-safe, a'la the
> optimizer, however at present, this might be too complex.
>
> It would, for instance be a bit difficult to see whether a function
> that writes to a shared memory location is thread-safe, because
> writing to this location *could* be a semaphore or behind a
> semaphore.
>
> Note: Remember there's a difference between thread-safe and
> interrupt-safe. Whether or not I should mention 'reentry-safe' or
> not, I don't know.. Well, hereby done. ;)
>

Your final paragraph here gives some hints about the size of this idea - 
both in its potential usefulness, and in the work required to implement 
it.  Trying to implement some sort of checking for "signal handler safe" 
or "thread safe" or "interrupt safe" functions is a waste of effort.  It 
would have to be much more general to be effective - then "interrupt 
safe" or "signal handler safe" would simply be a specialisation of the 
concept.

What you need here is a way of tagging the compilation state with some 
sort of attributes, and a way of having functions and other parts of the 
code check those attributes for particular features.  These features 
must be definable in the user code, not just in the compiler, so they 
should probably have string names and integer values.  So then you'd 
have things like this:

__require_tag("gotLock1")
void foo(void) { ... code assuming lock1 is acquired .... }

void bar(void) {
	getLock(lock1);
	__set_tag("gotLock1");
	foo();
	__unset_tag("gotLock1");
	releaseLock(lock1);
}

Trying to call "foo" from code that has not set the "gotLock1" tag will 
give an error or warning.

Once you have this idea, there are all sorts of possibilities.  Some of 
these include:

Alternative paths in functions depending on the tags (if you have the 
"interruptsDisabled" tag on a single-processor system, then you can take 
short-cuts when accessing "atomic" data).  Or the "foo" function could 
be made to acquire and release the lock if needed.  This would be 
particularly efficient in inline functions.

Functions could affect the tags of their callers - "getLock" could set a 
tag on return.

You could use tags to say that "lock1" was always needed before getting 
"lock2" - thus spotting ordering errors that could lead to deadlocks.

You could have "unsafe" functions, that may only be called by code that 
sets the "unsafe" tag.  This could easily be combined with code 
development policies, such as requiring extra code reviews for anything 
"unsafe".

Code that must be run on a particular cpu in an SMP system could be tagged.

There are lots of uses for embedded systems and odd processors.  For 
example, on the msp430, gcc disables interrupts whenever it needs to use 
the hardware multiplier.  With an "interruptsDisabled" tag, it could 
generate smaller and faster code in some situations.


The potential for such a tag system is enormous, both for enhancing 
warning and error checking, and thus code quality, and for generating 
smaller and faster object code.  But it would also take a great deal of 
effort to come up with a flexible, consistent and workable syntax for 
the system.

As for implementation, I think it would be possible to come a long way 
by using a pre-preprocessor, as I think it would all be handled in a 
single compilation unit at a time.  In particular, any tag requirements 
for a function or code would be specified in the function declaration, 
not the definition.


mvh.,

David





More information about the Gcc-help mailing list