/* * SignalSafeUnwind.cpp * * This source file is part of the FoundationDB open source project * * Copyright 2013-2018 Apple Inc. and the FoundationDB project authors * * Licensed 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 "flow/SignalSafeUnwind.h" int64_t dl_iterate_phdr_calls = 0; #ifdef __linux__ #include #include static int (*chain_dl_iterate_phdr)( int (*callback) (struct dl_phdr_info *info, size_t size, void *data), void *data) = nullptr; static void initChain() { static std::once_flag flag; // Ensure that chain_dl_iterate_phdr points to the "real" function that we are overriding std::call_once(flag, [](){ *(void**)&chain_dl_iterate_phdr = dlsym(RTLD_NEXT, "dl_iterate_phdr"); }); if (!chain_dl_iterate_phdr) { criticalError(FDB_EXIT_ERROR, "SignalSafeUnwindError", "Unable to find dl_iterate_phdr symbol"); } } // This overrides the function in libc! extern "C" int dl_iterate_phdr( int (*callback) (struct dl_phdr_info *info, size_t size, void *data), void *data) { interlockedIncrement64(&dl_iterate_phdr_calls); initChain(); setProfilingEnabled(0); int result = chain_dl_iterate_phdr(callback, data); setProfilingEnabled(1); return result; } #endif