AddressSanitizer find bugs in axmol engine #1362
Replies: 22 comments
-
FYI. @rh101 @halx99 @DelinWorks @kiranb47 Visual studio support only AddressSanitizer https://learn.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-170 Does any one of can build and check axmol on linux against all available sanitizers [address, memory, thread, undefined] |
Beta Was this translation helpful? Give feedback.
-
@crazyhappygame The ActionsProgressTests issue seems like a false positive from ASAN. It can be boiled down to this code which throws this error:
If we change it to this, an error is still flagged by ASAN:
For some reason the const reference is flagged as being out of scope, which shouldn't be the case. Unless there is something I'm not seeing, none of the code above should result in no errors. This version of it does not throw an error:
|
Beta Was this translation helpful? Give feedback.
-
@crazyhappygame I couldn't reproduce this issue. Did you test it with the 32bit of 64bit build? Once I did the change to fix issue 1 in |
Beta Was this translation helpful? Give feedback.
-
@rh101 ASAN does not produce false positive.
Clarification:
V3F_C4B_T2F_Quad temporary value is destroyed immediately and we keep reference to Possible fixes:
and later use quad
Please check "Reference Lifetime Extension" e.g.: Generally:
This is WRONG. Reference Lifetime Extension does not work for any sub expression.
|
Beta Was this translation helpful? Give feedback.
-
Universal Reference is better fix it:
auto&& xxx =
获取Outlook for Android<https://aka.ms/AAb9ysg>
…________________________________
From: CHP ***@***.***>
Sent: Sunday, July 9, 2023 3:31:36 PM
To: axmolengine/axmol ***@***.***>
Cc: Deal(一线灵) ***@***.***>; Mention ***@***.***>
Subject: Re: [axmolengine/axmol] AddressSanitizer find bugs in axmol engine (Issue #1257)
@rh101<https://github.com/rh101> ASAN does not produce false positive.
Below line is a real bug (not a false positive)
const Color4B& sc = _sprite->getQuad().tl.colors;
Clarification:
sprite returns by value V3F_C4B_T2F_Quad
V3F_C4B_T2F_Quad getQuad() const { return _quad; }
V3F_C4B_T2F_Quad temporary value is destroyed immediately and we keep reference to const Color4B& sc that points to non existing part of V3F_C4B_T2F_Quad
Possible fixes:
1. Store copy of Color4B
const Color4B sc = _sprite->getQuad().tl.colors;
1. Extend lifetime of rvalue
const auto& quad = _sprite->getQuad();
and later use quad
_vertexData[i].colors = quad.tl.colors;
Please check "Reference Lifetime Extension" e.g.:
https://abseil.io/tips/107
Generally:
This is OK. Reference Lifetime Extension.
const auto& temp = _sprite->getQuad();
This is WRONG. Reference Lifetime Extension does not work for any sub expression.
const auto& temp1 = _sprite->getQuad().tl;
const auto& temp2 = _sprite->getQuad().tl.color;
―
Reply to this email directly, view it on GitHub<#1257 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ABVHOJ7WYWJEYFUNPUYXKCDXPJM5RANCNFSM6AAAAAA2DBMBOQ>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
This looks like some threading problem. Most probably there is some race. We should run tread sanitizer to increase chance to reproduce this problem. I reproduce this problem on win 64 bit build |
Beta Was this translation helpful? Give feedback.
-
You're absolutely right; I completely missed that the return value of |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
auto&& quad = _sprite->getQuad();
temp._vertexData[i].colors = quad.tl.colors; not work? |
Beta Was this translation helpful? Give feedback.
-
I checked below:
That should work
There should be no difference how Reference Lifetime Extension works for below cases
|
Beta Was this translation helpful? Give feedback.
-
Sorry, yes that does work, which is equivalent to:
Which would be preferred? 1 - Change or 2 - Update it's usage in
|
Beta Was this translation helpful? Give feedback.
-
Both works for me. Not sure how big can _vertexData vector and what compiler code is generated here but there is a chance that below could be the faster. There is no indirection in body loop quad.tl.colors
And most probably changing to below will be some small performance and readability improvement
|
Beta Was this translation helpful? Give feedback.
-
That would be an extra copy for the If getQuads returned a then the old code in
Also, the other places that use
All they do is either calculations on the values or copy the contents somewhere else, so if we change
|
Beta Was this translation helpful? Give feedback.
-
I think this single copy does not matter here:
Most probably below would be the most performant and readable code
and then
|
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
I can take care of this in a few minutes. It'll affect other functions too, such as
They will become:
Which is probably a good thing too, since inside those methods the I'll get a PR done soon unless someone else wants to handle this. |
Beta Was this translation helpful? Give feedback.
-
@rh101 thank you for merging fix. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
If you go into the TextureCache ( I could reproduce the issue constantly on MacOS, but on Windows 10 I couldn't get it to happen at all, possibly because the images load very quickly, so the callback occurs before the next test is loaded when the right arrow is clicked. EDIT: These errors are related to the test implementation, and not TextureCache. When a test scene is deleted, it doesn't unbind the callbacks registered with the texture cache for the async image loading. The way I managed to get it working is to simply use this:
in the destructor for each test. The only issue with the above is that the test code also needs to be refactored to move the test setup from the constructor to the 1 - NewTestScene constructor called, If we move the code to 1 - NewTestScene constructor called (no code in here) Come to think of it, the entire test implementation is a little strange, since everything is done in the constructors, which is not ideal. The constructors shouldn't be used to set up the tests, along with the fact that virtual methods are being called from constructors, which end up being resolved statically, causing issues with overriden methods. Anyhow, with the changes above, the TextureCache test no longer crashes. |
Beta Was this translation helpful? Give feedback.
-
@crazyhappygame If you get a chance to, please try out the changes in #1267 to verify that it fixes the crash you were getting in TextureCacheUnbindTest. |
Beta Was this translation helpful? Give feedback.
-
@crazyhappygame If you have verified that the issues raised have been addressed, then please close this issue. |
Beta Was this translation helpful? Give feedback.
-
Thank you. I checked v1.0.0 - issue is fixed. I |
Beta Was this translation helpful? Give feedback.
-
Steps to Reproduce:
Windows, Visual studio 2022
https://learn.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-170
by adding on the top of to CMakeLists.txt
Sample errors:
Address Sanitizer Error: Use of out-of-scope stack memory
Address Sanitizer Error: Use of deallocated memory
Comments:
This kind of problems means that we are in undefined behavior zone and can not reason about program correctness.
This kind of issue could result in the problems seen in #1211
Beta Was this translation helpful? Give feedback.
All reactions