Pycharm breakpoints hang when executed code is inside of a function - debugging

When using Pycharm's debugger, the breakpoints hang if the code being inspected is inside of a function.
If I have a file with the code:
print("Hello")
print("World") # Breakpoint here
And I start a debugging REPL, it prints "Hello", then automatically switches to the "Deubgger" tab and shows the variables in scope. This is what I expect to happen.
If I put it in a function though:
def hello():
print("Hello")
print("World") # Breakpoint here
And then start a debugger REPL and call hello, it prints "Hello" then nothing happens. It just sits there. If I switch to the "Debugger" tab in the console, it's empty except for a "Connected" with an icon in the "Variables" box.
If I leave it long enough, it just seemingly silenty fails and exits the function?:
>>> hello()
Hello
# A few minutes later
>>> # "World" is never printed and it returns.
This is the first time I've used Pycharm's debugger, but I've used IntelliJ's, and it worked as I expected. This issue has survived restarting both the computer.
Does anyone know why the debugger is hanging is this case?

Related

How can I prevent interrupts stepping out from my code while debugging?

I'm currently debugging the linux kernel and it's properly set up with kgdb.
I set a breakpoint to a function I am trying to debug, and the break occurs once I run my program which needs this kernel function to do something, this is wanted. But whenever I try to step through the code with "n" or "si", I always immediately land in arch/x86/include/asm/apic.h, which then runs some interrupt handling code and timers. I'm aware of the kernel being heavily parallelized so it has to move into some other code while being executed, but is it possible to step through the function more comfortably?
What I want to achieve:
before:
-> line A
line B
after:
line A
-> line B
What I have right now:
before:
-> line A
line B
after:
line A
... jumps into way different code here
I think it's hard. Let's think if the interrupts are all aborted, then how can you put your order by keybord or mouse?

How do I set a breakpoint in GDB, but not have the breakpoint halt execution? I just want to be notified in the console if the line is hit

Normally if you set a gdb breakpoint and the the program hits that point, gdb stops execution entirely and lets the user examine and poke around before continuing.
I want the option to be notified of the breakpoint traversal, but not halt execution.
I know I could simply go to the code and add a print statement, but this is annoying especially debugging libraries outside my code which I am not building myself.
Again, I'm already using GDB and want to use 'breakpoints' but just get some sort of notification of when and how many times a line is traversed without halting the whole program's execution. Is this possible?
I want the option to be notified of the breakpoint traversal, but not halt execution.
(gdb) break foo.c:123
(gdb) commands $bpnum
continue
end
This attaches a command to the breakpoint. GDB will print that a breakpoint is hit, then run the attached command, which will continue execution.
You could also print some variables before continuing, or even continue only if some condition is true, and stop otherwise. E.g. "continue if x > 100, but stop if it's not".

How to continue without breakpoints in Byebug

Using the byebug gem gives me the ability to continue until the next breakpoint:
(byebug) help
break -- Sets breakpoints in the source code
catch -- Handles exception catchpoints
condition -- Sets conditions on breakpoints
continue -- Runs until program ends, hits a breakpoint or reaches a line
delete -- Deletes breakpoints
disable -- Disables breakpoints or displays
display -- Evaluates expressions every time the debugger stops
down -- Moves to a lower frame in the stack trace
edit -- Edits source files
enable -- Enables breakpoints or displays
finish -- Runs the program until frame returns
frame -- Moves to a frame in the call stack
help -- Helps you using byebug
history -- Shows byebug's history of commands
info -- Shows several informations about the program being debugged
interrupt -- Interrupts the program
irb -- Starts an IRB session
kill -- Sends a signal to the current process
list -- Lists lines of source code
method -- Shows methods of an object, class or module
next -- Runs one or more lines of code
pry -- Starts a Pry session
ps -- Evaluates an expression and prettyprints & sort the result
quit -- Exits byebug
restart -- Restarts the debugged program
save -- Saves current byebug session to a file
set -- Modifies byebug settings
show -- Shows byebug settings
source -- Restores a previously saved byebug session
step -- Steps into blocks or methods one or more times
thread -- Commands to manipulate threads
tracevar -- Enables tracing of a global variable
undisplay -- Stops displaying all or some expressions when program stops
untracevar -- Stops tracing a global variable
up -- Moves to a higher frame in the stack trace
var -- Shows variables and its values
where -- Displays the backtrace
I looked all over and I cannot find a way to "continue without breakpoints". The only way I can think of is to remove or comment the byebug statements, quit with q! and restart the test.
How can I continue without stopping at other byebug statements in Ruby?
You can use continue! or alias c! since byebug 11.0.0, released on February 15, 2019.
See this PR https://github.com/deivid-rodriguez/byebug/pull/524
If you are working with Rails, you may wanna reset it back on new request, than you can add a filter:
# application_controller.rb
before_action do
if defined?(Byebug) && Byebug.mode == :off && Rails.env.development?
Byebug.mode = nil
end
end
I just found out in the code, that you can stop byebug altogether using:
Byebug.mode = :off
You can't turn it back on, since it won't attach on itself any more, but this is handy, e.g. when just debugging a script that you want to finish running.
A byebug method call in your code is not a 'breakpoint' (thinking of the references to breakpoint in the help output).
As per the help output, breakpoints can be disabled with the disable command. But that does not solve your problem because the next byebug will pause execution again.
Since byebug is just a method call, you can make it conditional:
byebug if SomeModule.byebug?
Then, in SomeModule, you could use a global variable to toggle it on/off. You'd either have to do that on all your calls to byebug, or you could monkey-patch the byebug method to do the same, alias_method_chain or something similar.
"Make Byebug finish executing without exiting Pry" is a similar answer.

Make byebug stay in scope/function after running last line

Say I'm debugging a function like this
def foo {
byebug
x = 1+1
}
Running this, we hit the breakpoint. If I now hit "n", it runs the next line and exits the function. How can I instead remain in the function and inspect x?
Try finish 0.
The finish command should step out the number of frames you specify as an argument. If you specify 0, it has special behavior and just finishes the current frame without stepping out of it.

how to force gdb to stop right after the start of program execution?

I've tried to set breakpoint on every function that makes any sense but program exit before reaching any of those. Is there a way to make program run in step-by-step mode from the start so I can see what's going on?
I'm trying to debug /usr/bin/id if it's important (we have custom plugin for it and it's misbehaved)
P.S. Start command doesn't work for me here(it should be a comment, but I don't have enough rep for it)
Get the program entry point address and insert a breakpoint at that address.
One way to do this is to do info files which gives you for example "Entry point: 0x4045a4". Then do "break *0x4045a4". After run-ning program, it will immediately stop.
From here on you can use single stepping instructions (like step or stepi) to proceed.
You did not tell what system you are trying to debug. If code is in read-only memory you may need to use hardware breakpoints (hbreak) if they are supported by that system.
Use start command
The ‘start’ command does the equivalent of setting a temporary breakpoint at the beginning of the main procedure and then invoking the ‘run’ command.
e.g.
a program with debug info main, and usage like this: main arg1 arg2
gdb main
(gdb) start arg1 arg2
Use starti. Unlike start this stops at the actual first instruction, not at main().
You can type record full right after running the program. This will record all instructions and make them possible for replaying/going back.
For main function, you'd need to type this before reaching the breakpoint so you can set an earlier one by break _start -> _start is a function always called before the standard main function. (apparently applies only to the gcc compiler or similar)
Then continue to main breakpoint and do reverse-stepi to go exactly one instruction back
For more info about recording look here: link

Resources