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

CorDebugStringValue internally returning HRESULT.E_INVALID_ARG - triggering error flow #14

Closed
christophediericx opened this issue Apr 4, 2024 · 6 comments

Comments

@christophediericx
Copy link

Trying to call public HRESULT TryGetString(out string szStringResult) goes off the rails in the following snippet:

int cchString = 0;
int pcchString;
char[] szString;
HRESULT hr = Raw.GetString(cchString, out pcchString, null);

if (hr != HRESULT.S_FALSE && hr != HRESULT.ERROR_INSUFFICIENT_BUFFER && hr != HRESULT.S_OK)
  goto fail;

Raw.GetString returns HRESULT E_INVALIDARG (because of the null?), thus triggering the "fail" path.

This happens with the latest build as was provided in #13

@lordmilko
Copy link
Owner

Which interface is this for? ICorDebugStringValue?

@christophediericx
Copy link
Author

Yes, that is correct.

@lordmilko
Copy link
Owner

ClrDebug assumes that anything that is an array can be retrieved via a two stage process, asking for the length and then creating a buffer with the required length. Some APIs don't actually allow for a two stage query, and require you to figure out the length yourself. I fix rare methods like this as I encounter them. I have confirmed from the implementation of CordbObjectValue::GetString that it requires a valid buffer be specified in the first place, using a length retrieved from ICorDebugStringValue.GetLength. I will update this method to use manual query semantics

@christophediericx
Copy link
Author

christophediericx commented Apr 4, 2024

Playing around with the interface it looks like the two stage process approach would still work as long as what is being passed in is not null initially, e.g., the following works fine.

CorDebugStringValue stringVal = val.As<CorDebugStringValue>();
char[] charBuff = Array.Empty<char>();
stringVal.Raw.GetString(1024, out int len, charBuff);
charBuff = new char[len];
stringVal.Raw.GetString(len, out int _len, charBuff);
string v = new(charBuff, 0, _len);

But as you mentioned, since Length is correctly populated on ICorDebugStringValue anyway there is probably not even a need for a second pass.

@lordmilko
Copy link
Owner

Hi @christophediericx,

Please try the latest build

Regards,
lordmilko

@christophediericx
Copy link
Author

Works like a charm - thank you!

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

2 participants