vadimcn / codelldb

A native debugger extension for VSCode based on LLDB
https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb
MIT License
2.43k stars 237 forks source link

Rust synth summary KeyError #949

Open erichulburd opened 1 year ago

erichulburd commented 1 year ago

OS:

% uname -a
Darwin BK-****** 22.4.0 Darwin Kernel Version 22.4.0: Mon Mar  6 20:59:28 PST 2023; root:xnu-8796.101.5~3/RELEASE_ARM64_T6000 arm6
% gcc -dumpmachine
arm64-apple-darwin22.4.

VSCode version:

I am actually using nvim:

% nvim --version
NVIM v0.9.0
Build type: Release
LuaJIT 2.1.0-beta3

CodeLLDB version: 1.9.2

Compiler

% rustc --version
rustc 1.68.2 (9eb3afe9e 2023-03-27

Debugee

Rust binary. A silly, simple program:

fn main() {
    let s = Some("");

    if s.is_some() {
        let s1 = s.unwrap();
        println!("s1: {}", s1);
    }

    println!("Hello, world!");
}

The Problem

While I am able to attach to the debugger, set breakpoints, and print variable names, on startup and each time I print a variable, I get Python stacktrace from a KeyError on get_synth_summary in formatters/rust.py for obj id 4294967295.

Console is in 'commands' mode, prefix expressions with '?'.
Executing script: initCommands
Launching: /Users/***/Code/nlsp-settings-demo/target/debug/nlsp-settings-demo
Launched process 83874

[debug-adapter stderr] ERROR(Python) 15:16:35 formatters.rust: 4294967295
Traceback (most recent call last):
  File "/Users/***/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/formatters/rust.py", line 105, in get_synth_summary
    summary = RustSynthProvider.synth_by_id[obj_id].get_summary()
  File "/Users/***/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/lldb/lib/python3.9/weakref.py", line 134, in __getitem__
    o = self.data[key]()
KeyError: 4294967295

[debug-adapter stderr] Traceback (most recent call last):
  File "/Users/***/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/formatters/rust.py", line 85, in summary_fn
    def summary_fn(valobj, dict): return get_synth_summary(synth_class, valobj, dict)
  File "/Users/***/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/formatters/rust.py", line 105, in get_synth_summary
    summary = RustSynthProvider.synth_by_id[obj_id].get_summary()
  File "/Users/***/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/lldb/lib/python3.9/weakref.py", line 134, in __getitem__
    o = self.data[key]()
KeyError: 4294967295

[debug-adapter stderr] ERROR(Python) 15:16:35 formatters.rust: 4294967295
Traceback (most recent call last):
  File "/Users/***/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/formatters/rust.py", line 105, in get_synth_summary
    summary = RustSynthProvider.synth_by_id[obj_id].get_summary()
  File "/Users/***/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/lldb/lib/python3.9/weakref.py", line 134, in __getitem__
    o = self.data[key]()
KeyError: 4294967295
Traceback (most recent call last):
  File "/Users/***/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/formatters/rust.py", line 85, in summary_fn
    def summary_fn(valobj, dict): return get_synth_summary(synth_class, valobj, dict)
  File "/Users/***/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/formatters/rust.py", line 105, in get_synth_summary
    summary = RustSynthProvider.synth_by_id[obj_id].get_summary()
  File "/Users/***/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/lldb/lib/python3.9/weakref.py", line 134, in __getitem__
    o = self.data[key]()
KeyError: 4294967295

Also, it may be useful to know that I am following the snippets in the nvim-dap Wiki for Rust lldb-vscode.

dap.configurations.rust = {
  {
    -- ... the previous config goes here ...,
    initCommands = function()
      -- Find out where to look for the pretty printer Python module
      local rustc_sysroot = vim.fn.trim(vim.fn.system('rustc --print sysroot'))

      local script_import = 'command script import "' .. rustc_sysroot .. '/lib/rustlib/etc/lldb_lookup.py"'
      local commands_file = rustc_sysroot .. '/lib/rustlib/etc/lldb_commands'

      local commands = {}
      local file = io.open(commands_file, 'r')
      if file then
        for line in file:lines() do
          table.insert(commands, line)
        end
        file:close()
      end
      table.insert(commands, 1, script_import)

      return commands
    end,
    -- ...,
  }
vadimcn commented 1 year ago

What exactly do you mean by "print a variable"? Can you please provide a verbose log?

erichulburd commented 11 months ago

Thanks for the patience and not closing the issue. I pivoted over to another project for a while.

What exactly do you mean by "print a variable"?

Using nvim-dap-ui:

dap> ?program_path
{...}
  : <error: No value>
  [raw]: core::option::Option<alloc::string::String>::Some

Beautiful, this is great, thanks.

Can you please provide a verbose log?

Console is in 'commands' mode, prefix expressions with '?'.
Executing script: initCommands

[debug-adapter stderr] INFO(Python) 14:35:22 formatters: Initializing

[debug-adapter stderr] INFO(Python) 14:35:22 formatters.rust: Initializing
Launching: /Users/xxx/Code/path/to/my/exec with my args
Launched process 74911

[debug-adapter stderr] [ERROR codelldb::debug_session] [529] no available capacity

[debug-adapter stderr] [ERROR codelldb::debug_session] [529] no available capacity

[debug-adapter stderr] [ERROR codelldb::debug_session] [529] no available capacity

[debug-adapter stderr] [ERROR codelldb::debug_session] [529] no available capacity
[ERROR codelldb::debug_session] [529] no available capacity
[ERROR codelldb::debug_session] [529] no available capacity

[debug-adapter stderr] [ERROR codelldb::debug_session] [529] no available capacity

# The following repeats 12 times:

[debug-adapter stderr] ERROR(Python) 14:35:26 formatters.rust: 4294967295
Traceback (most recent call last):
  File "/Users/xxx/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/formatters/rust.py", line 105, in get_synth_summary
    summary = RustSynthProvider.synth_by_id[obj_id].get_summary()
  File "/Users/xxx/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/lldb/lib/python3.9/weakref.py", line 134, in __getitem__
    o = self.data[key]()
KeyError: 4294967295

[debug-adapter stderr] Traceback (most recent call last):
  File "/Users/xxx/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/formatters/rust.py", line 85, in summary_fn
    def summary_fn(valobj, dict): return get_synth_summary(synth_class, valobj, dict)
  File "/Users/xxx/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/formatters/rust.py", line 105, in get_synth_summary
    summary = RustSynthProvider.synth_by_id[obj_id].get_summary()
  File "/Users/xxx/.vscode/extensions/vadimcn.vscode-lldb-1.9.2/lldb/lib/python3.9/weakref.py", line 134, in __getitem__
    o = self.data[key]()
KeyError: 4294967295

# end repeats

FWIW, I am running in nvim. I was able to replicate the verbose logging in VSCode by setting RUST_LOG=error,codelldb=debug: https://github.com/vadimcn/codelldb/blob/f4b6ad6dfc20a31da922146b78cbea9543997e5d/extension/novsc/adapter.ts#L42

SlayerOfTheBad commented 6 months ago

I was running into this too, and here's my findings for my case:

https://github.com/vadimcn/codelldb/blob/05502bf75e4e7878a99b0bf0a7a81bba2922cbe3/formatters/rust.py#L115

tries to retrieve an Index of a child with name, using the LLDB function uint32_t SBValue::GetIndexOfChildWithName, as defined at

https://github.com/llvm/llvm-project/blob/780a5116ba68ec8c53b65008b3407479478b2d5e/lldb/source/API/SBValue.cpp#L683

where we can see that UINT32_MAX, i.e. -1, is returned as a fallback value - It's essentially an error code.

There is no check for this error value before

https://github.com/vadimcn/codelldb/blob/05502bf75e4e7878a99b0bf0a7a81bba2922cbe3/formatters/rust.py#L116

Leading it to try to index on an error code.

In my case, the parent value (valobj) seems be either core::option::Option, or core::result::Result. In both cases, both options (Some and None for Option, Ok and Err for Result) throw this error.

I thought this might be generalised over all Enums because of this, but user-defined enums seem to be perfectly fine. It might be that it's enums with generics, but I haven't had the time to investigate that yet.

SlayerOfTheBad commented 6 months ago

@vadimcn because extra info, for good measure.

SlayerOfTheBad commented 6 months ago

Workaround Update (@erichulburd): It seems to be possible to resolve this issue by adding

type summary add -F lldb_lookup.summary_lookup  -e -x -h "^(core::([a-z_]+::)+)Option<.+>::(Some|None)$" --category Rust
type summary add -F lldb_lookup.summary_lookup  -e -x -h "^(core::([a-z_]+::)+)Result<.+>::(Ok|Err)$" --category Rust

(or something that equivalently matches any FQN of Option<T>::(Some|None) and Result<T, E>::(Ok|Err)) to $(rustc --print sysroot)/lib/rustlib/etc/lldb_commands.

This means it should probably be resolved in https://github.com/rust-lang/rust/blob/master/src/etc/lldb_commands rather than it being a codelldb issue. I will look into it a bit more, and then likely make an issue and PR there

SlayerOfTheBad commented 6 months ago

Alright, one more. Been at this all day:

The snippets me and @erichulburd have been using are only for lldb-vscode, which requires an external formatter for the Rust types, provided by the rust project. codelldb has its own formatter, and does not require these scripts.

I think this ticket can be closed as the issue boils down to "Using configs meant for a different tool breaks this tool"