-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Plain struct not copied correctly when passed to method under certain conditions #89774
Comments
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsDescriptionWhen passing a struct to a method on a class, if there is a second parameter of interface type and an instance of a struct implementing that interface is passed in as the second parameter, then if stepping into the record constructor of the struct and then stepping into the method using a debugger via VS Code or Visual Studio for Mac two of the fields of the first parameter are set to null. This change in the value is "real" and not a visual bug in the debugger, attempting to access or read that value will confirm this. Note that the bug was detected whilst running code without a debugger, when inexplicable null values were detected deeper in the call stack. So under certain conditions it happens even without stepping in the debugger, but this is a reliable repro. ![]() ![]() Reproduction StepsTo produce the bug: place breakpoint on the first line, step into the constructor of the record, then step into the method The second line which passes Also placing breakpoint within Not related to using
Expected behaviorWhen an instance of a plain struct is passed to a method, it is expected that the copy of the struct should arrive whole and intact -- i.e. some fields should not suddenly go missing or be altered. Actual behaviorUnder certain conditions, when passing an instance of a struct to method, some of the fields of the struct are missing in the copy of the instance accessible from within the method. Regression?No response Known WorkaroundsNo response Configuration.net version: 7.0.304 VS Code and Visual Studio for Mac both exhibit the same behaviour. Other informationNo response
|
I tried it on SDKs 7.0.306 and 8.0.100-preview.7. It didn't repro on my macOS machine in either x64 or arm64 builds. |
@odyssjii was this with a debug or release build? |
@AndyAyersMS This is with debug build. Here is repro in VS Code on a different machine also running macOS: dotnet version: 7.0.304 Note that both of the machines are Apple computers with Intel CPUs. |
Do I understand correctly that this only repros under the debugger and requires stepping in a very specific pattern?
Do you happen to have an example that doesn't require attaching and stepping with a debugger? It sounds likely these could be two separate issues. |
Hi @jakobbotsch ! I will try to construct a repro that does not require the stepping in with a debugger. It is not as straightforward though, I still don't know under what condition that happens. |
Thanks @odyssjii! If you are able to reproduce it without a debugger it would definitely indicate some sort of codegen bug. Sadly I don't have an Intel Mac and it seems like VSCode/OmniSharp does not support debugging with an SDK running under Rosetta, so I cannot try it while stepping. @dotnet/jit-contrib Anyone with an Intel Mac who wants to see if they are able to repro it? I've looked at the x64 debug codegen on my Mac and I do not see anything suspicious. I've also tried reproducing it when stepping on Ubuntu x64 (which should be the exact same codegen since it's the same ABI), but haven't had luck. |
@tommcdon Can the diagnostics team take a look at this? It seems to be related to stepping, and unfortunately I don't have an x64 Mac to take a look. |
|
Tagging subscribers to this area: @tommcdon Issue DetailsDescriptionWhen passing a struct to a method on a class, if there is a second parameter of interface type and an instance of a struct implementing that interface is passed in as the second parameter, then if stepping into the record constructor of the struct and then stepping into the method using a debugger via VS Code or Visual Studio for Mac two of the fields of the first parameter are set to null. This change in the value is "real" and not a visual bug in the debugger, attempting to access or read that value will confirm this. Note that the bug was detected whilst running code without a debugger, when inexplicable null values were detected deeper in the call stack. So under certain conditions it happens even without stepping in the debugger, but this is a reliable repro. ![]() ![]() Reproduction StepsTo produce the bug: place breakpoint on the first line, step into the constructor of the record, then step into the method The second line which passes Also placing breakpoint within Not related to using
Expected behaviorWhen an instance of a plain struct is passed to a method, it is expected that the copy of the struct should arrive whole and intact -- i.e. some fields should not suddenly go missing or be altered. Actual behaviorUnder certain conditions, when passing an instance of a struct to method, some of the fields of the struct are missing in the copy of the instance accessible from within the method. Regression?No response Known WorkaroundsNo response Configuration.net version: 7.0.304 VS Code and Visual Studio for Mac both exhibit the same behaviour. Other informationNo response
|
@jakobbotsch would mind explaining why this issue was assigned to the debugger team? The customer provided a repro with the debugger attached but it seems it reproduces without the debugger as well per the comment above. |
Hi @odyssjii, would you mind trying |
I have looked at the codegen and I see nothing wrong with it. If there is a possible codegen issue then I think it is a separate issue -- I would gladly look at that once an example is provided. Note that it is not just about the debugger being attached -- the debugger also needs to be used to step in a specific pattern, as far as I understand. |
@odyssjii would you mind confirming the above statement? From what I understand is that this bug reproduces without the debugger attached and that the debugger-based stepping repro was merely a reliable way of reproducing it. |
Per offline conv with @jakobbotsch, moving this issue back to codegen assuming that the issue reproduces without the debugger and moving to the 9.0 milestone. |
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsDescriptionWhen passing a struct to a method on a class, if there is a second parameter of interface type and an instance of a struct implementing that interface is passed in as the second parameter, then if stepping into the record constructor of the struct and then stepping into the method using a debugger via VS Code or Visual Studio for Mac two of the fields of the first parameter are set to null. This change in the value is "real" and not a visual bug in the debugger, attempting to access or read that value will confirm this. Note that the bug was detected whilst running code without a debugger, when inexplicable null values were detected deeper in the call stack. So under certain conditions it happens even without stepping in the debugger, but this is a reliable repro. ![]() ![]() Reproduction StepsTo produce the bug: place breakpoint on the first line, step into the constructor of the record, then step into the method The second line which passes Also placing breakpoint within Not related to using
Expected behaviorWhen an instance of a plain struct is passed to a method, it is expected that the copy of the struct should arrive whole and intact -- i.e. some fields should not suddenly go missing or be altered. Actual behaviorUnder certain conditions, when passing an instance of a struct to method, some of the fields of the struct are missing in the copy of the instance accessible from within the method. Regression?No response Known WorkaroundsNo response Configuration.net version: 7.0.304 VS Code and Visual Studio for Mac both exhibit the same behaviour. Other informationNo response
|
I'm going to move this to 9.0 and mark it as needing author action since there is nothing actionable from the codegen side at this point. Will happily take another look once a repro case that doesn't involve the debugger/stepping is provided. |
This issue has been marked |
It doesn't repro if COMPlus_EnableAVX=0. If does also repro on .NET 8 even with the AVX PR ##89705 changes. |
Ok, so the summary is that the repro case posted is a duplicate of #78991. We still need to determine whether there is a codegen issue, but we need a repro case that doesn't involve stepping or more details to do that. |
This issue has been marked |
This issue has been automatically marked |
This issue will now be closed since it had been marked |
Description
When passing a struct to a method on a class, if there is a second parameter of interface type and an instance of a struct implementing that interface is passed in as the second parameter, then if stepping into the record constructor of the struct and then stepping into the method using a debugger via VS Code or Visual Studio for Mac two of the fields of the first parameter are set to null.
This change in the value is "real" and not a visual bug in the debugger, attempting to access or read that value will confirm this.
Note that the bug was detected whilst running code without a debugger, when inexplicable null values were detected deeper in the call stack. So under certain conditions it happens even without stepping in the debugger, but this is a reliable repro.
Reproduction Steps
To produce the bug: place breakpoint on the first line, step into the constructor of the record, then step into the method
Z::Foo
, inspect the method argumentobj
andX::D
andX::E
have been set tonull
.The second line which passes
new B()
instead ofnew A()
does not have this issue.Also placing breakpoint within
Z::Foo
and running directly to that point (do not step into record constructor) will NOT produce the bug.Not related to using
record struct
, same problem with a regular struct.Expected behavior
When an instance of a plain struct is passed to a method, it is expected that the copy of the struct should arrive whole and intact -- i.e. some fields should not suddenly go missing or be altered.
Actual behavior
Under certain conditions, when passing an instance of a struct to method, some of the fields of the struct are missing in the copy of the instance accessible from within the method.
Regression?
No response
Known Workarounds
No response
Configuration
.net version: 7.0.304
OS: macOS Ventura 13.4.1
Arch: x64
VS Code and Visual Studio for Mac both exhibit the same behaviour.
Other information
No response
The text was updated successfully, but these errors were encountered: