Skip to content

Conversation

jengelh
Copy link
Contributor

@jengelh jengelh commented Jun 6, 2025

Pull Request Type

  • Runtime changes
    • Other changes

Description

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 gets initialized.

Static variables declared in functions are initialized on first use,
which can help steer global initialization short of placing the
global state in a class instance of its own.

Fixes: 40c7f0d

Related Issues

#667

Checklist

  • I have tested my changes locally and verified that they work as intended.
  • I have reviewed the changes to ensure they do not introduce any unnecessary complexity or duplicate code.
  • I understand that by submitting this pull request, I am agreeing to license my contributions under the project's license.

@jengelh jengelh marked this pull request as draft June 8, 2025 21:24
@jengelh jengelh closed this Jun 15, 2025
@jengelh jengelh reopened this Jun 15, 2025
@jengelh jengelh marked this pull request as ready for review June 15, 2025 08:33
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: 40c7f0d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants