develooper Front page | perl.perl5.porters | Postings from August 2017

Re: Calls in the perl core distribution that are unsafe in multithreaded applications

Thread Previous | Thread Next
From:
Karl Williamson
Date:
August 9, 2017 23:10
Subject:
Re: Calls in the perl core distribution that are unsafe in multithreaded applications
Message ID:
d346456c-6cbc-9c0a-1f14-6cf57d16f8b7@khwilliamson.com
On 08/09/2017 12:08 PM, Karl Williamson wrote:
> I looked at the glibc man pages to try to find all functions that we 
> call that aren't thread safe, and to see if we properly have taken this 
> into account.  This is what I found (though perhaps I missed some 
> things, and other systems may have a differing set of functions that are 
> unsafe).

I did some more research and found some more issues.

> 
> Anything that changes the environment is unsafe: we call putenv(), 
> clearenv(), and setenv().  I didn't see any synchronization around 
> these.  I believe these calls should be changed to be protected by 
> semaphores.  I wonder if this is the cause of some unexplained bugs.
> 
> Sys::Syslog calls setlogmask(), which has a race if another thread is 
> doing the same thing at the same time.  Though unlikely to occur, I 
> believe this should have a semaphore as well.
> 
> Windows calls fcloseall(), which in glibc has a race with 'streams'.  I 
> don't know if it is safe on Windows.
> 
> exit() turns out to be unsafe; the only symptom I could find in an 
> internet search is the process hanging.  I don't see us making any 
> changes here.
> 
> sleep() is unsafe, having a conflict with SIGCHILD.  I wonder if this is 
> the cause of some of our timing test failures.  I don't know what to do 
> about this.
> 
> There are a bunch of calls, such as readdir() which are unsafe, but 
> there is a safe version, specified by appending "_r" to the name, like 
> readdir_r().  This is transparently done by reentr.h for systems that 
> have them.  Thus, the code won't be safe when run on a platform that 
> doesn't have the "_r" version, but will be safe on a platform that does. 
>   This can lead to apparently unexplainable errors on the platforms that 
> don't have them.  I suppose we could generate compile time messages when 
> this happens.  Maybe you can think of something better.

Some of those _r functions turn out to still be unsafe in glibc:
getpwent_r()
getgrent_r()
getlogin_r()
I think these should be protected by semaphores
> 
> Some of those _r functions are for things in POSIX, like ctime().  I did 
> not check to see if a call to POSIX::asctime() for example, gets the 
> reentrant treatment, and gets converted to asctime_r().  If it doesn't, 
> it should.

I have now checked about POSIX.xs, and it does not currently use the _r 
versions, but

  #define PERL_EXT

at the top of the file causes it to.  Is there a reason not to do this?

> 
> getmntent() is unsafe.  It is called only on cygwin.  Linux (and hence I 
> presume cygwin) has getmntent_r(), which is safe.  I suspect that the 
> reason we don't probe for the _r version is because it's only on cygwin. 
>   I think this should be added to reentr.h
> 
> I did not look much at the OS's that we aren't really maintaining, like 
> os2.  I did see, for example, that strtok() is called in Netware, and is 
> unsafe (in glibc anyway; and there is a strtok_r() in glibc that is 
> safe).  I propose doing nothing for these.
> 

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About