Skip to content

Undefined method '+' for nil #1134

@paul

Description

@paul

Your environment

  • ruby -v: ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux]
  • rdbg -v: rdbg 1.10.0

Describe the bug

I'm trying to debug a separate issue, where it seems the WebConsole thread is hanging instead of reporting an error. When I connect to the puma server with rdbg -A, do th to list the threads, then th 13 (or whatever to pick the stuck thread), then do bt, I get a big exception printed to the puma output:

[
  "DEBUGGER Exception: /home/rando/.local/share/mise/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/debug-1.10.0/lib/debug/thread_client.rb:1252", 
  #<NoMethodError: undefined method '+' for nil>, 
  [
    "/home/rando/.local/share/mise/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/debug-1.10.0/lib/debug/thread_client.rb:85:in 'DEBUGGER__::ThreadClient#default_frame_formatter'", 
    "/home/rando/.local/share/mise/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/debug-1.10.0/lib/debug/thread_client.rb:755:in 'Method#call'", 
    "/home/rando/.local/share/mise/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/debug-1.10.0/lib/debug/thread_client.rb:755:in 'DEBUGGER__::ThreadClient#frame_str'", 
    "/home/rando/.local/share/mise/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/debug-1.10.0/lib/debug/thread_client.rb:742:in 'block in DEBUGGER__::ThreadClient#show_frames'", 
    "<internal:numeric>:257:in 'Integer#times'",
    # ...

(formatted for readability, such as it is)

Also, when this happens, the console input for rdbg doesn't return. I have to hit ^C, and it prints "Stop by SIGURG", and I'm able to input commands again.

To Reproduce

  1. Have a stuck thread using 100% CPU (I'm not sure that that's a requirement, its what I'm investigating).
  2. Connect rdbg to the process, and switch to the stuck thread.
  3. Print the backtrace for that thread.

Expected behavior

Successfully print the backtrace for a frame with nil for block_loc, or determine why a frame would have that.

Additional context

It looks like its coming from thread_client.rb:85, so I printed out the values for level, block_loc, args and frame:

{
  :level     => "",
  :block_loc => nil,
  :args      => [],
  :frame     => #<Object:ActionDispatch::ServerTiming:0x00045ba0
    attr_reader :callee = nil,
    attr_reader :local_variables = nil,
    binding = #<Binding:0x00007f67cf5e0e78>,
    class = ActionDispatch::ServerTiming < Object,
    dupped_binding = nil,
    frame_depth = 17,
    has_raised_exception = nil,
    has_return_value = nil,
    iseq = <RubyVM::InstructionSequence:block in call@/home/rando/.local/share/mise/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/actionpack-7.1.5.1/lib/action_dispatch/middleware/server_timing.rb:58>,
    location = "/home/rando/.local/share/mise/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/actionpack-7.1.5.1/lib/action_dispatch/middleware/server_timing.rb:24:in 'ActionDispatch::ServerTiming::Subscriber#collect_events'",
    raised_exception = nil,
    return_value = nil,
    self = #<ActionDispatch::ServerTiming:0x00007f67e8e5f1f8 ...wall of text, looks like a middleware stack...>,
    show_line = nil
  >
}

I'm able to get it to not blow up by changing the code like this:

-          "#{colorize_blue("block")}#{args_str} in #{colorize_blue(block_loc + level)}"
+          "#{colorize_blue('block')}#{args_str} in #{colorize_blue([block_loc, level].compact.join)}"

But, I'm not sure why block_loc is nil (and level is empty string), and if that indicates a larger problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions