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

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

cmtice
Copy link
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.
@@ -7,7 +7,7 @@ RUN: %lldb -b -o 'command script import print_elements' %t | FileCheck %s
Check target.max-children-count values are correctly translated to "print
elements" values.

CHECK: gdb.parameter('print elements'): None
CHECK: gdb.parameter('print elements'): 256
Copy link
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.

@@ -34,7 +34,7 @@ def __lldb_init_module(debugger, internal_dict):
gdb.printing.register_pretty_printer(gdb.current_objfile(), printer)

# lldb treats all negative values here as 'unlimited'.
# 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
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.

if (t.GetTypeClass() == lldb.eTypeClassStruct):
valstr = str(self._sbvalue_object.GetSyntheticValue())
if (valstr != "No value" and
valstr.find("$1") == -1):
Copy link
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
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
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
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