Ruby script hangs forever
You cannot use while
loop with upto
.
Change it to:
0.upto ARGV[0].to_i do
num << rand(254)
end
And it works properly (I've changed braces to curly one, because I believe you want 254 to be parameter here).
Sidenote:
Remember when writing threads program in Ruby, that CRuby has GIL - Global Interpreter Lock. Therefore only one thread will be operating at one time. If you want different behaviour - switch for example to jRuby. More information about GIL can be found f.e. here: http://www.jstorimer.com/blogs/workingwithcode/8085491-nobody-understands-the-gil
A Simple Ruby Script Freezes My Machine
You are creating a huge array which you don't even need. That is forcing your machine to start paging (it would take up 5% of the 64-bit address space and your machine certainly doesn't have that much RAM). Your code is not making it to the loop (the condition in the if statement isn't valid ruby).
CONSTANT = 1000
# start with something small, then increase by 10
# 10000000 works for me.
start = Time.now
CONSTANT.times do |i|
if 1000 < i && CONSTANT * 9 / 10
elsif i > CONSTANT * 9 / 10
else
end
end
finish = Time.now
puts "Running time: #{finish - start} seconds"
How to find out why rails server hangs at 100%?
Once you have attached with gdb to the busy looping process then call rb_backtrace
from gdb:
> call rb_backtrace()
The output from rb_backtrace
will be similar to a crash report, and the output will go to your log files similar to a standard Ruby error backtrace.
From there you should hopefully already be a step closer to the solution since you will see where in your Ruby code the process is stuck.
You can check out some more tips here:
http://isotope11.com/blog/getting-a-ruby-backtrace-from-gnu-debugger
How to debug Ruby scripts
Use Pry (GitHub).
Install via:
$ gem install pry
$ pry
Then add:
require 'pry'; binding.pry
into your program.
As of pry
0.12.2 however, there are no navigation commands such as next
, break
, etc. Some other gems additionally provide this, see for example pry-byebug
.
Ruby File IO Hang
Ok..since running the test code does not require any external ruby libraries I can compile 1.9 on my machine without installing it, and run the test program.
Here's what I see:
- Ruby seems to "hang" (you can't interrupt it, and it doesn't exit by itself).
top
shows ruby running at 100% CPUstrace
shows no output once it goes into 100% CPU mode.
From this it's obvious Ruby goes into an infinite loop. And looking at each_byte
in io.c
, and adding a printf
into the suspicious location reveals where we get stuck:
static VALUE
rb_io_each_byte(VALUE io)
{
rb_io_t *fptr;
char *p, *e;
RETURN_ENUMERATOR(io, 0, 0);
GetOpenFile(io, fptr);
for (;;) {
p = fptr->rbuf+fptr->rbuf_off;
e = p + fptr->rbuf_len;
printf("UH OH: %d < %d\n", p, e); /* INFINITE LOOP ALERT */
while (p < e) {
fptr->rbuf_off++;
fptr->rbuf_len--;
rb_yield(INT2FIX(*p & 0xff));
p++;
errno = 0;
}
rb_io_check_byte_readable(fptr);
READ_CHECK(fptr);
if (io_fillbuf(fptr) < 0) {
break;
}
}
return io;
}
On my machine it prints this:
UH OH: 0 < 0
UH OH: 137343104 < 137351296
UH OH: 137343119 < 137343104
UH OH: 137343119 < 137343104
UH OH: 137343119 < 137343104
...ad infinitum...
And 137343119 is NOT less than 137343104, which means we stop going into the while
loop (which would yield the block).
When you run the code so that it doesn't hang you get this:
UH OH: 0 < 0
UH OH: 137341560 < 137349752
UH OH: 137341560 < 137349752
UH OH: 137341560 < 137349752
UH OH: 137341560 < 137349752
....
And 137341560 IS less than 137349752.
Anyway..that's all I got for now. Still no clue why it's happening. But now we at least know WHAT is happening. Someone who wrote that code could probably explain why it's happening immidiately.
Anyway..I still think the lseek
calls somehow mess up ruby's internal file pointers, and the above loop goes haywire because of that.
EDIT
And here's a fix:
Change flush_before_seek
in io.c
to look like this:
static rb_io_t *
flush_before_seek(rb_io_t *fptr)
{
int wbuf_len = fptr->wbuf_len;
if (io_fflush(fptr) < 0)
rb_sys_fail(0);
if (wbuf_len != 0)
io_unread(fptr);
errno = 0;
return fptr;
}
What I added was the check for wbuf_len != 0
, so that we don't do io_unread
unnecessarily. Calling io_unread
while in the each_byte
loop is what messes things up. Skipping the unread makes things work and all the tests for make test
still pass.
Anyway..it's not a proper fix, since there is some fundamental thought mistake with f.pos
. It's just a workaround...but it fixes the above problem none the less :-/
Ruby run external program stops script
Try to run Something.exe
in a new Thread:
Thread.new { system("Something.exe") }
Related Topics
Millisecond Resolution of Datetime in Ruby
How to Test If a Div Has a Certain CSS Style in Rspec/Capybara
Is It a Bad Practice to List Ruby Version in Both Gemfile and .Ruby-Version Dotfile
Safely Assign Value to Nested Hash Using Hash#Dig or Lonely Operator(&.)
Heroku Rails 4 Could Not Connect to Server: Connection Refused
Heroku Wrongly Detecting My Node App as a Ruby App
Difference Between 'Self.Method_Name' and 'Class << Self' in Ruby
Rails - Multiple Top Level Domains and a Single Session/Cookie
Accessing Objects Memory Address in Ruby
How to Merge Two Hashes with No New Keys
How to Compile Ruby with Rvm on a Low Memory System
What's the Best Way to Search for a String in a File
Is There a Simple Way to Get Image Dimensions in Ruby