[cmake-developers] CMake execute_process/signal_handler on Unix

Yordanov, Dimitar dimitar.yordanov at sap.com
Fri Jun 3 02:05:35 EDT 2016


Hi Brad,

thanks for responding!

* Brad King <brad.king at kitware.com> [16-06-01 17:18 CEST]:
> On 06/01/2016 09:04 AM, Yordanov, Dimitar wrote:
> > I'm looking into an issue with a CMake build on Linux hanging in a
> > select syscall, when using EXECUTE_PROCESS without any additional
> > arguments. The subprocess executed is "chmod". The child finishes and
> > is marked as a zombie, but CMake did not realize that. The only
> > descriptors left open are the one of the signaling pipe.
> 
> The code in question uses a well-known idiom to make SIGCHLD
> select()able.  It has worked well for years on many platforms.
> Are you running inside some kind of virtualization or emulation
> environment?

Actually not. The server is maybe under heavy load, but should it
matter?

> 
> > is the use of a shared variable "kwsysProcesses" in the signal
> > handler. I think the usage of non volatile shared objects should be
> > avoided in signal handlers and we should just do as less as we
> > can in there.
> 
> IIRC we suppress signals while updating the shared variables.
> CMake also doesn't use threads.

Possibly I'm on the wrong track, but couldn't the compiler reorder the
code where kwsysProcess is set, and move it out of the blocked
section? Should it be volatile to avoid such scenario?

> > Why do we need the "(void)pipeStatus;" lines. For debugging?
> 
> Some compilers complain we don't use the return value of write().
> Therefore we must assign it to a variable.  Then compilers
> complain that the variable is assigned a value that is never
> used.  The cast suppresses this.

I thought (void)write(...); is a portable way to say that we are not
interested in the return value. Not that I would change running code
for that.

> > Why do we need to read from the pipe in the signal handler?
> 
> If many signals are received in succession before the select()
> wakes up and reads from the pipe then it could fill the pipe
> and block in the handler.  We do a non-blocking read to make
> sure the pipe never has more than one byte in it.  All we care
> about is waking up any blocking select().

The write end is also non-blocking so it would not block the signal
handler. I was just trying to understand the implementation and if I'm
not misunderstanding something.

> 
> BTW, in the long run I'd like to drop this code completely and
> move to libuv.  Meanwhile I'd rather not spend too much time
> updating the existing implementation.

Thanks for sharing.

Best wishes
Dimitar

> 
> -Brad
> 


More information about the cmake-developers mailing list