Skip to content

[Debug Info] Gracefully handle invalid String/Vec#155509

Open
Walnut356 wants to merge 2 commits intorust-lang:mainfrom
Walnut356:string_crash
Open

[Debug Info] Gracefully handle invalid String/Vec#155509
Walnut356 wants to merge 2 commits intorust-lang:mainfrom
Walnut356:string_crash

Conversation

@Walnut356
Copy link
Copy Markdown
Contributor

Somewhat related to #150392.

Currently the handling can throw an exception, which we should absolutely not do. It causes issues with debugger adapters (e.g. CodeLLDB will hang forever. Trying to stop the debugger via vscode's interface causes a CodeLLDB to leak memory constantly until RAM is depleted and the OS starts killing processes). The exception has been replaced with a printed error message and a placeholder value.

Additionally, if a String/Vec is in an "invalid" state due to niche optimization (capacity >= (1 << 63), common with Option<String>/Option<Vec<T>>), the pointer and length values will be meaningless, but are not guaranteed to be 0'd. The debugger will happily proceed as if they are useful values, and often do things like <try to read multiple GB of data from the debugee>.

I added simple checks to ensure that the capacity and length are within bounds, and that the pointer is non-null. If any check fails, the string/vec just acts as if it's empty.

Eventually this problem will be solved on LLDB's end via llvm/llvm-project#188487 or similar, but preventing issues on our end in the short term will help a lot.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 19, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 19, 2026

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @Mark-Simulacrum

Copy link
Copy Markdown
Member

@Mark-Simulacrum Mark-Simulacrum left a comment

Choose a reason for hiding this comment

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

r=me with if wording fixed, happy to skip/defer the helper, up to you.

View changes since this review

Comment thread src/etc/lldb_providers.py Outdated

if length <= 0:
return '""'

no_hi_bit_max: int = 1 << ((pointer.GetByteSize() * 8) - 1)
# technically length isn't a NoHighBit<usize>, but if length should always be <= capacity
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
# technically length isn't a NoHighBit<usize>, but if length should always be <= capacity
# technically length isn't a NoHighBit<usize>, but length should always be <= capacity

Not sure what if was meaning to refer to here?

Comment thread src/etc/lldb_providers.py Outdated
else:
raise Exception("ReadMemory error: %s", error.GetCString())
try:
data = process.ReadMemory(pointer.GetValueAsUnsigned(), length, error)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we aim for all process.ReadMemory calls to be wrapped like this? Maybe we should define our own helper to push for that? E.g., StdPathSummaryProvider probably needs the same treatment?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah, yeah that's a good question. It's probably best to, since swig FFI exceptions cause such catastrophic issues.

StdPathSummaryProvider probably needs the same treatment

Atm Path and OsStr providers defer directly to the vec synthetic's get_num_children and get_child_at_index. Since the vec synthetic can now detect invalid state, it'll just report an empty string.

It wouldn't be a bad idea to switch to using process.ReadMemory eventually since it's significantly more performant, but it's not too urgent since paths are usually quite short.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

data = process.ReadMemory(start, length, error)
- doesn't that need to get wrapped with try catch?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤦‍♂️ i might be blind lol

@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 26, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 26, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Apr 26, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 27, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@Walnut356
Copy link
Copy Markdown
Contributor Author

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants