I am new to Ruby so have installed RadRails, Ruby 1.92 and ruby-debug-ide19. I have a very simple ruby program that prints hello world. But when I try and place a breakpoint in the code and run in debug mode all i get is the following line on the console:
Fast Debugger (ruby-debug-ide 0.4.9) listens on :51224
Why does it need to listen on a port anyway? And how can i get it to run my program until the breakpoint?
Personally, I don't bother with an IDE for debugging. I prefer to be closer to the metal... err... command-line, so I use ruby-debug19 from the command-line.
rdebug some_file_to_debug
For the basics use:
b to set your breakpoints
n to step over methods
s to step into methods
c to continue running after hitting a breakpoint
c n to run to a particular line then stop
p to display a value
h will display the built-in help
irb drops into IRB with the current variables pre-initialized so you can poke at things with a stick and see what they'll do.
More docs are at the Ruby-Debug site.
It uses the port to communicate between the IDE and the ruby-debug process, ruby-debug-ide is opening a port and waiting for the IDE to connect to it, but that happens pretty must instantly.
From what you've stated, debugging should already be working: You can right-click and select Toggle breakpoint, or double-click on the left-hand gutter of the editor. When your program hits any enabled breakpoint line the program should suspend and you can inspect variables, the stackframes, execute arbitrary code, step into or through your code, continue, etc.
Related
I would like to debug a C++ program in VSCode. The problem is this program is run as part of a large and messy build system that spawns many processes and prepares input for the program. In other words if I run:
./do the_task
It will compile a load of C++, generate some input and eventually - through several layers of Bash, Python and Makefiles - run something like this:
/very/long/path/to/the_task --lots --of --arguments /very/long/path/to/generated_input.xml
I'd like to debug that process using VSCode/GDB, in such a way that I can
Set breakpoints in the_task.cpp
Just click "Start debugging" with the launch.json set to run do the_task
Unfortunately that doesn't work because by default GDB doesn't follow child processes. You can tell it to but then it will halt the parent process so that only a single process runs at a time. That causes everything to get stuck at some point in my case.
Some ideas I've had:
Is there a way to tell GDB to run a script when a new inferior (process) starts, check the executable name and then detach from the child if it doesn't match?
I could create a proxy GDB/MI wrapper that pretends to VSCode that the program has been started (so the connection doesn't time out), and then when we get to running /very/long/path/to/the_task prefix it with gdb --interpreter=mi and forward on all of the cached commands (to set breakpoints etc.) This seems like quite a lot of work and quite hacky so I'm not sure I like it.
Prefix /very/long/path/to/the_task with gdbserver. Then I can connect to it from VSCode. This is definitely the simplest and most obvious solution but the UX sucks - you have to manually start the command, then wait, then click "start debugging". Plus you're inevitably going to run into port reuse annoyances.
3, but write a custom VSCode extension that automatically starts debugging when it detects gdbserver has started. I've done this for Python debugging so it does work but there are some minor annoyances (e.g. if you restart VSCode and it restores a terminal session it doesn't work). Also it's a fair amount of work.
Is there an obvious solution I'm missing?
I am using Visual Studio Code with the Julia plugin. Regular debugging is impossibly slow, so I a tried to use the package Infiltrator.jl. I insert #infiltrate where I want execution to stop, just like a breakpoint and then start the REPL. Execution indeed stops there and the REPL prompt changes to yellow infil>. So far so good, but when I type something the letters get scrambled, sometimes when I hit Enter and sometimes even before that. It happens before my eyes. After two or three attempts the REPL prompt changes back to green julia> and the REPL freezes.
Anyone familiar with this problem?
As per the readme:
Running code that ends up triggering the #infiltrate REPL mode via inline evaluation in VSCode or Juno can cause issues, so it's recommended to always use the REPL directly.
I am trying to debug a simple "tutorial" ruby program that uses gets to fetch input. It seems the debugger freezes and there is no way to input a line of text into the program when it runs in the debugger. Is this expected? Is it possible to debug interactive ruby console text input?
This seems useful to me when teaching some basic "enter your name and age" type programs to young developers.
Currently VSCode cannot handle this.
For interactive console app debugging where input can be accepted, other IDEs such as Eclipse plus ruby plugin, or Netbeans plus ruby plugin, or an IntelliJ family IDE with ruby plugin (or rubymine itself) is a better choice for teaching ruby with interactive visible execution (single step through code, stop, and accept user input then continue code).
By using the code runner extension and going to : settings => code runner : run in terminal => check , it will work and ask for the input.
03/01/2022 ; in case someone new is looking for the answer.
I have a GUI Ruby tool that needs to spawn a child command-line process, for example ping. If i do this on Windows, the console window will appear and dissapear for console process, that is very annoying. Is it possible to start a process from GUI Ruby script with no console window visible? If i use backtick operator or Kernel#system, the console window will appear, see example below:
require 'Tk'
require 'thread'
Thread.new { `ping 8.8.8.8` }
TkRoot.new.mainloop
The issue is that every executable on Windows is defined to be either a GUI executable or a Console executable (well, there's more detail than that but it doesn't matter here) at the time it is built. The executable that's running your Ruby script is a GUI executable (it also happens to use Tk to actually build a GUI, even if only a very simple one in your screenshot) and the ping executable is a Console executable. If a GUI executable starts a Console executable, a console is automatically created to run the executable in; you can't change this.
Of course, the picture is more complex than that. That's because a console application can actually work with the GUI (it just needs to do the right API calls) and you can use a whole catalogue of tricks to cause the console window to stay out of the way (such as starting ping through an appropriately-configured shortcut file) but such things are rather awkward. The easiest way is to have the console window be there the whole time by making Ruby itself be a console app (through naming your script with the .rb suffix, not .rbw). Yes, it doesn't really get rid of the problem, but it stops any annoying flashing.
If you were using ping as the purpose of your app (i.e., to find out if services were up) then I'd as whether it is possible/advisable to switch to writing the checking code directly in Ruby by connecting to the service instead of pinging it, as ping just measures whether the target OS kernel is alive, and not the service executable. This is a fine distinction, but I've seen machines get into a state where no executables were running but the machine was still responding to pings; this was very strange and can totally break your mental abstractions but can happen. But since you're only using ping as an example, I think you can just focus on the (rather problematic) console handling. Still, if you can do it without running a subprocess then definitely choose that method (on Windows; if you were on any sort of Unix you wouldn't have this problem at all).
It is indeed possible to spawn processes with Ruby. Here is a couple of ways to do it. I am not sure what you mean with
the console window will appear and dissapear for console process
but I think the best way for you to do it is to simply grab out and err and show it to your user in your own window. If you want the native windows console to appear wou probably need to something fancy with windows scripting.
One way to keep a spawned console alive is to have it run a batch file with a PAUSE command at the end:
rungping.bat:
ping %1
pause
exit
In your ruby file:
Thread.new {`start runping.bat 8.8.8.8`}
Just trying to get my irb sessions to actually list the current line of code, and those around it. Similar to what Perl's -d debugging mode lets you ddo.
Its because, when you are doing it interactively, your "sourcefile" is std-in.
If you are looking for a Ruby debugger you could try ruby-debug. It lets you set a breakpoint and then step through the code while displaying a context around the current instruction.