Hello,
I've put together some basic implementation of ABRT support for Ruby. It means that whenever your application/library fails in Ruby code (note that this does not catch segfaults), it will be easy to your users to report such problem into Bugzilla.
Source code: https://github.com/voxik/abrt-ruby Gem: gem install abrt
ATM, there are several ways how to test the gem:
1) "require 'abrt'" in your code, as soon as possible, but later then rubygems if you are using Ruby 1.8. 2) If you are already using Ruby 1.9, you can add "RUBYOPT='-rabrt'" into your environment. This assures that every time Ruby is started, the abrt gem is activated. Unfortunately, this doesn't work with Ruby 1.8, since RubyGems are not loaded by default and "RUBYOPT='-rubygems -rabrt'" does not work for some reason :/
Please note that ABRT reports errors just for Ruby libraries managed by RPM. If something appears to not work as expected, it is good to observe /var/log/messages for more details.
In the future, I'd love to see this integrated into Ruby (probably in F18?). I already asked upstream about possible integration [1], but if went without response, so it seems that I will have to come with some proposal.
I'd love to here your comments and of course your patches :)
Thank you
Vit
[1] http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/42236
(4/16/12 3:54 PM), Vít Ondruch wrote:
Hello,
I've put together some basic implementation of ABRT support for Ruby. It means that whenever your application/library fails in Ruby code (note that this does not catch segfaults), it will be easy to your users to report such problem into Bugzilla.
Source code: https://github.com/voxik/abrt-ruby Gem: gem install abrt
ATM, there are several ways how to test the gem:
- "require 'abrt'" in your code, as soon as possible, but later then rubygems if you are using Ruby 1.8.
- If you are already using Ruby 1.9, you can add "RUBYOPT='-rabrt'" into your environment. This assures that every time Ruby is started, the abrt gem is activated. Unfortunately, this doesn't work with Ruby 1.8, since RubyGems are not loaded by default and "RUBYOPT='-rubygems -rabrt'" does not work for some reason :/
Please note that ABRT reports errors just for Ruby libraries managed by RPM. If something appears to not work as expected, it is good to observe /var/log/messages for more details.
In the future, I'd love to see this integrated into Ruby (probably in F18?). I already asked upstream about possible integration [1], but if went without response, so it seems that I will have to come with some proposal.
I'd love to here your comments and of course your patches :)
Hello,
I have a question. Can we detect abrt enableness on runtime? I mean, I want to integrate it to upstream. Ruby already has similar support code for Mac. but I also want to fallback original behavior when a user disable abrt service.
Hello Motohiro,
Dne 17.4.2012 17:58, KOSAKI Motohiro napsal(a):
Hello,
I have a question. Can we detect abrt enableness on runtime?
I am not sure what is the best way how to detect ABRT enableness, but I can clarify it with upstream. Actually such checking is not required I would say, because:
1) If ABRT is not enabled, the gem cannot send the report via socket. Only record into /var/log/messages is made. 2) I would like to see Ruby in Fedora automatically to try to require abrt.rb and fail silently if the gem is not installed.
I mean, I want to integrate it to upstream. Ruby already has similar support code for Mac.
Could you please elaborate what Mac support Ruby already has?
but I also want to fallback original behavior when a user disable abrt service.
The original behavior is always preserved (assuming that there is no bug in the ABRT gem :)), i.e. the exception is written to terminal for example. The report to ABRT is just extension.
With regards to SEGV, I believe that they are caught by ABRT anyway, since Ruby itself is C, so they should be handled by ABRT C hook. Or are you aware of some specific example which does not work that way?
Vit
I have a question. Can we detect abrt enableness on runtime?
I am not sure what is the best way how to detect ABRT enableness, but I can clarify it with upstream. Actually such checking is not required I would say, because:
- If ABRT is not enabled, the gem cannot send the report via socket. Only
record into /var/log/messages is made. 2) I would like to see Ruby in Fedora automatically to try to require abrt.rb and fail silently if the gem is not installed.
Hmm.. this is not an item I wanted. when abrt is disabled, ruby shouldn't run any additional code. any new code path might make application deadlock. for clarify, the worst scenario is, ruby or ruby extention made memory corruption and libc internal function made SEGV and then libc lock (libc internal mutex) was not released. any libc call may makes deadlock. and if ruby don't exit, abrt can't record correct information and more importantly, crash watching daemon can't know ruby stop to working and then fail to restart it.
I mean, I want to integrate it to upstream. Ruby already has similar support code for Mac.
Could you please elaborate what Mac support Ruby already has?
Ruby didn't need any additional code for Mac. Its abrt like crash logger automatically save a crash information. we only remove redundunt code.
but I also want to fallback original behavior when a user disable abrt service.
The original behavior is always preserved (assuming that there is no bug in the ABRT gem :)), i.e. the exception is written to terminal for example. The report to ABRT is just extension.
With regards to SEGV, I believe that they are caught by ABRT anyway, since Ruby itself is C, so they should be handled by ABRT C hook. Or are you aware of some specific example which does not work that way?
Vit
ruby-sig mailing list ruby-sig@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/ruby-sig
Dne 18.4.2012 03:44, KOSAKI Motohiro napsal(a):
I have a question. Can we detect abrt enableness on runtime?
I am not sure what is the best way how to detect ABRT enableness, but I can clarify it with upstream. Actually such checking is not required I would say, because:
- If ABRT is not enabled, the gem cannot send the report via socket. Only
record into /var/log/messages is made. 2) I would like to see Ruby in Fedora automatically to try to require abrt.rb and fail silently if the gem is not installed.
Hmm.. this is not an item I wanted. when abrt is disabled, ruby shouldn't run any additional code.
Hmm, there might be some additional code on startup checking if ABRT is enabled and install the at_exit handler only if it is. However there are two issues to consider:
1) There will be probably some slowdown to Ruby startup time, which may penalize especially short scripts, but this might be unnoticeable. 2) What if the Ruby process is some long running service and ABRT is started/installed later? But this looks a bit silly :)
any new code path might make application deadlock.
Yes, that is true that this handler might get things worse, but it is aimed to handle problems in your Ruby code, such as if you change some functionality, but not adjust the rest of the application. So it is not designed to check some errors in C code or extensions. However I really should check, if for example SEGV in nokogiri is caught by ABRT.
for clarify, the worst scenario is, ruby or ruby extention made memory corruption and libc internal function made SEGV and then libc lock (libc internal mutex) was not released. any libc call may makes deadlock. and if ruby don't exit, abrt can't record correct information and more importantly, crash watching daemon can't know ruby stop to working and then fail to restart it.
Hm, this is probably far beyond ABRT capabilities and design. Do you believe that such problem is somehow detectable?
I mean, I want to integrate it to upstream. Ruby already has similar support code for Mac.
Could you please elaborate what Mac support Ruby already has?
Ruby didn't need any additional code for Mac. Its abrt like crash logger automatically save a crash information. we only remove redundunt code.
What I need to get this working is some thing like automatic inclusion of os_prelude.rb during build time if that is available in build directory, or alternatively some configuration option to achieve the same, i.e. to require some .rb file which is somewhere available and treat it as a prelude file. Of course I can patch the Ruby build to include some os_prelude.rb, but I'd like to see this supported by upstream.
but I also want to fallback original behavior when a user disable abrt service.
The original behavior is always preserved (assuming that there is no bug in the ABRT gem :)), i.e. the exception is written to terminal for example. The report to ABRT is just extension.
With regards to SEGV, I believe that they are caught by ABRT anyway, since Ruby itself is C, so they should be handled by ABRT C hook. Or are you aware of some specific example which does not work that way?
Vit
ruby-sig mailing list ruby-sig@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/ruby-sig
ruby-sig mailing list ruby-sig@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/ruby-sig
(4/16/12 3:54 PM), Vít Ondruch wrote:
Hello,
I've put together some basic implementation of ABRT support for Ruby. It means that whenever your application/library fails in Ruby code (note that this does not catch segfaults), it will be easy to your users to report such problem into Bugzilla.
Source code: https://github.com/voxik/abrt-ruby Gem: gem install abrt
Oops. This seems wrong idea. When SEGV occur, ruby code can't work. we need simple C extension, maybe. At least, you want to merge it into upstream.
Hi,
Updated ABRT gem version 0.0.2 is available at RubyGems.org if you like to test it. I'd love to hear some feedback.
There were done following changes:
* Improved code base * Better handling of some edge cases, such as call to Kernel#exit or Ctrl+C event * Test suite added * Improved documentation
I also prepared RPM for Fedora. Review is available at https://bugzilla.redhat.com/show_bug.cgi?id=838568
Vit
On Mon, Jul 9, 2012 at 9:47 AM, Vít Ondruch vondruch@redhat.com wrote:
Hi,
Updated ABRT gem version 0.0.2 is available at RubyGems.org if you like to test it. I'd love to hear some feedback.
There were done following changes:
- Improved code base
- Better handling of some edge cases, such as call to Kernel#exit or Ctrl+C
event
- Test suite added
- Improved documentation
I also prepared RPM for Fedora. Review is available at https://bugzilla.redhat.com/show_bug.cgi?id=838568
def self.report(backtrace, io = abrt_socket) io.write "PUT / HTTP/1.1\r\n\r\n" io.write "PID=#{Process.pid}\0" io.write "EXECUTABLE=#{$PROGRAM_NAME}\0"
Hmm..
If I understand correctly, EXECUTABLE key is used for looking up package name from abrt daemon. Then, It should be realfilename. See below abrt doc.
abrt/doc/interpreted-languages:
EXECUTABLE The file with the main entry point of the application. Might be a JAR archive, a script file, a bytecode file, or the interpreter. It should be a real file on the filesystem, so ABRT can check the origin of the
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
However, PROGRAM_NAME can be changed from ruby scripting. e.g. $0 = "foobar"
# TODO: Do we need specialized Ruby analyzer? # io.write "ANALYZER=Ruby\0" io.write "ANALYZER=Python\0" io.write "BASENAME=rbhook\0" io.write "REASON=#{backtrace.first}\0" io.write "BACKTRACE=#{backtrace.join("\n")}\0"
btw, I wrote a patch to redirect rb_bug() message to abrtd too. Is it interesting for you?
https://github.com/kosaki/ruby/commit/6283017dc2747f306808ce530292dc51273746...
Hi Motohiro,
Thank you for your feedback.
Dne 9.7.2012 22:46, KOSAKI Motohiro napsal(a):
On Mon, Jul 9, 2012 at 9:47 AM, Vít Ondruch vondruch@redhat.com wrote:
Hi,
Updated ABRT gem version 0.0.2 is available at RubyGems.org if you like to test it. I'd love to hear some feedback.
There were done following changes:
- Improved code base
- Better handling of some edge cases, such as call to Kernel#exit or Ctrl+C
event
- Test suite added
- Improved documentation
I also prepared RPM for Fedora. Review is available at https://bugzilla.redhat.com/show_bug.cgi?id=838568
def self.report(backtrace, io = abrt_socket) io.write "PUT / HTTP/1.1\r\n\r\n" io.write "PID=#{Process.pid}\0" io.write "EXECUTABLE=#{$PROGRAM_NAME}\0"
Hmm..
If I understand correctly, EXECUTABLE key is used for looking up package name from abrt daemon. Then, It should be realfilename. See below abrt doc.
abrt/doc/interpreted-languages:
EXECUTABLE The file with the main entry point of the application. Might be a JAR archive, a script file, a bytecode file, or the interpreter. It should be a real file on the filesystem, so ABRT can check the origin of the
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
However, PROGRAM_NAME can be changed from ruby scripting. e.g. $0 = "foobar"
You are right, you can change the $PROGRAM_NAME. I'll make several points here
* Is there some more reliable way how to detect the script name? * What is the use case and how widely is this practice used? Can we ignore this case? Python handler ignores it if I am not mistaken (but we should be better of course ;) * ABRT ignores such failure and it just logs something like "Executable 'foo.rb' doesn't belong to any package" into /var/log/messages.
# TODO: Do we need specialized Ruby analyzer? # io.write "ANALYZER=Ruby\0" io.write "ANALYZER=Python\0" io.write "BASENAME=rbhook\0" io.write "REASON=#{backtrace.first}\0" io.write "BACKTRACE=#{backtrace.join("\n")}\0"
btw, I wrote a patch to redirect rb_bug() message to abrtd too. Is it interesting for you?
https://github.com/kosaki/ruby/commit/6283017dc2747f306808ce530292dc51273746...
I'll take a closer look later if you don't mind, but could you please elaborate the patch a bit? I know you have risen some concerns previously. What is advantage of your patch or how is it different? What scenarios it should handle and what not?
Thank you.
Vit
On Tue, Jul 10, 2012 at 9:29 AM, Vít Ondruch vondruch@redhat.com wrote:
You are right, you can change the $PROGRAM_NAME. I'll make several points here
- Is there some more reliable way how to detect the script name?
- What is the use case and how widely is this practice used? Can we ignore
this case? Python handler ignores it if I am not mistaken (but we should be better of course ;)
- ABRT ignores such failure and it just logs something like "Executable
'foo.rb' doesn't belong to any package" into /var/log/messages.
If the Ruby documentation is to be believed you could use Kernel#caller to get a stack trace which apparently has a set format including the file name. It is of course swapping a user modifiable value for something slightly more fragile (it could potentially change in some future version). Perhaps use the current way and fall back to Kernel#caller if $0 doesn't resolve to a real file (which would indicate it has been modified.
None of this of course covers scenarios where user/other code is loaded from within another program (think rake, thor, etc) but in the case of an exception, Exception#backtrace is the same format as Kernel#caller.
Dne 10.7.2012 16:12, John5342 napsal(a):
On Tue, Jul 10, 2012 at 9:29 AM, Vít Ondruch vondruch@redhat.com wrote:
You are right, you can change the $PROGRAM_NAME. I'll make several points here
- Is there some more reliable way how to detect the script name?
- What is the use case and how widely is this practice used? Can we ignore
this case? Python handler ignores it if I am not mistaken (but we should be better of course ;)
- ABRT ignores such failure and it just logs something like "Executable
'foo.rb' doesn't belong to any package" into /var/log/messages.
If the Ruby documentation is to be believed you could use Kernel#caller to get a stack trace which apparently has a set format including the file name. It is of course swapping a user modifiable value for something slightly more fragile (it could potentially change in some future version). Perhaps use the current way and fall back to Kernel#caller if $0 doesn't resolve to a real file (which would indicate it has been modified.
None of this of course covers scenarios where user/other code is loaded from within another program (think rake, thor, etc) but in the case of an exception, Exception#backtrace is the same format as Kernel#caller.
John, thank you. Use of the Exception#backtrace is nice idea! Have to take a look into.
It might be even possible to extract the "latest gem" in the backtrace and assign the bug to it, but I am not sure if that is good idea, since the error might be in the gem as well as in its caller. In that case, I would expect that the library consumer/application author has "more" knowledge about the library then the library author about the consumer/application. Thoughts?
Vit
On Tue, Jul 10, 2012 at 3:27 PM, Vít Ondruch vondruch@redhat.com wrote:
Dne 10.7.2012 16:12, John5342 napsal(a):
If the Ruby documentation is to be believed you could use Kernel#caller to get a stack trace which apparently has a set format including the file name. It is of course swapping a user modifiable value for something slightly more fragile (it could potentially change in some future version). Perhaps use the current way and fall back to Kernel#caller if $0 doesn't resolve to a real file (which would indicate it has been modified.
None of this of course covers scenarios where user/other code is loaded from within another program (think rake, thor, etc) but in the case of an exception, Exception#backtrace is the same format as Kernel#caller.
John, thank you. Use of the Exception#backtrace is nice idea! Have to take a look into.
It might be even possible to extract the "latest gem" in the backtrace and assign the bug to it, but I am not sure if that is good idea, since the error might be in the gem as well as in its caller. In that case, I would expect that the library consumer/application author has "more" knowledge about the library then the library author about the consumer/application. Thoughts?
Yeah i think you are right there. The entry point is the only guaranteed thing. The more you narrow things down from there the more work is needed to avoid getting things wrong so it really depends on how much effort you want to put into it.
Certainly if i was maintaining a ruby program i would not mind receiving bugs that are in the end caused by a library used by my program. I would easily be able to forward it on plus if i have had a bug then i can watch for the fix etc. Bonus points though if the report could include a complete list of loaded gems/packages (to help in ruling out monkey patching issues and the like) and the list of gems/packages in the call stack at the time of the error (would make it much easier to see where the problems _could_ be).
Dne 10.7.2012 17:06, John5342 napsal(a):
On Tue, Jul 10, 2012 at 3:27 PM, Vít Ondruch vondruch@redhat.com wrote:
Dne 10.7.2012 16:12, John5342 napsal(a):
If the Ruby documentation is to be believed you could use Kernel#caller to get a stack trace which apparently has a set format including the file name. It is of course swapping a user modifiable value for something slightly more fragile (it could potentially change in some future version). Perhaps use the current way and fall back to Kernel#caller if $0 doesn't resolve to a real file (which would indicate it has been modified.
None of this of course covers scenarios where user/other code is loaded from within another program (think rake, thor, etc) but in the case of an exception, Exception#backtrace is the same format as Kernel#caller.
John, thank you. Use of the Exception#backtrace is nice idea! Have to take a look into.
It might be even possible to extract the "latest gem" in the backtrace and assign the bug to it, but I am not sure if that is good idea, since the error might be in the gem as well as in its caller. In that case, I would expect that the library consumer/application author has "more" knowledge about the library then the library author about the consumer/application. Thoughts?
Yeah i think you are right there. The entry point is the only guaranteed thing. The more you narrow things down from there the more work is needed to avoid getting things wrong so it really depends on how much effort you want to put into it.
Certainly if i was maintaining a ruby program i would not mind receiving bugs that are in the end caused by a library used by my program. I would easily be able to forward it on plus if i have had a bug then i can watch for the fix etc.
Right. I will keep it simple for now, report it to the entry point application. Thinking about gems would definitely add more fragility than anything else.
Bonus points though if the report could include a complete list of loaded gems/packages (to help in ruling out monkey patching issues and the like) and the list of gems/packages in the call stack at the time of the error (would make it much easier to see where the problems _could_ be).
This could be done. The python handler for example adds values of local variables as a bonus. This might be also very valuable information. Will try to keep that idea in mind, if I'll get bored ;)
Vit
On Tue, Jul 10, 2012 at 4:27 PM, Vít Ondruch vondruch@redhat.com wrote:
Dne 10.7.2012 17:06, John5342 napsal(a):
Bonus points though if the report could include a complete list of loaded gems/packages (to help in ruling out monkey patching issues and the like) and the list of gems/packages in the call stack at the time of the error (would make it much easier to see where the problems _could_ be).
This could be done. The python handler for example adds values of local variables as a bonus. This might be also very valuable information. Will try to keep that idea in mind, if I'll get bored ;)
Local variables would be great although at this moment in time i can't think how to get at them by the time an exception has been caught. If you are interested in and want any help with my own suggestions i would be more than happy to fork and submit a potential implementation upstream when i get some free time next week :-)
Dne 10.7.2012 17:57, John5342 napsal(a):
On Tue, Jul 10, 2012 at 4:27 PM, Vít Ondruch vondruch@redhat.com wrote:
Dne 10.7.2012 17:06, John5342 napsal(a):
Bonus points though if the report could include a complete list of loaded gems/packages (to help in ruling out monkey patching issues and the like) and the list of gems/packages in the call stack at the time of the error (would make it much easier to see where the problems _could_ be).
This could be done. The python handler for example adds values of local variables as a bonus. This might be also very valuable information. Will try to keep that idea in mind, if I'll get bored ;)
Local variables would be great although at this moment in time i can't think how to get at them by the time an exception has been caught. If you are interested in and want any help with my own suggestions i would be more than happy to fork and submit a potential implementation upstream when i get some free time next week :-)
Of course, pull requests are more than welcome :) Thank you.
Vit
Dne 9.7.2012 22:46, KOSAKI Motohiro napsal(a):
On Mon, Jul 9, 2012 at 9:47 AM, Vít Ondruch vondruch@redhat.com wrote:
Hi,
Updated ABRT gem version 0.0.2 is available at RubyGems.org if you like to test it. I'd love to hear some feedback.
There were done following changes:
- Improved code base
- Better handling of some edge cases, such as call to Kernel#exit or Ctrl+C
event
- Test suite added
- Improved documentation
I also prepared RPM for Fedora. Review is available at https://bugzilla.redhat.com/show_bug.cgi?id=838568
def self.report(backtrace, io = abrt_socket) io.write "PUT / HTTP/1.1\r\n\r\n" io.write "PID=#{Process.pid}\0" io.write "EXECUTABLE=#{$PROGRAM_NAME}\0"
Hmm..
If I understand correctly, EXECUTABLE key is used for looking up package name from abrt daemon. Then, It should be realfilename. See below abrt doc.
abrt/doc/interpreted-languages:
EXECUTABLE The file with the main entry point of the application. Might be a JAR archive, a script file, a bytecode file, or the interpreter. It should be a real file on the filesystem, so ABRT can check the origin of the
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
However, PROGRAM_NAME can be changed from ruby scripting. e.g. $0 = "foobar"
The executable name is now always obtained from the backtrace:
https://github.com/voxik/abrt-ruby/commit/8c5dbb9f4db3b6328a8945e0eff17b57c6...
Vit
Dne 13.7.2012 16:12, Vít Ondruch napsal(a):
Dne 9.7.2012 22:46, KOSAKI Motohiro napsal(a):
On Mon, Jul 9, 2012 at 9:47 AM, Vít Ondruch vondruch@redhat.com wrote:
Hi,
Updated ABRT gem version 0.0.2 is available at RubyGems.org if you like to test it. I'd love to hear some feedback.
There were done following changes:
- Improved code base
- Better handling of some edge cases, such as call to Kernel#exit or
Ctrl+C event
- Test suite added
- Improved documentation
I also prepared RPM for Fedora. Review is available at https://bugzilla.redhat.com/show_bug.cgi?id=838568
def self.report(backtrace, io = abrt_socket) io.write "PUT / HTTP/1.1\r\n\r\n" io.write "PID=#{Process.pid}\0" io.write "EXECUTABLE=#{$PROGRAM_NAME}\0"
Hmm..
If I understand correctly, EXECUTABLE key is used for looking up package name from abrt daemon. Then, It should be realfilename. See below abrt doc.
abrt/doc/interpreted-languages:
EXECUTABLE The file with the main entry point of the application. Might be a JAR archive, a script file, a bytecode file, or the interpreter. It should be a real file on the filesystem, so ABRT can check the origin of the
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
However, PROGRAM_NAME can be changed from ruby scripting. e.g. $0 = "foobar"
The executable name is now always obtained from the backtrace:
https://github.com/voxik/abrt-ruby/commit/8c5dbb9f4db3b6328a8945e0eff17b57c6...
Sigh, I took the most straight-forward approach and missed this line https://github.com/voxik/abrt-ruby/blob/master/lib/abrt/handler.rb#L8
Vit
https://github.com/voxik/abrt-ruby/commit/8c5dbb9f4db3b6328a8945e0eff17b57c6...
Sigh, I took the most straight-forward approach and missed this line https://github.com/voxik/abrt-ruby/blob/master/lib/abrt/handler.rb#L8
?
$0 is an alias name of $PROGRAM_NAME.
ruby-sig@lists.fedoraproject.org