3

I have a rarely reproduced bug in ruby code. By running my test suite constantly I get it once every 10-15 minutes.

What I want to do is to have the execution recorded step by step and once it fails, go ahead and debug what happened.

I know about https://rr-project.org/ and I used it to debug such things in C++. It basically gives you a complete gdb interface into a recorded replay. Something along the same lines would be great.

unkulunkulu
  • 11,576
  • 2
  • 31
  • 49
  • Well, I did debug it with conventional stuff: logging. But still would be interested if there is a stronger tool :) – unkulunkulu May 22 '23 at 18:50

1 Answers1

1

There is a recording functionality:

# intermittent.rb

require "debug"

# figure out your break condition
binding.b do: "catch TypeError"
binding.b do: "record on"
# this is slow ^

class M
  def m
    var = rand(10)
    var = "1" if rand(1000) == 666
    var
  end
end

loop do
  M.new.m + 1
end

Never really used it, but you can step back:

$ ruby ./intermittent.rb
Stop by #0  BP - Catch  "TypeError"

(rdbg) step back
[replay] [6, 15] in ./intermittent.rb
[replay]      6| 
[replay]      7| class M
[replay]      8|   def m
[replay]      9|     var = rand(10)
[replay]     10|     var = "1" if rand(1000) == 666
[replay] =>  11|     var
[replay]     12|   end
[replay]     13| end
[replay]     14| 
[replay]     15| loop do
[replay] =>#0   M#m at ./intermittent.rb:11
[replay]   #1   block in <main> at ./intermittent.rb:16
[replay]   # and 2 frames (use `bt' command for all frames)

(rdbg) info
[replay] %self = #<M:0x00007f946d07ef28>
[replay] var = "1"

(rdbg) step back
(rdbg) info
[replay] %self = #<M:0x00007f946d07ef28>
[replay] var = 2
# etc...

https://github.com/ruby/debug

Alex
  • 16,409
  • 6
  • 40
  • 56