HaxeFoundation / HaxeFoundation/hxcpp
Crash because hxcpp's GC fail to mark a local variable
- Dominant language
- C++
- Stars
- 330
- Forks
- 227
- Avg merge
- 2d 16h
- Merged PRs (30d)
- 18
Description
I have a crash, which is very easy to reproduce。
Finally, I found the root cause of crash! That is the hxcpp's GC fail to mark a local variable,It's amazing!
########################################################################
> **How to reproduce:**
1. In order to simplify the analysis, let's modify the openfl-sample BunnyMark's "_**Main.hx**_":
```
for (i in 0...1) { // Modify from 100 to 1
addBunny ();
}
```
2. Build the openfl-sample BunnyMark :
```
openfl build wasm.
```
Then you can open the html page "index.html" which generated by lime. You'll find that everything is OK, nothing error.
3. Modify lime's _**EmscriptenPlatform.hx**_:
```
if (!project.defines.exists ("openfl_skip_haxe_build")) { //Add
ProcessHelper.runCommand ("", "haxe", args);
} //Add
```
This will help us to modify and build those cpp files generated by Haxe.
4. Modify BunnyMark's _**Bunny.cpp**_ file:
```
void Bunny_obj::__construct(){
HX_STACKFRAME(&_hx_pos_7e22fcda50e23ba6_16_new)
HXDLIN( 16) super::__construct(0,null(),null(),null(),null(),null(),null(),null());
__hxcpp_collect(); // Add this line
}
```
The above modification is to force GC (mark-sweep).
5. Build again the openfl sample project by:
```
openfl build wasm -Dopenfl_skip_haxe_build
```
Then open the BunnyMark's index.html on the browser, Crash will occur !
########################################################################
> **Crash Analysis:**
1. Let's print the gc log in the _**immix.cpp**_:
```
void MarkConservative(int *inBottom, int *inTop,hx::MarkContext *__inCtx)
{
.......
if ( t==allocObject )
{
GCLOG(" Mark object %p (%p)\n", vptr,ptr); // print gc log
HX_MARK_OBJECT( ((hx::Object *)vptr) );
lastPin = vptr;
info->pin();
}
......
}
```
2. Print the memory address of the local variable which gc-mark is missed.
This local variable is Bunny_obj.
Modify the _**Main.cpp**_ of BunnyMark:
>
> void Main_obj::addBunny(){
> HX_GC_STACKFRAME(&_hx_pos_e47a9afac0942eb9_64_addBunny)
> HXLINE( 66) Bunny bunny = Bunny_obj::__alloc( HX_CTX );
> printf("Main_obj::addBunny() bunny->Ptr: %p\n", bunny.GetPtr()); //Add this line
> HXLINE( 67) bunny->set_x(( (Float)(0) ));
> HXLINE( 68) bunny->set_y(( (Float)(0) ));
> HXLINE( 69) bunny->speedX = (::Math_obj::random() * 5);
> HXLINE( 70) bunny->speedY = ((::Math_obj::random() * 5) - ((Float)2.5));
> HXLINE( 71) this->bunnies->push(bunny);
> HXLINE( 72) this->tilemap->addTile(bunny);
> }
Important: Do not print Bunny_obj* in Bunny_obj::__alloc()
3. Comare the gc log of the normal version and the gc log of the crash version.
compile Bunny.cpp with emcc -O0: (no crash)
http://kuangyaozong.com/wasm-bunny_cpp-O0/
compile Bunny.cpp with emcc -O1: (crash)
http://kuangyaozong.com/wasm-bunny_cpp-O1/
4. The important local variable:
Bunny.cpp:
```
hx::ObjectPtr Bunny_obj::__alloc(hx::Ctx *_hx_ctx) {
Bunny_obj *__this = (Bunny_obj*)(hx::Ctx::alloc(_hx_ctx, sizeof(Bunny_obj), true, "Bunny"));
*(void **)__this = Bunny_obj::_hx_vtable;
__this->__construct();
return __this;
}
```
The local variable is __this in Bunny_obj::__alloc().
I found that the Bunny_obj* is missing in GC-Mark, then the Bunny_obj* is collected by GC , so crash happened。
This local variable is as the memory address of the Bunny_obj object in function Bunny_obj::__alloc() . In fact, the value of this local variable will return and becomes a member of an Object, it should not be collected by GC !
5. Compile Bunny.cpp Using emcc -O0, instead of emcc -O1.
Open **_emscripten-toolchain.xml_**, modify like this:
```
```
Then build BunnyMark with:
`
openfl build wasm -Dopenfl_skip_haxe_build
`
Finally, run the html file, crash disappeared,no error. So compiling with "emcc -O0" may be a solution of this crash.
########################################################################
> **Conclusion:**
The MARK process of hxcpp GC miss Mark for some local variable when compile emscripten target with emcc -O1.
Can anyone help me ? What is the reason?
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.