Commit beaeee3
committed
Fix a case of static initialization order debacle
When descent3 is built with g++ -flto=auto, there is a crash at startup:
```
Program received signal SIGSEGV, Segmentation fault.
0x00005555557b3b20 in pilot::initialize (
this=this@entry=0x555555fbd480 <Current_pilot>)
at Descent3/pilot_class.cpp:208
208 game_window_w = Video_res_list[Current_video_resolution_id].width;
Missing separate debuginfos, use: zypper install libcpp-httplib0_20-debuginfo-0.20.1-2.1.x86_64 libSDL3-0-debuginfo-3.2.16-1.1.x86_64 libzstd1-x86-64-v3-debuginfo-1.5.7-3.1.x86_64
(gdb) p Current_video_resolution_id
$1 = 0
(gdb) p Video_res_list
$2 = std::vector of length 0, capacity 0
(gdb) bt
f0 pilot::initialize (this=this@entry=0x555555fbd480 <Current_pilot>) at Descent3/pilot_class.cpp:208
f1 pilot::pilot (this=<optimized out>, this=<optimized out>) at Descent3/pilot_class.cpp:177
f2 _sub_I_65535_0.0 ()
f3 call_init (argc=1, argv=0x7fffffffdb68, env=<optimized out>) at ../csu/libc-start.c:145
f4 __libc_start_main_impl
f5 _start () at ../sysdeps/x86_64/start.S:115
```
When ASAN/UBSAN is enabled in conjunction with LTO:
```
/usr/include/c++/14/bits/stl_vector.h:1144:34: runtime error: reference binding to null pointer of type 'struct value_type'
Descent3/pilot_class.cpp:208:63: runtime error: member access within null pointer of type 'struct value_type'
AddressSanitizer:DEADLYSIGNAL
=================================================================
==58724==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000
==58724==The signal is caused by a READ memory access.
==58724==Hint: address points to the zero page.
f0 pilot::initialize() Descent3/pilot_class.cpp:208
f1 pilot::pilot() Descent3/pilot_class.cpp:177
f2 _sub_I_65535_0.0 (b/build/Descent3+0x52ece3)
f3 call_init ../csu/libc-start.c:145
f4 __libc_start_main_impl ../csu/libc-start.c:347
f5 _start ../sysdeps/x86_64/start.S:115
```
``_sub_I_65535_0.0`` is indicative of a global constructor, so we
are looking at a case of Static Initialization Order Fiasco whereby
``pilot::initialize`` runs before ``Video_res_list`` and
``Current_resolution_id`` get initialized.
Perform pilot construction explicitly in main().
Fixes: 40c7f0d1 parent da7cdf0 commit beaeee3
4 files changed
Lines changed: 9 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
696 | 696 | | |
697 | 697 | | |
698 | 698 | | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
699 | 704 | | |
700 | 705 | | |
701 | 706 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
177 | 177 | | |
178 | 178 | | |
179 | 179 | | |
180 | | - | |
181 | 180 | | |
182 | 181 | | |
183 | | - | |
| 182 | + | |
184 | 183 | | |
185 | 184 | | |
186 | 185 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
233 | 233 | | |
234 | 234 | | |
235 | 235 | | |
236 | | - | |
237 | 236 | | |
| 237 | + | |
238 | 238 | | |
239 | 239 | | |
240 | 240 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
| 48 | + | |
48 | 49 | | |
49 | 50 | | |
50 | 51 | | |
| |||
222 | 223 | | |
223 | 224 | | |
224 | 225 | | |
| 226 | + | |
225 | 227 | | |
226 | 228 | | |
227 | 229 | | |
| |||
0 commit comments