summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibC/crt0.cpp3
-rw-r--r--Userland/Libraries/LibC/libcinit.cpp1
-rw-r--r--Userland/Libraries/LibCore/EventLoop.cpp16
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>>;