1

The problem: byebug or pry output is returning via HTTP instead of on console.

I have a webrick.rb script which has a CGIHandler mounted with a dispatch.fcgi script passed to it:

server.mount("/", WEBrick::HTTPServlet::CGIHandler, File.expand_path(File.dirname(FILE))+"/dispatch.fcgi")

Thus, webrick passes each HTTP request to this script via the _do_GET_ method.

This method spawns a subprocess using IO::popen as per this code snippet from

/usr/local/rvm/rubies/ruby-2.2.10/lib/ruby/2.2.0/webrick/httpservlet/cgihandler.rb

class CGIHandler < AbstractServlet
      Ruby = RbConfig.ruby # :nodoc:
      CGIRunner = "\"#{Ruby}\" \"#{WEBrick::Config::LIBDIR}/httpservlet/cgi_runner.rb\"" # :nodoc:

      ##
      # Creates a new CGI script servlet for the script at +name+

      def initialize(server, name)
        super(server, name)
        @script_filename = name
        @tempdir = server[:TempDir]
        @cgicmd = "#{CGIRunner} #{server[:CGIInterpreter]}"
      end

      # :stopdoc:

      def do_GET(req, res)
        cgi_in = IO::popen(@cgicmd, "wb")

When I use byebug or binding.pry in the source code files, their stdout is returned to the parent process which is then returned eventually by the dispatch.fcgi script and thus returned via HTTP. Obviously this is useless as I cannot interact with it.

To fix this, my idea is to have byebug rather use different IO streams rather than stdout and stdin or otherwise redirect it somehow to a different file descriptor under /dev/pts . Then, I can write a small console.rb script to interact with those file descriptors/IO streams instead and in this way I'm able to interact with byebug or pry.

I am new to ruby, byebug/pry and webrick and my idea sounds over complicated. I don't really know how to achieve this (e.g. how do I create new file descriptors in OS) and I'm sure there must be some easier way than to hack the byebug/pry gems and mess with the OS? The resources out there to debug CGI are very slim.

raven
  • 11
  • 2
  • [pry-remote](https://github.com/Mon-Ouie/pry-remote) might work for your use-case – Turtlefight Jul 18 '19 at 16:31
  • yeah I also thought maybe using TCP sockets instead, but was hoping someone has solved a similar challenge in a simpler manner that I'm not thinking of. But pry-remote seems worth a try – raven Jul 18 '19 at 17:55
  • pry-remote uses TCP to allow you to connect to the pry session remotely (it uses [DRb](https://ruby-doc.org/stdlib-2.6.3/libdoc/drb/rdoc/DRb.html), which internally uses TCP). – Turtlefight Jul 18 '19 at 18:19
  • Thanks @Turtlefight, you pointed me in the right direction. I searched for byebug remote debugging and used https://github.com/deivid-rodriguez/byebug/blob/master/GUIDE.md, works great. I had tunnel vision after spending hours to get things working my way, so the answer was simple in the end. – raven Jul 18 '19 at 20:01

0 Answers0