I get failure of TryGetValue in PushObject results in wrong data being passed back #73

Closed
LucienMP opened this Issue Mar 1, 2014 · 6 comments

Comments

Projects
None yet
4 participants
@LucienMP

LucienMP commented Mar 1, 2014

When I have this running under Unity (Mono 2.0) I am catching the following problem ONLY on specific data types. Can anyone confirm, or at least explain the issue to me - I am going to assume a broken VM with broken Equals() implementation.

C# Side
struct Top { struct sub y; }
struct sub { struct sub2 z; }
struct sub2 { int someval; }

LUA Side:
-- x=new Top() from C#
print( "Z is type:" .. tostring( x.y.z:GetType() ) .. " should be sub2" )

Result:
Z is type: sub should be sub2

Any attempt at accessing past x.y results in getting back "y" from LUA.
The result seems to be due to TryGetValue's internal "Equals" incorrectly identifying two types as the same. Works fine in MSVC.NET 3.5/4+

Here is the code I inserted to find the issue, and it does hit the debug print and when I check types in LUA I get the message above.

======== SOURCE OF ERROR IN CODE:
ObjectTranslator.cs : PushObject

internal void PushObject (LuaState luaState, object o, string metatable)
...
bool found = objectsBackMap.TryGetValue(o, out index);
if ( found && o != objects[index]) // LMP - Added as extra catch test
Debug.Print("\tAlready found it @ index {0}, types DONT MATCH", index);
...
// So now index is wrong, its going to retrieve the wrong type

@MikeSchurman

This comment has been minimized.

Show comment
Hide comment
@MikeSchurman

MikeSchurman Apr 14, 2014

Contributor

I'm seeing a potentially similar thing, where 2 valuetypes that hash to the same number share an object.

In Lua:
v1 = Vector3(0,0,0)
v2 = Vector3(0,0,0) -- because these vectors are the same value, they share the same object(error)
v1.x = 1
-- v2.x will now equal 1, as v1 and v2 share the same object on the c# side, because it uses objectsBackMap dictionary

Contributor

MikeSchurman commented Apr 14, 2014

I'm seeing a potentially similar thing, where 2 valuetypes that hash to the same number share an object.

In Lua:
v1 = Vector3(0,0,0)
v2 = Vector3(0,0,0) -- because these vectors are the same value, they share the same object(error)
v1.x = 1
-- v2.x will now equal 1, as v1 and v2 share the same object on the c# side, because it uses objectsBackMap dictionary

@viniciusjarina

This comment has been minimized.

Show comment
Hide comment
@viniciusjarina

viniciusjarina Apr 28, 2014

Member

Hey guys..

I wrote a simple test here using the code from @LucienMP and is working here 😢

Can you guys write a unit test and create a PR ? I will be happy to fix this issue.

Thank you.

Member

viniciusjarina commented Apr 28, 2014

Hey guys..

I wrote a simple test here using the code from @LucienMP and is working here 😢

Can you guys write a unit test and create a PR ? I will be happy to fix this issue.

Thank you.

@MikeSchurman

This comment has been minimized.

Show comment
Hide comment
@MikeSchurman

MikeSchurman Apr 28, 2014

Contributor

I plan to try and write a unit test, for my case at least. I just need to familiarize myself with your project structure.

Contributor

MikeSchurman commented Apr 28, 2014

I plan to try and write a unit test, for my case at least. I just need to familiarize myself with your project structure.

@MikeSchurman

This comment has been minimized.

Show comment
Hide comment
@MikeSchurman

MikeSchurman May 13, 2014

Contributor

I finally got that failing unit test in a PR for you. I'm not sure if the fix will be easy. If it is giving you a lot of trouble let me know and I'll think about a work-around. One workaround would be to ensure to only use C# structs in lua that don't hash to the same value (ie. override GetHashCode to use a more class-like hashing function).

I have to say my understanding of hashing/struct/class/equality in C# is not 100%

Contributor

MikeSchurman commented May 13, 2014

I finally got that failing unit test in a PR for you. I'm not sure if the fix will be easy. If it is giving you a lot of trouble let me know and I'll think about a work-around. One workaround would be to ensure to only use C# structs in lua that don't hash to the same value (ie. override GetHashCode to use a more class-like hashing function).

I have to say my understanding of hashing/struct/class/equality in C# is not 100%

@thomasfn

This comment has been minimized.

Show comment
Hide comment
@thomasfn

thomasfn May 16, 2014

This caused huge issues in Oxide (https://github.com/RustOxide/Oxide, http://rustoxide.com). LucienMP's fix (implemented in LucienMP@866b842) has stopped the described problem from occuring and has been very widely stress tested. I'm a bit fuzzy on the details now as it's been a while since I looked at this problem, but if the solution committed above can be made less hacky that would be great.

Just to clarify, the issue lies with the fact we're using a very old version of mono (Unity3D's current version) that has a bad implementation of something, it's been fixed in newer versions of mono).

This caused huge issues in Oxide (https://github.com/RustOxide/Oxide, http://rustoxide.com). LucienMP's fix (implemented in LucienMP@866b842) has stopped the described problem from occuring and has been very widely stress tested. I'm a bit fuzzy on the details now as it's been a while since I looked at this problem, but if the solution committed above can be made less hacky that would be great.

Just to clarify, the issue lies with the fact we're using a very old version of mono (Unity3D's current version) that has a bad implementation of something, it's been fixed in newer versions of mono).

@viniciusjarina

This comment has been minimized.

Show comment
Hide comment
Member

viniciusjarina commented Jun 21, 2014

Fixed 81d6d81

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment