Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to print these in rust-lldb? #240

Open
vjpr opened this issue Sep 2, 2021 · 3 comments
Open

Is there a way to print these in rust-lldb? #240

vjpr opened this issue Sep 2, 2021 · 3 comments

Comments

@vjpr
Copy link

vjpr commented Sep 2, 2021

I am using CLion with the Rust plugin.

Trying to debug a variable in the swc-project/swc project.

$ p src

(string_cache::atom::Atom<swc_atoms::JsWordStaticSet>) src = {
  unsafe_data = 140464742296960 {
    0 = 140464742296960
  }
  phantom = {}
}
@vjpr
Copy link
Author

vjpr commented Sep 2, 2021

Work is ongoing here intellij-rust/intellij-rust#3000

@vjpr vjpr closed this as completed Sep 2, 2021
@vjpr
Copy link
Author

vjpr commented Sep 6, 2021

I actually will need help with this.

Is there a way to get the string from the unsafe_data ptr?

@vjpr vjpr reopened this Sep 6, 2021
@vjpr
Copy link
Author

vjpr commented Sep 7, 2021

This seems to work for me, but would be interested in input. I am new to Rust.

unsafe_data points to dynamic_set::Entry, which I then just read as a CString - which seems to work although I thought Rust's strs are not null-terminated.

This is using IntelliJ with the Rust plugin. Then you run a debug session.


~/.lldbinit

command script import ./summaries.py
command script import ./lldb_init.py

lldb_init.py

def __lldb_init_module(debugger, internal_dict):
  summary_cmd = (
    "type summary add "
    "Atom "
    "--expand "
    "--hide-empty "
    '--regex "string_cache::atom::Atom" '
    "--python-function summaries.AtomSummary "
    "--category Rust "
  )

  synthetic_cmd = (
      "type synthetic add "
      "Atom "
      "--python-class summaries.AtomProvider "
      '--regex "string_cache::atom::Atom" '
      "--category Rust "
    )


  # NOTE: If this command is incorrect `unknown option` is printed with no other debugging info.
  debugger.HandleCommand(summary_cmd)
  # debugger.HandleCommand(synthetic_cmd)

summaries.py

import lldb
import sys

PY3 = sys.version_info[0] == 3
if PY3:
  from typing import Optional

def AtomSummary(valobj, internal_dict):
  # type: (SBValue, dict) -> str

  process = valobj.GetProcess()

  # length = valobj.GetChildMemberWithName("length").GetValueAsUnsigned()
  length = 200
  if length == 0:
    return '""'

  unsafe_data = valobj.GetChildMemberWithName("unsafe_data")

  # From: https://github.com/servo/string-cache/blob/master/src/atom.rs
  TAG_MASK = 0b_11  # u8
  DYNAMIC_TAG = 0b_00  # u8
  INLINE_TAG = 0b_01  # b8 - len in upper nybble
  STATIC_TAG = 0b_10  # u8
  TAG_MASK = 0b_11
  LEN_OFFSET = 4
  LEN_MASK = 0xF0
  # ---

  # *const dynamic_set::Entry
  # https://docs.rs/string_cache/0.8.1/src/string_cache/dynamic_set.rs.html
  unsafe_data = unsafe_data.GetChildAtIndex(0).GetValueAsUnsigned()

  tag = unsafe_data & TAG_MASK  # u8

  type = 'unknown'
  if (tag == DYNAMIC_TAG): type = 'dynamic'
  if (tag == INLINE_TAG):  type = 'inline_tag'
  if (tag == STATIC_TAG): type = 'static_tag'

  if (unsafe_data == 0):
    return '""'

  # TODO(vjpr): Check tag to decide what to do.

  error = lldb.SBError()
  ptr_to_entry = process.ReadPointerFromMemory(unsafe_data, error)
  if error.Success():
    print('pointer: 0x%x' % ptr_to_entry)
  else:
    print('error: ', error)
    return '""'

  error = lldb.SBError()
  str = process.ReadCStringFromMemory(ptr_to_entry, length, error)

  print("ptr_to_entry: 0x{:x}, entry_ptr: 0x{:x}, tag: {}".format(unsafe_data, ptr_to_entry, tag))
  print("string: {}".format(str))

  return '"%s"' % str

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant