diff options
-rw-r--r-- | Userland/Libraries/LibC/crt0.cpp | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibC/libcinit.cpp | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibCore/EventLoop.cpp | 16 |
3 files changed, 20 insertions, 0 deletions
diff --git a/Userland/Libraries/LibC/crt0.cpp b/Userland/Libraries/LibC/crt0.cpp index 798f7c751b..f8bb061456 100644 --- a/Userland/Libraries/LibC/crt0.cpp +++ b/Userland/Libraries/LibC/crt0.cpp @@ -15,6 +15,7 @@ extern "C" { extern size_t __stack_chk_guard; +extern bool s_global_initializers_ran; int main(int, char**, char**); @@ -41,6 +42,8 @@ int _entry(int argc, char** argv, char** env) __environ_is_malloced = false; __begin_atexit_locking(); + s_global_initializers_ran = true; + _init(); int status = main(argc, argv, environ); diff --git a/Userland/Libraries/LibC/libcinit.cpp b/Userland/Libraries/LibC/libcinit.cpp index 09d81cbac4..38cab1bdaa 100644 --- a/Userland/Libraries/LibC/libcinit.cpp +++ b/Userland/Libraries/LibC/libcinit.cpp @@ -19,6 +19,7 @@ __thread int errno; char** environ; bool __environ_is_malloced; bool __stdio_is_initialized; +bool s_global_initializers_ran; void* __auxiliary_vector; static void __auxiliary_vector_init(); diff --git a/Userland/Libraries/LibCore/EventLoop.cpp b/Userland/Libraries/LibCore/EventLoop.cpp index 7fe465ceeb..b7f6c109a7 100644 --- a/Userland/Libraries/LibCore/EventLoop.cpp +++ b/Userland/Libraries/LibCore/EventLoop.cpp @@ -35,6 +35,10 @@ #include <time.h> #include <unistd.h> +#ifdef __serenity__ +extern bool s_global_initializers_ran; +#endif + namespace Core { class InspectorServerConnection; @@ -284,6 +288,18 @@ private: EventLoop::EventLoop([[maybe_unused]] MakeInspectable make_inspectable) : m_private(make<Private>()) { +#ifdef __serenity__ + if (!s_global_initializers_ran) { + // NOTE: Trying to have an event loop as a global variable will lead to initialization-order fiascos, + // as the event loop constructor accesses and/or sets other global variables. + // Therefore, we crash the program before ASAN catches us. + // If you came here because of the assertion failure, please redesign your program to not have global event loops. + // The common practice is to initialize the main event loop in the main function, and if necessary, + // pass event loop references around or access them with EventLoop::with_main_locked() and EventLoop::current(). + VERIFY_NOT_REACHED(); + } +#endif + if (!s_event_loop_stack) { s_event_loop_stack = new Vector<EventLoop&>; s_timers = new HashMap<int, NonnullOwnPtr<EventLoopTimer>>; |