Conversation
lib/debug/thread_client.rb
Outdated
| b = current_frame&.binding || TOPLEVEL_BINDING | ||
|
|
||
| special_local_variables current_frame do |name, var| | ||
| special_local_variables current_frame, binding: b do |name, var| |
There was a problem hiding this comment.
To evaluate in C frames, we should be able to fallback to TOPLEVEL_BINDING. So relying on the frame's binding is not enough here.
| @success_last_eval = false | ||
|
|
||
| b = current_frame&.eval_binding || TOPLEVEL_BINDING | ||
| b = b.dup |
There was a problem hiding this comment.
For some unknown reasons, I can't reproduce the polluted binding case anymore 🙈 . So I just remove the .dup call.
There was a problem hiding this comment.
Ah, it's because the current implementation only defines them at the frame that has those values. So it's not easy or even impossible to leak them into the program.
For example, the _return is only defined at the end of the method definition, like
def foo
# ...
end # <= hereAnd theoretically no user program will be able to access it, so there's no need to worry about it polluting the program.
There was a problem hiding this comment.
without .dup, TOPLEVEL_BINDING will be affected with assignments.
Maybe it is not intended.
|
|
||
| private def make_binding | ||
| __newb__ = self.self.instance_eval('binding') | ||
| self.local_variables.each{|var, val| |
There was a problem hiding this comment.
This isn't correct as local_variables only yields keys but no values. But the fact that we didn't spot this probably means it's never called anyway.
Prior to this commit, the `_raised` special local doesn't work in C method frame. This PR fixes the issue and improves the coverage.
| repl_binding.local_variables.each do |var| | ||
| next if SPECIAL_LOCAL_VAR_NAMES.include?(var) | ||
| original_binding.local_variable_set(var, repl_binding.local_variable_get(var)) | ||
| end |
There was a problem hiding this comment.
After we dup the original binding, local variables changes made in the REPL won't be applied to it. So we need to manually propagate the values back to the original binding.
There was a problem hiding this comment.
on master, it is propagated. which case do you considering?
[1, 5] in target.rb
=> 1| a = b = c = nil
2| p a, b, c
3|
4|
5| __END__
=>#0 <main> at target.rb:1
(rdbg) n # next command
[1, 5] in target.rb
1| a = b = c = nil
=> 2| p a, b, c
3|
4|
5| __END__
=>#0 <main> at target.rb:2
(rdbg) eval a = b = c = :ok # command
(rdbg) n # next command
:ok
:ok
:ok
There was a problem hiding this comment.
maybe you mean:
[1, 4] in target.rb
1|
=> 2| a = 1
3|
4| __END__
=>#0 <main> at target.rb:2
(rdbg) y = 50 # ruby
50
(rdbg) y
eval error: undefined local variable or method `y' for main:Object
(rdbg)/target.rb:1:in `<main>'
nil
but y is only valid on this debug subsession (when continue, the y will be gone). hmm
There was a problem hiding this comment.
byebug's example.
[master]$ byebug target.rb
[1, 10] in /mnt/c/ko1/src/rb/ruby-debug/target.rb
1:
=> 2: a = 1
3: b = 2
4:
5: __END__
6:
7: require 'foo'
8:
9: __END__
10:
(byebug) y = 10
10
(byebug) p y
10
10
(byebug) n
[1, 10] in /mnt/c/ko1/src/rb/ruby-debug/target.rb
1:
2: a = 1
=> 3: b = 2
4:
5: __END__
6:
7: require 'foo'
8:
9: __END__
10:
(byebug) y
*** NoMethodError Exception: undefined method `end_line=' for nil:NilClass|
I made #441 so please tell me if it is not enough. |
This PR fixes 2 issues:
_raiseddoesn't work in C method frames.