@@ -1007,20 +1007,27 @@ void Profiler::writeHeapUsage(long value, bool live) {
10071007
10081008void *Profiler::dlopen_hook (const char *filename, int flags) {
10091009 void *result = dlopen (filename, flags);
1010+
10101011 if (result != NULL ) {
10111012 // Static function of Profiler -> can not use the instance variable _libs
10121013 // Since Libraries is a singleton, this does not matter
10131014 Libraries::instance ()->updateSymbols (false );
1015+ // Patch sigaction in wasmtime if it was just loaded
1016+ LibraryPatcher::patch_sigaction ();
10141017 // Extract build-ids for newly loaded libraries if remote symbolication is enabled
10151018 Profiler* profiler = instance ();
10161019 if (profiler != nullptr && profiler->_remote_symbolication ) {
10171020 Libraries::instance ()->updateBuildIds ();
10181021 }
10191022 }
1023+
10201024 return result;
10211025}
10221026
10231027void Profiler::switchLibraryTrap (bool enable) {
1028+ if (_dlopen_entry == NULL ) {
1029+ return ; // Not initialized yet, nothing to do
1030+ }
10241031 void *impl = enable ? (void *)dlopen_hook : (void *)dlopen;
10251032 __atomic_store_n (_dlopen_entry, impl, __ATOMIC_RELEASE);
10261033}
@@ -1037,13 +1044,25 @@ void Profiler::disableEngines() {
10371044
10381045void Profiler::segvHandler (int signo, siginfo_t *siginfo, void *ucontext) {
10391046 if (!crashHandler (signo, siginfo, ucontext)) {
1040- orig_segvHandler (signo, siginfo, ucontext);
1047+ // Check dynamic chain target first (set by intercepted sigaction calls)
1048+ SigAction chain = OS::getSegvChainTarget ();
1049+ if (chain != nullptr ) {
1050+ chain (signo, siginfo, ucontext);
1051+ } else if (orig_segvHandler != nullptr ) {
1052+ orig_segvHandler (signo, siginfo, ucontext);
1053+ }
10411054 }
10421055}
10431056
10441057void Profiler::busHandler (int signo, siginfo_t *siginfo, void *ucontext) {
10451058 if (!crashHandler (signo, siginfo, ucontext)) {
1046- orig_busHandler (signo, siginfo, ucontext);
1059+ // Check dynamic chain target first (set by intercepted sigaction calls)
1060+ SigAction chain = OS::getBusChainTarget ();
1061+ if (chain != nullptr ) {
1062+ chain (signo, siginfo, ucontext);
1063+ } else if (orig_busHandler != nullptr ) {
1064+ orig_busHandler (signo, siginfo, ucontext);
1065+ }
10471066 }
10481067}
10491068
@@ -1102,17 +1121,22 @@ bool Profiler::crashHandler(int signo, siginfo_t *siginfo, void *ucontext) {
11021121}
11031122
11041123void Profiler::setupSignalHandlers () {
1105- // do not re-run the signal setup (run only when VM has not been loaded yet)
1124+ // Do not re-run the signal setup (run only when VM has not been loaded yet)
11061125 if (__sync_bool_compare_and_swap (&_signals_initialized, false , true )) {
11071126 if (VM::isHotspot () || VM::isOpenJ9 ()) {
1108- // HotSpot and J9 tolerate interposed SIGSEGV/SIGBUS handler; other JVMs
1109- // probably not
1127+ // HotSpot and J9 tolerate interposed SIGSEGV/SIGBUS handler; other JVMs probably not
11101128 orig_segvHandler = OS::replaceSigsegvHandler (segvHandler);
11111129 orig_busHandler = OS::replaceSigbusHandler (busHandler);
1130+ // Protect our handlers from being overwritten by other libraries (e.g., wasmtime).
1131+ // Their handlers will be stored as chain targets and called from our handlers.
1132+ OS::protectSignalHandlers (segvHandler, busHandler);
1133+ // Patch sigaction GOT in libraries with broken signal handlers (already loaded)
1134+ LibraryPatcher::patch_sigaction ();
11121135 }
11131136 }
11141137}
11151138
1139+
11161140/* *
11171141 * Update thread name for the given thread
11181142 */
@@ -1417,7 +1441,8 @@ Error Profiler::start(Arguments &args, bool reset) {
14171441
14181442 enableEngines ();
14191443
1420- switchLibraryTrap (_cstack == CSTACK_DWARF || _remote_symbolication);
1444+ // Always enable library trap to catch wasmtime loading and patch its broken sigaction
1445+ switchLibraryTrap (true );
14211446
14221447 JfrMetadata::initialize (args._context_attributes );
14231448 _num_context_attributes = args._context_attributes .size ();
0 commit comments