Ruby process is at 100% after script ends, profiling, solution? - ruby

UPDATE: Problem located in my related question - Nokogiri performance problem
I am having a serious problem with my program. After program reaches it's last statement, Aptana studio shows the program is still running even after the last line was evaluated. Ruby process (after the last line of the script) is still running with 100% CPU usage, it ends after several seconds (15-30 maybe). I am trying to at atleast see where the problem is but after a long time I am still at the beginning. So the question is, what could cause this problem and how can I at least see where the problem is, what are my options? Some additional information:
Aptana debbug mode: After the last line, this will show in the Debug window:
<terminated, exit value: 0>path/to/ruby
But Ruby process is still running and using 100% CPU
I was trying to use gdb to profile Ruby process itself, but ended up with nothing using method described here: Profilig using gdb. I am using debian squeeze 64-bit and i tried both versions of script (8,12 > 16,24). When I tried to get some stack info I just get this:
Program received signal SIGSEGV, Segmentation fault.
0x00007f20539a80b8 in ?? () from /lib/libc.so.6
/home/giron/programovani/gdb_init.sh:1: Error in sourced command file:
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on".
Evaluation of the expression containing the function
(backtrace) will be abandoned.
When the function is done executing, GDB will silently stop.
After I quit gdb, following output shows up in Aptana console (But this is maybe absolutely useless, probably gdb did this, I don't know):
/home/giron/Aptana Studio 3 Workspace/RedisXmlConcept/bin/main.rb: [BUG] Segmentation fault
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]
-- control frame ----------
c:0001 p:0000 s:0002 b:0002 l:000f68 d:000f68 TOP
---------------------------
-- C level backtrace information -------------------------------------------
/home/giron/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(rb_vm_bugreport+0x5f)[0x7f205488216f]
/home/giron/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(+0x63274) [0x7f205476a274]
/home/giron/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(rb_bug+0xb3) [0x7f205476a413]
/home/giron/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(+0x10c215) [0x7f2054813215]
/lib/libpthread.so.0(+0xeff0) [0x7f20544f9ff0]
/lib/libc.so.6(+0xe40b8) [0x7f20539a80b8]
/lib/libgcc_s.so.1(_Unwind_Backtrace+0x49) [0x7f2050d5b599]
/lib/libc.so.6(backtrace+0x4e) [0x7f20539a81ae]
/home/giron/.rvm/rubies/ruby-1.9.2-p290/bin/ruby(_start+0) [0x400890]
[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html
Just to be sure that I have described problem well, last line of code (before this, Nokogiri parsing and work with Redis database is done):
puts "End"
End is printed out and after this Ruby process will consume 100% CPU for several seconds
This question is related to my previous one here: Nokogiri performance problem where are some more code snippets but since I am focusing on the different approach here (profiling Ruby), I have created new question.
Thank you in advance for any tips, I am pretty much clueless right now.

I was trying to use gdb to profile Ruby process itself
Don't do that. Calling backtrace may not be safe in the context you are executing in, and (apparently) causes your program to SIGSEGV.
Instead, just attach gdb to the Ruby process, and execute thread apply all where command. Update your question with the output, and you may get a better answer.

Related

Why is Valgrind memcheck running numerous times on my Ruby program?

When I run my Ruby program with the following command:
valgrind --tool=memcheck ruby hello.rb
I get outputs for heap, leak and error summaries exactly four times every time.
Full output
All my Ruby program does is that it loads a text file containing 10,000 characters. Memcheck worked just fine for my similar Python programs when I ran them with the same commands. Why do I get four outputs? Is some of them indicating the correct amount of memory used? I'm measuring memory consumptions for my master's thesis, so I really need to find out what's causing this!
Thanks!
By default, valgrind does not 'follow' child processes (i.e. does not follow
the forked children that calls an exec system call).
But by default, a forked child that does not exec will output some results.
Using --child-silent-after-fork=yes should make the output of the forking not
exec-ing child disappear.

See the current line being executed of a ruby script

I have a ruby script, apparently correct, that sometimes stops working (probably on some calls to Postgresql through the pg gem). The problem is that it freezes but doesn't produce any error, so I can't see the line number and I always have to isolate the line by using puts "ok1", puts "ok2", etc. and see where the script stops.
Is there any better way to see the current line being executed (without changing the script)? And maybe the current stack?
You could investigate ruby-debug a project that has been rewritten several times for several different versions of ruby, should allow you to step through your code line by line. I personally prefer printf debugging in a lot of cases though. Also, if I had to take an absolutely random guess at your problem, I might investigate whether or not you're running into a race condition and/or deadlock in your DB.

Introductory Ruby Threading Issue

I've been learning Ruby for the past few days, and I've run into a few issues concerning the implementation of threads. I've programmed in other languages before (mainly Java and C), and I still couldn't figure out what the issue is. I'm running ruby 2.1.2p95 on Ubuntu Server 14.10. The code in question is from Mr. Neighborly's Humble Little Ruby Book:
mate = Thread.new do
puts "Ahoy! Can I be dropping the anchor sir?"
Thread.stop
puts "Aye sir, dropping anchor!"
end
Thread.pass
puts "CAPTAIN: Aye, laddy!"
mate.run
mate.join
The output should be:
Ahoy! Can I be dropping the anchor sir?
CAPTAIN: Aye, laddy!
Aye sir, dropping anchor!
But instead, I'm receiving the following join and deadlock error:
CAPTAIN: Aye, laddy!
Ahoy! Can I be dropping the anchor sir?
ex2.rb:12:in `join': No live threads left. Deadlock? (fatal)
from ex2.rb:12:in `<main>'
I've run into errors with other threading examples from other resources as well, and have tried running the examples on other Ubuntu machines as well as trying Ruby 2.2. Is there a blatant concept that I'm missing out on? Has something changed in recent revisions of Ruby that would deem the examples out-of-date? Thank you for your help!
Has something changed in recent revisions of Ruby that would deem the examples out-of-date?
Yes. It looks like this book was written for Ruby 1.8, which used green threads. Ruby 1.9 onwards uses native threads (where the threads are scheduled by the OS).
Compare the documentation for the Thread.pass method in Ruby 1.8.7:
Invokes the thread scheduler to pass execution to another thread.
In Ruby 2.1.2 (the version you are using), this methods documentation looks like this:
Give the thread scheduler a hint to pass execution to another thread. A running thread may or may not switch, it depends on OS and processor.
So in current versions the scheduling is not deterministic in the way it was in Ruby 1.8.7, the OS is free to ignore the call to Thread.pass and run the main thread first, which causes the problems.
Running this script on my machine (Mac OS 10.9, Ruby 2.2.0) I get both results, sometimes it works and I see:
Ahoy! Can I be dropping the anchor sir?
CAPTAIN: Aye, laddy!
Aye sir, dropping anchor!
Other times it fails with:
CAPTAIN: Aye, laddy!
Ahoy! Can I be dropping the anchor sir?
capt-thread.rb:12:in `join': No live threads left. Deadlock? (fatal)
from capt-thread.rb:12:in `<main>'

Break and continue in GHCi debugger without use of breakpoints

In a traditional imperative debugger such as gdb it is possible to break into program executing with SIGINT, inspect the program state, and eventually resume execution.
While GHCi allows one to break into program execution at an arbitrary point with -fbreak-on-exception, attempting to resume execution with :continue will only lead to the interpreter continuing on with the exception handler and terminating the program,
> let main = findCureForCancer
> :set -fbreak-on-exception
> :trace main
[twiddle thumbs]
[why is this taking so long?]
[maybe something is wrong, I better see what it's doing]
^CStopped at <exception thrown>
_exception :: e = GHC.Exception.SomeException
GHC.IO.Exception.UserInterrupt
> :hist
...
[ahh, looks like this will just take a bit longer]
> :continue
[program should keep running]
Is it possible to break into execution and still resume execution after poking about a bit with the GHCi debugger?
I’m no GHC expert, but I am extremely confident that neither stable GHC nor the current GHC HEAD supports this. The manual mentions nothing about it, and I’ve sourcedived the current HEAD to make sure there’s nothing undocumented, commented out, or surrounded in an #if FALSE. (If you’re interested, the currently-impemented GHCi commands are defined at /ghc/InteractiveUI.hs:136.) Nothing has been posted on the mailing list about this, at least since January 2013, and nobody has filed or closed a bug about it (see the relevant bug tracker search).
This sounds like it would be a useful feature to have – would you file a feature request?

how to get output of rb_backtrace() in gdb for passenger process

I'm trying to dump a backtrace of a passenger process in gdb. I know I should just execute
attach <PID>
call rb_backtrace()
after starting gdb, but I can't figure out where the output is going, I've looked at rails production logs (set to info), nginx logs in /var/logs/nginx but I can't find the output. Any ideas?
I don't know the answer on the ruby end -- I'd guess it is going to the ruby process' stdout or stderr -- but gdb recently got a new feature that is designed to help with this scenario.
The new feature is called "frame filters" and it lets you change how stack traces are presented by writing simple Python scripts that examine the state of the inferior process. For example, you could write such a script that understands the Ruby interpreter, and then have gdb's "bt" automatically interleave interpreted (Ruby) frames with C frames.
For more information, start here and read the next few nodes: http://sourceware.org/gdb/current/onlinedocs/gdb/Frame-Filter-API.html#Frame-Filter-API
I'd like to see this feature be adopted by the various interpreter projects. There's been pretty good adoption of pretty printing, and I think this is a logical next step.

Resources