diff options
Diffstat (limited to 'src/modules.cpp')
| -rw-r--r-- | src/modules.cpp | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/src/modules.cpp b/src/modules.cpp index b832694..7a82028 100644 --- a/src/modules.cpp +++ b/src/modules.cpp | |||
| @@ -1,8 +1,11 @@ | |||
| 1 | // modules.cpp — /proc/self/maps parsing and module discovery | 1 | // modules.cpp — /proc/self/maps parsing and module discovery |
| 2 | #include "hl2h.h" | 2 | #include "hl2h.h" |
| 3 | #include <elf.h> | 3 | #include <elf.h> |
| 4 | #include <mutex> | ||
| 4 | #include <vector> | 5 | #include <vector> |
| 5 | 6 | ||
| 7 | static std::mutex g_modules_mutex; | ||
| 8 | |||
| 6 | static bool basename_is(const char *path, const char *base) { | 9 | static bool basename_is(const char *path, const char *base) { |
| 7 | size_t pl = strlen(path), bl = strlen(base); | 10 | size_t pl = strlen(path), bl = strlen(base); |
| 8 | if (pl < bl || strcmp(path + pl - bl, base) != 0) | 11 | if (pl < bl || strcmp(path + pl - bl, base) != 0) |
| @@ -11,9 +14,7 @@ static bool basename_is(const char *path, const char *base) { | |||
| 11 | } | 14 | } |
| 12 | 15 | ||
| 13 | void find_modules() { | 16 | void find_modules() { |
| 14 | g_client = Module(); | 17 | Module client, engine, server; |
| 15 | g_engine = Module(); | ||
| 16 | g_server = Module(); | ||
| 17 | FILE *f = fopen("/proc/self/maps", "r"); | 18 | FILE *f = fopen("/proc/self/maps", "r"); |
| 18 | if (!f) | 19 | if (!f) |
| 19 | return; | 20 | return; |
| @@ -41,19 +42,19 @@ void find_modules() { | |||
| 41 | memcpy(clean, path, pl); | 42 | memcpy(clean, path, pl); |
| 42 | clean[pl] = 0; | 43 | clean[pl] = 0; |
| 43 | if (basename_is(clean, "client.so")) | 44 | if (basename_is(clean, "client.so")) |
| 44 | m = &g_client; | 45 | m = &client; |
| 45 | else if (basename_is(clean, "engine.so")) | 46 | else if (basename_is(clean, "engine.so")) |
| 46 | m = &g_engine; | 47 | m = &engine; |
| 47 | else if (basename_is(clean, "server.so")) | 48 | else if (basename_is(clean, "server.so")) |
| 48 | m = &g_server; | 49 | m = &server; |
| 49 | } else { | 50 | } else { |
| 50 | // anon: absorb only as .bss tail after a file-backed range | 51 | // anon: absorb only as .bss tail after a file-backed range |
| 51 | if (g_client.valid() && g_client.ranges.back().file && | 52 | if (client.valid() && client.ranges.back().file && |
| 52 | lo == g_client.ranges.back().hi && hi - lo <= 0x1000000) | 53 | lo == client.ranges.back().hi && hi - lo <= 0x1000000) |
| 53 | m = &g_client; | 54 | m = &client; |
| 54 | else if (g_engine.valid() && g_engine.ranges.back().file && | 55 | else if (engine.valid() && engine.ranges.back().file && |
| 55 | lo == g_engine.ranges.back().hi && hi - lo <= 0x1000000) | 56 | lo == engine.ranges.back().hi && hi - lo <= 0x1000000) |
| 56 | m = &g_engine; | 57 | m = &engine; |
| 57 | } | 58 | } |
| 58 | if (!m) | 59 | if (!m) |
| 59 | continue; | 60 | continue; |
| @@ -71,6 +72,16 @@ void find_modules() { | |||
| 71 | } | 72 | } |
| 72 | } | 73 | } |
| 73 | fclose(f); | 74 | fclose(f); |
| 75 | // setup_thread and resolve_server_netvars can both call this; the old code | ||
| 76 | // reset the shared Module globals and reallocated their vectors live, which | ||
| 77 | // crashed under the startup thread. Publish complete snapshots instead. | ||
| 78 | std::lock_guard<std::mutex> lock(g_modules_mutex); | ||
| 79 | if (client.valid()) | ||
| 80 | g_client = std::move(client); | ||
| 81 | if (engine.valid()) | ||
| 82 | g_engine = std::move(engine); | ||
| 83 | if (server.valid()) | ||
| 84 | g_server = std::move(server); | ||
| 74 | } | 85 | } |
| 75 | 86 | ||
| 76 | // --------------------------------------------------------------------------- | 87 | // --------------------------------------------------------------------------- |
