Skip to content

Update gdb.Value.__str__ to iterate through, and return, children val…#21

Open
cmtice wants to merge 2 commits into
sivachandra:masterfrom
cmtice:elements_fix
Open

Update gdb.Value.__str__ to iterate through, and return, children val…#21
cmtice wants to merge 2 commits into
sivachandra:masterfrom
cmtice:elements_fix

Conversation

@cmtice
Copy link
Copy Markdown
Collaborator

@cmtice cmtice commented Sep 6, 2024

Update "gdb.Value.str" to check synthetic values.

This updates gdb.Value.str to iterate through, and return, synthetic children values if there are any, when it is appropriate. It also fixes a small bug in print_elements.test (the assumed return value for negative numbers is incorrect), and updates that test to test this new functionality.

print_elements.test, and update the test to actually test the
new funcitonality as well.
elements" values.

CHECK: gdb.parameter('print elements'): None
CHECK: gdb.parameter('print elements'): 256
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behavior where a negative number means "no limit" was recently removed by llvm/llvm-project#105460. I think it would be better to just remove this CHECK, I don't see a need to check for a specific default value and it makes the test brittle in case lldb decides to change the default.

If you want, you could also simplify the parameter function around line 950 to

def parameter(s: str) -> Any:
    # gdb's 'print elements' is used for number of array elements to print and
    # also max number of chars in a string. lldb has 'target.max-children-count'
    # and 'target.max-string-summary-length', but max-children-count seems like
    # a closer match.
    if s == "print elements":
        return int(_GetSetting('target.max-children-count'))
    return None

but we can also do that as a follow-up if you prefer.

# gdb.parameter('print elements') returns None in this case.
# gdb.parameter('print elements') returns 256 in this case.
debugger.HandleCommand('settings set -- target.max-children-count -99')
print("gdb.parameter('print elements'):", gdb.parameter('print elements'))
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, please remove the negative number test case.

Comment thread gdb/__init__.py
if (t.GetTypeClass() == lldb.eTypeClassStruct):
valstr = str(self._sbvalue_object.GetSyntheticValue())
if (valstr != "No value" and
valstr.find("$1") == -1):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would SBValue.IsValid() work here instead of checking the string against "No value"?

What is the check against "$1" supposed to do? If possible, we should replace this with some API call that tests some property of the SBValue rather than pattern-matching the stringified version. If this is not possible, is it always "$1" or is this the kind of convenience variable that depends on how many expressions you've evaluated before? Can it ever be "$2" or "$3"?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem comes from 'address.test'. There is a part of the text that specifically does not want to use a synthetic value (but there is a valid one). The Check line is
CHECK: Pretty s = pretty MyStruct

What my code returns, without the '$1' test is:
Pretty s = (MyStruct) $1 = pretty MyStruct

I don't really like the '$1' hack, but I'm not sure how to handle/fix this particular case?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using IsValid does work, allowing me to not text for "No Value"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been trying some stuff and it looks like lldb is pretty inflexible about what str(sbvalue) does. It will always generate a string with the following format

(${val.GetType().GetName()}) ${val.GetName()} = ${val.GetSummary()} {
  children
  ...
}

In this case, the "$1" comes from SBValue.GetName(). If we want to match what gdb does, I'm afraid we'll need to implement the logic to generate the string ourselves without relying on str(val).

Or we could live with (MyStruct) $1 = pretty MyStruct and relax address.test to match that output.

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

Successfully merging this pull request may close these issues.

2 participants