Debugging subprocess

I’m using Autotest to automatically run my tests when I modify my code.
I would like to use ruby-debug to debug some of my code. The problem is
whenever I put a debugger statement in my code, the breakpoint is hit,
but the usual debugger output, containing the source code and line
numbers, is not show in my terminal so I can’t see what’s going on. It
takes my input commands, however. After the tests have completed, all
of the debugger output is finally written to the console.

I’ve looked into the Autotest code
(https://github.com/seattlerb/zentest/blob/master/lib/autotest.rb#L343)
and it appears that it is kicking off another ruby subprocess to run the
tests. I’m certain this is why the debugging output isn’t showing up
until the tests have finished running. I’ve tried altering the Autotest
code to use popen() and PTY.spawn() with no luck. The output is still
not showing up when the breakpoints are hit. Can someone help me out?

On Mon, Nov 22, 2010 at 6:06 AM, Chad B. [email protected] wrote:

and it appears that it is kicking off another ruby subprocess to run the
tests. I’m certain this is why the debugging output isn’t showing up
until the tests have finished running. I’ve tried altering the Autotest
code to use popen() and PTY.spawn() with no luck. The output is still
not showing up when the breakpoints are hit. Can someone help me out?

Sounds like a buffering issue. You could try

$stdout.sync = $stderr.sync = true

somewhere early in your code (at least before the breakpoint is hit).
This is just a workaround though.

Kind regards

robert

Thanks Robert, but that didn’t do it. If you look up a few lines in the
code in the link I sent you, you can see the author already did
$stdout.sync = true. Any other ideas? Maybe I’ll just open a ticket on
the project.

On Mon, Nov 22, 2010 at 3:42 PM, Chad B. [email protected] wrote:

Thanks Robert, but that didn’t do it. If you look up a few lines in the
code in the link I sent you, you can see the author already did
$stdout.sync = true. Any other ideas? Maybe I’ll just open a ticket on
the project.

Wrong code. I was talking about your code, i.e. the code that is
supposedly in the process started in line 343 not in autotest.rb and
which you want to debug (I assume).

Kind regards

robert

That didn’t seem to do it either. I put this in test/test_helper.rb,
which is included at the top of each test, and also tried it at the top
of the file in which the debugger statement is located (the class under
test), and neither resolved the issue.

On Mon, Nov 22, 2010 at 5:08 PM, Chad B. [email protected] wrote:

That didn’t seem to do it either. I put this in test/test_helper.rb,
which is included at the top of each test, and also tried it at the top
of the file in which the debugger statement is located (the class under
test), and neither resolved the issue.

I don’t know the details of ruby-debug, but are you sure that you can
actually control your debugger? When I use the debugger which is part
of the standard library I see that it does not work with a closed
stdin. In your test you have a closed stdin (because of open “| …”
with “r”):

17:15:16 ~$ ruby19 -r debug -e ‘10.times do |i|
puts i
end’
Debug.rb
Emacs support available.

-e:1:10.times do |i|
(rdb:1) n
-e:2:puts i
(rdb:1) n
0
-e:2:puts i
(rdb:1) n
1
-e:2:puts i
(rdb:1) n
2
-e:2:puts i
(rdb:1) n
3
-e:2:puts i
(rdb:1) quit
Really quit? (y/n) y
17:17:40 ~$ ruby19 -r debug -e ‘10.times do |i|
puts i
end’ <&-
Debug.rb
Emacs support available.

-e:1:10.times do |i|
(rdb:1)
0
1
2
3
4
5
6
7
8
9
17:17:47 ~$

The first execution is normally, the second with closed stdin. The
debugger shows the prompt once but does not work interactive.

To work around this the debugger would have to open the current
terminal in order to accept commands.

Kind regards

robert

I say I am able to control the debugger because even though I can’t see
the debugging output (the terminal essentially freezes), I can use the
debugger “c” command to continue through each breakpoint, and I finally
see all of the debugging output when the test finishes.

BTW, I am using Ruby 1.8.7 with the ruby-debug gem.

Ryan D. wrote in post #963270:

On Nov 21, 2010, at 21:06 , Chad B. wrote:

I’m using Autotest to automatically run my tests when I modify my code.
I would like to use ruby-debug to debug some of my code.

These two activities are separate (testing vs debugging). Why are you
trying to debug via autotest? Why not just run your tests directly when
you need to debug?

True, they are separate. I guess my answer to that question would be
laziness :slight_smile: It’s easier to just quickly enter a debugger statement,
save off my file and let autotest rerun the test for me than to
open/switch to another terminal window and run the test manually. Not
to mention I would need to either kill the autotest process before
entering my debugger statement, or after debugging, go back to the
autotest window that is now hanging from my debugger statement and
continue it (without seeing the debugging context).

On Nov 21, 2010, at 21:06 , Chad B. wrote:

I’m using Autotest to automatically run my tests when I modify my code.
I would like to use ruby-debug to debug some of my code.

These two activities are separate (testing vs debugging). Why are you
trying to debug via autotest? Why not just run your tests directly when
you need to debug?

On Nov 22, 2010, at 21:19 , Chad B. wrote:

True, they are separate. I guess my answer to that question would be
laziness :slight_smile: It’s easier to just quickly enter a debugger statement,
save off my file and let autotest rerun the test for me than to
open/switch to another terminal window and run the test manually. Not
to mention I would need to either kill the autotest process before
entering my debugger statement, or after debugging, go back to the
autotest window that is now hanging from my debugger statement and
continue it (without seeing the debugging context).

I generally debug entirely through my tests, but if I were in your
situation it’d look something like this:

  • normal development with autotest.
  • get stuck and need to poke internally.
  • switch to autotest terminal, suspend.
  • add breakpoint call where needed and save.
  • switch to autotest terminal, run rake or individual test.
  • poke until I understand the situation, quit.
  • remove breakpoint call and write a test to reproduce the problem
  • switch to autotest terminal and foreground the autotest process.

autotest has to read the output of the tests in order to function. It
cannot let go of that mid-run.