Is calling system() from a thread suppose to be safe?

Hey there,

I am calling system() from a thread and getting:

system': no implicit conversion from nil to integer (TypeError) from wifi-state-observer:169:in vpn_down’
from wifi-state-observer:46:in block in run' from wifi-state-observer:54:in call’
from wifi-state-observer:54:in run' from wifi-state-observer:54:in run’
from wifi-state-observer:270:in `’

Looking at Ruby’s source:

https://github.com/ruby/ruby/blob/trunk/process.c#L3673

it seems like rb_last_status_get() might be non-thread safe? Though I
would expect at that time the GVL would held so I am not sure why would
rb_last_status_get() return nil. This is running 1.9.3.

Any ideas?

  • rgs

On Fri, Aug 24, 2012 at 6:04 AM, [email protected] wrote:

from wifi-state-observer:270:in `’

Looking at Ruby’s source:

Can we first look at your call to system and surrounding code?

Any ideas?

Not yet.

Kind regards

robert

Hi Robert,

On 24 August 2012 01:18, Robert K. [email protected]
wrote:

from wifi-state-observer:54:in run' from wifi-state-observer:270:in

Looking at Ruby’s source:

Can we first look at your call to system and surrounding code?

Sure, here is the full-script:

http://www.itevenworks.net/~rgs/ruby/wifi-state-observer

system() happens inside vpn_down(). As you can see the main thread is
glib2 loop and the other forks/execs a binary (that connects to a
vpn).

Cheers,

  • rgs

Considering the message about conversion from nil to integer, I’d expect
the problem to be that either “cmd” or “@ncui_pid” is returning nil and
can’t be passed into the system command.

On Tue, Aug 28, 2012 at 2:12 PM, Joel P. [email protected]
wrote:

Considering the message about conversion from nil to integer, I’d expect
the problem to be that either “cmd” or “@ncui_pid” is returning nil and
can’t be passed into the system command.

I don’t think so:

cmd = "sudo kill -9 -#{@ncui_pid}"


system(cmd)

see http://www.itevenworks.net/~rgs/ruby/wifi-state-observer

cmd won’t be nil and if @ncui_pid is nil this won’t matter.

Kind regards

robert

Can you add a line which puts the cmd value out before triggering the
system command and report it back? It still looks like the only way to
get that error in this code is to pass something invalid to system.

2012/8/25 Ral Gutirrez S. [email protected]:

Sure, here is the full-script:

http://www.itevenworks.net/~rgs/ruby/wifi-state-observer

system() happens inside vpn_down(). As you can see the main thread is
glib2 loop and the other forks/execs a binary (that connects to a
vpn).

It seems Process.waitall takes the child process spawned by system().

In my environment, the problem can be reproducible as follows,
sometimes (not always):

% ruby -ve ’
Thread.new { loop { p Process.waitall } }
loop { p system(“true”) }

ruby 2.0.0dev (2012-08-15 trunk 36702) [x86_64-linux]
-e:3: warning: instance variable status not initialized
-e:3:in system': no implicit conversion from nil to integer (TypeError) from -e:3:in block in ’
from -e:3:in loop' from -e:3:in

How about avoiding Process.waitall?

I feel the error message can be improved, though.

I don’t know if this is relevant as I don’t use VM, but I noticed it in
your code. Would this be related?

Hi Tanaka!

On 29 August 2012 01:30, Tanaka A. [email protected] wrote:

It seems Process.waitall takes the child process spawned by system().
It does!

-e:3:in system': no implicit conversion from nil to integer (TypeError) from -e:3:in block in ’
from -e:3:in loop' from -e:3:in

How about avoiding Process.waitall?

I feel the error message can be improved, though.

Yup - that would be helpful… maybe we can add something to the docs
about missing system and waitall too?

Thanks!

  • rgs