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

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.

Related

Golang get command tty output

I'm using go's exec Run command to get command output, which works great when the command 'Stdout' field is set to os.Stdout, and the error is sent to os.Stderr.
I want to display the output and the error output to the console, but I also want my program to see what the output was.
I then made my own Writer type that did just that, wrote both to a buffer and printed to the terminal.
Here's the problem—some applications change their output to something much less readable by humans when it detects it's not writing to a tty. So the output I get changes to something ugly when I do it in the latter way. (cleaner for computers, uglier for humans)
I wanted to know if there was some way within Go to convince whatever command I'm running that I am a tty, despite not being os.Stdout/os.Stderr. I know it's possible to do using the script bash command, but that uses a different flag depending on Darwin/Linux, so I'm trying to avoid that.
Thanks in advance!
The only practical way to solve this is to allocate a pseudo terminal (PTY) and make your external process use it for its output: since PTY is still a terminal, a process checking whether it's connected to a real terminal thinks it is.
You may start with this query.
The github.com/creack/ptyis probably a good starting point.
The next step is to have a package implementing a PTY actually allocate it, and connect "the other end" of a PTY to your custom writer.
(By the way, there's no point in writing a custom "multi writer" as there exist io.MultiWriter).

Ruby open interactive sub process within the shell

I want to use ruby and in one moment open another program (cfdisk) and let the user interact with it, then return to my code
I can use
exec "cfdisk; ruby another.rb"
but that is very hacky and certainly not the right thing to do
I know about Open3 but i dont know how to use it properly for my usecase. I know that when I use capture3 on irb on Windows it says:
["Running under a virtual console, enabling 256/true-color support\n", "Screen size 28640x499 is not supported; limit 500x500.\nCheck the TERM environment variable.\n", #]
In Arch it opens it but the graphical output isnt present, the keystrokes are registered, they work (for example mc exits with F10) but the window isnt there, just blinking cursor.
parted exits immediately
Tried popen3 but I had no luck with it either
What is wrong with system for this case?
The exec ruby command replaces the running process, so it will not return to your code.
The Open3 library is used when you want to capture stdout and stderr.
Isn't this what you are looking for?
puts "here"
system "cfdisk"
puts 'there'
If you have some screen related issues, this is another issue that you might be able to resolve with different TERM value in the environment variable.

How do I wrap a compiled command line tool for use in Ruby?

I have compiled and tested an open-source command line SIP client for my machine which we can assume has the same architecture as all other machines in our shop. By this I mean that I have successfully passed a compiled binary to others in the shop and they were able to use them.
The tool has a fairly esoteric invocation, a simple bash script piped to it prior to execution as follows:
(sleep 3; echo "# 1"; sleep 3; echo h) | pjsua sip:somephonenumber#ip --flag_1 val --flag_2 val
Note that the leading bash script is an essential part of the functioning of the program and that the line itself seems to be the best practice for use.
In the framing of my problem I am considering the following:
I don't think I can expect very many others in the shop to
compile the binary for themselves
Having a common system architecture in the shop it is reasonable to think that a repo can house the most up-to-date version
Having a way to invoke the tool using Ruby would be the most useful and the most accessible to the
most people.
The leading bash script being passed needs to be wholly extensible. These signify modifiable "scenarios" e.g. in this case:
Call
Wait three seconds
Press 1
Wait three seconds
Hang up
There may be as many as a dozen flags. Possibly a configuration file.
Is it a reasonable practice to create a gem that carries at its core a command line tool that has been previously compiled?
It seems reasonable to create a gem that uses a command line tool. The only thing I'd say is to check that the command is available using system('which psjua') and raising an informative error if it hasn't been installed.
So it seems like the vocabulary I was missing is extension. Here is a great stack discussion on wrapping up a Ruby C extension in a Ruby Gem.
Here is a link to the Gem Guides on creating Gems with Extensions.
Apparently not only is it done but there are sets of best practices around its use.

Ruby: Seeing the output of external calls on the fly

Whenever I wish to run some outside process in Ruby I write something like this:
output = `outer_process`
This works well, and the output of the process is placed into "output". But sometimes the process takes a lot of time and gives a lot of output and I would like to see it on the screen even before it stopped running. Is there a way to do this?
Take a look at the open4 gem. There are some limitations, but assuming there is output to STDOUT from your process, you could do something like this:
Open4.open4( outer_process ) do | pid, pstdin, pstdout, pstderr |
pstdout.each { |line| puts line }
end
This is pretty similar, in terms of underlying mechanisms, to Anand's suggestion in comments.
Note this will not work immediately if the process you call is not flushing STDOUT. If you need to work around that limitation, you will need to provide a terminal for the child process, which is possible in Ruby, but more complicated - see answer to Continuously read from STDOUT of external process in Ruby

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

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.

Resources