prod/native/extension/code/SigSegvHandler.cpp (42 lines of code) (raw):

/* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include "elastic_otel_version.h" #include "LoggerInterface.h" #include "ModuleGlobals.h" #include "CommonUtils.h" #include "os/StackTraceCapture.h" #include <signal.h> namespace signalHandlerData { typedef void (*OsSignalHandler)(int); static OsSignalHandler oldSigSegvHandler = nullptr; } // namespace signalHandlerData void SigSegvHandler(int signalId) { #ifdef __ELASTIC_LIBC_MUSL__ #define LIBC_IMPL "musl" #else #define LIBC_IMPL "glibc" #endif if (ELASTICAPM_G(globals) && ELASTICAPM_G(globals)->logger_) { auto output = elasticapm::osutils::getStackTrace(0); ELOGF_NF_CRITICAL(ELASTICAPM_G(globals)->logger_.get(), "Received signal %d. Agent version: " ELASTIC_OTEL_VERSION " " LIBC_IMPL "\n%s", signalId, output.c_str()); /* Call the default signal handler to have core dump generated... */ if (signalHandlerData::oldSigSegvHandler) { signal(signalId, signalHandlerData::oldSigSegvHandler); } else { signal(signalId, SIG_DFL); } raise(signalId); } } void registerSigSegvHandler(elasticapm::php::LoggerInterface * logger) { auto retval = signal(SIGSEGV, SigSegvHandler); if (retval == SIG_ERR) { ELOGF_NF_ERROR(logger, "Unable to set SIGSEGV handler. Errno: %d", errno); return; } else { signalHandlerData::oldSigSegvHandler = retval; } } void unregisterSigSegvHandler() { if (signalHandlerData::oldSigSegvHandler == SigSegvHandler) { signal(SIGSEGV, signalHandlerData::oldSigSegvHandler); signalHandlerData::oldSigSegvHandler = nullptr; } }