Link Time Optimization (-flto) triggers static initialization bug in Open3D
- Dominant language
- C++
- Stars
- 14k
- Forks
- 2.6k
- Avg merge
- 5d 18h
- Merged PRs (30d)
- 6
Description
### Checklist
- [X] I have searched for [similar issues](https://github.com/isl-org/Open3D/issues).
- [X] For Python issues, I have tested with the [latest development wheel](http://www.open3d.org/docs/latest/getting_started.html#development-version-pip).
- [X] I have checked the [release documentation](http://www.open3d.org/docs/release/) and the [latest documentation](http://www.open3d.org/docs/latest/) (for `master` branch).
### Steps to reproduce the issue
#### I first cloned Open3D by:
```
git clone https://github.com/isl-org/Open3D.git
cd Open3D
```
#### Then, I build Open3D (on Debian Sid) with:
```
mkdir build
cd build
cmake -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON ..
make -j$(nproc)
```
### Error message
```shell
Build succeeds without error, but the Open3D GUI will fail to load materials at runtime.
```
### Open3D, Python and System information
```markdown
- Operating system: Debian unstable ("sid")
- Python version: Python 3.9
- Open3D version: 0.14.1
- System architecture: x86
- Is this a remote workstation?: no
- How did you install Open3D?: build from source
- Compiler version (if built from source): gcc 11
```
### Additional information
I tracked the bug to a corrupted `defaults_mapping::shader_mappings` map. The map has static storage and depends on members of `FilamentResourceManager`, again with stattic storage. This creates a initialization order dependency across translation units, also known as the [static initialization order fiasco](https://en.cppreference.com/w/cpp/language/siof), and will break Open3D if the static variables from `FilamentResourceManager.cpp` are not initialized before those in `FilamentScene.cpp`.
As initialization normally happens in the order the object files are linked, and (thanks to the alphabetic sorting) `FilamentResourceManager.cpp` comes before `FilamentScene.cpp`, this bug has not surfaced before. However, LTO seems to mess with the initialization order, thereby exposing the bug.
The static initialization order problem is usually avoided using the Construct On First Use idiom. For now, the bug can be mitigated by disabling/not enabling Link Time Optimization for the Open3D main library. The Python module is not affected and *should* be built with LTO for performance reasons, actually.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.