Skip to content

Produce a summary for non-decodable strings. #8811

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

Merged
merged 1 commit into from
May 29, 2024

Conversation

adrian-prantl
Copy link

@adrian-prantl adrian-prantl commented May 28, 2024

Currently when LLDB encounters an uninitialized string the summary formatter will fail and the user sees something like:

(String) s = {
  _guts = {
    _object = (_countAndFlagsBits = 18374403900871474942, _object = 0xfefefefefefefefe)
  }
}

with this patch this becomes

(String) s = <could not decode string: unexpected discriminator>

@adrian-prantl
Copy link
Author

@swift-ci test

@kastiglione
Copy link

Proposed test case:

var coin: String
if Bool.random() {
    coin = "heads"
} else {
    coin = "tails"
}

When I print the string before it's assigned, the output is:

(lldb) p coin
(String) coin = {
  _guts = {
    _object = (_countAndFlagsBits = 0, _object = 0x0000000000000000)
  }
}

Does this patch address this case? If so what is the error message displayed? I wonder if the error should state "unassigned"/"uninitialized" or something else?

@adrian-prantl
Copy link
Author

Does this patch address this case? If so what is the error message displayed? I wonder if the error should state "unassigned"/"uninitialized" or something else?

The summary (one one machine I tried this on) is

<cannot decode string: memory read failed for 0x18>

but keep in mind that the exact error is going to be random, because we're reading from uninitialized memory.

@adrian-prantl
Copy link
Author

The reason I don't want to say "unassigned" or "uninitialized" is because the summary formatter really doesn't know that. I have encountered this most often in situations where a field's offset was miscomputed (probably biased because I've been debugging these scenarios a lot) and in such a case, "uninitialized" is just wrong.

@adrian-prantl
Copy link
Author

However, I could add a special case for an all-zero string?

Currently when LLDB encounters an uninitialized string the summary
formatter will fail and the user sees something like:

```
(String) s = {
  _guts = {
    _object = (_countAndFlagsBits = 18374403900871474942, _object = 0xfefefefefefefefe)
  }
}
```

with this patch this becomes

(String) s = <could not decode string: unexpected discriminator>
@adrian-prantl
Copy link
Author

Done. Your example has a good chance of printing as <uninitialized> now, depending on whether or not the compiler zeros out the memory first.

@adrian-prantl
Copy link
Author

@swift-ci test

Copy link

@jimingham jimingham left a comment

Choose a reason for hiding this comment

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

I think the goal of this update is good - giving some context around why the summary failed.

It worries me a bit that we are introducing some implicit, unexplained syntax: valid summaries print with quotes around them like "some message" - while <some message> isn't the content of a string but always an error message from the summary provider. Summary output is generally unstructured, so there's no reason this has to be true, and we don't always put quotes around the value.

This happens to be true for string summary provider, so maybe in this case you can get away with just printing an unquoted string with <> delimiters.

But it would be better to be explicit about it and add TypeSummary::GetError be the place where you return these strings. Then the ValueObjectPrinter could decorate the errors in some consistent way, maybe by colorizing them differently? Also if the error delimiter was common, that would help people understand what went on. It would also be nice to have ShouldPrintChildren take the error state into account, many we should print children for strings if we couldn't grok the string? Right now there's no way to do this.

That's all work you should do when adding "summary errors" as a general feature. But since the distinction is pretty clear for strings, maybe it's okay to special case them here.

@adrian-prantl
Copy link
Author

I agree about eventually adding error handling to the summaries. If these actually were errors, then an IDE could e.g., mark them up graphically different.

@adrian-prantl
Copy link
Author

@swift-ci test windows

@adrian-prantl adrian-prantl merged commit 4fbe4c4 into swiftlang:swift/release/6.0 May 29, 2024
3 checks passed
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.

3 participants