Bug:Boost: Use shlibs instead of header-only for call_stack::top_
This symbol is defined as a static member object inside of a boost detail header. When boost headers are used in a project that uses Boost in both the main binary as well as dlopen()'d shlibs, the top_ symbol gets duplicated and the metadata gets partitioned. We use the Boost shlib to unify both the main binary and the shlibs to use the same memory address for top_. This involves marking the templated object call_stack::top_ as "extern" and then declaring to Boost that we intend to use the shlibs.
This commit is contained in:
+22
-5
@@ -4,6 +4,7 @@ project(salmanoff VERSION 0.01.000 LANGUAGES CXX)
|
|||||||
include(CMakeDependentOption)
|
include(CMakeDependentOption)
|
||||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DAPSS.cmake)
|
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DAPSS.cmake)
|
||||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DebugOpts.cmake)
|
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DebugOpts.cmake)
|
||||||
|
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/VerifyBoostDynamic.cmake)
|
||||||
|
|
||||||
# Set C++ standard
|
# Set C++ standard
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
@@ -87,10 +88,19 @@ include_directories(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Find core dependencies
|
# Find core dependencies
|
||||||
# Boost 1.72.0 is required to ensure that a certain bug where boost::asio
|
# We cannot use header-only Boost.Asio because we need both our dlopen()'d
|
||||||
# objects depend on specific copies of symbols, and boost will cause a segfault
|
# libraries and the main binary to refer to the same instances of boost::asio's
|
||||||
# if boost::asio objects are used inside of a dlopen()'d library, is fixed.
|
# metadata. If we use header-only Boost.Asio, each dlopen()'d library will have
|
||||||
find_package(Boost 1.73.0 REQUIRED COMPONENTS system)
|
# its own copy of boost::asio's metadata, which will cause a segfault if
|
||||||
|
# boost::asio objects are used inside of a dlopen()'d library.
|
||||||
|
#
|
||||||
|
# Honestly, I never liked this whole "header-only" idea so I'm happy to be rid
|
||||||
|
# of it.
|
||||||
|
#
|
||||||
|
# Tell CMake we're linking against the shared library (not header-only)
|
||||||
|
set(Boost_USE_STATIC_LIBS OFF)
|
||||||
|
set(Boost_USE_HEADER_ONLY OFF)
|
||||||
|
find_package(Boost REQUIRED COMPONENTS system log)
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
find_package(FLEX REQUIRED)
|
find_package(FLEX REQUIRED)
|
||||||
find_package(BISON REQUIRED)
|
find_package(BISON REQUIRED)
|
||||||
@@ -116,11 +126,18 @@ add_subdirectory(devices)
|
|||||||
# Main executable
|
# Main executable
|
||||||
add_executable(salmanoff main.cpp)
|
add_executable(salmanoff main.cpp)
|
||||||
target_link_libraries(salmanoff
|
target_link_libraries(salmanoff
|
||||||
|
Boost::system Boost::log
|
||||||
smocore
|
smocore
|
||||||
${Boost_LIBRARIES}
|
|
||||||
${DL_LIBRARY}
|
${DL_LIBRARY}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Verify Boost dynamic dependencies after build
|
||||||
|
add_custom_command(TARGET salmanoff POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -DVERIFY_FILE="$<TARGET_FILE:salmanoff>"
|
||||||
|
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/VerifyBoostDynamic.cmake
|
||||||
|
COMMENT "Verifying Boost dynamic dependencies for salmanoff"
|
||||||
|
)
|
||||||
|
|
||||||
# Add all registered DAPSS targets as dependencies
|
# Add all registered DAPSS targets as dependencies
|
||||||
add_all_daps_dependencies()
|
add_all_daps_dependencies()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# SMO_VERIFY_BOOST_DYNAMIC_DEPENDENCY
|
||||||
|
# Verifies that a target file (executable or shared library) has Boost libraries
|
||||||
|
# in its dynamic dependency list via ldd.
|
||||||
|
#
|
||||||
|
# Usage as function:
|
||||||
|
# SMO_VERIFY_BOOST_DYNAMIC_DEPENDENCY(<target_file>)
|
||||||
|
#
|
||||||
|
# Usage as script (with -P):
|
||||||
|
# cmake -DVERIFY_FILE=<target_file> -P VerifyBoostDynamic.cmake
|
||||||
|
#
|
||||||
|
# This function/script:
|
||||||
|
# 1. Runs ldd on the target file
|
||||||
|
# 2. Checks for boost libraries in the dependency list
|
||||||
|
# 3. Reports success or failure with appropriate messages
|
||||||
|
#
|
||||||
|
function(SMO_VERIFY_BOOST_DYNAMIC_DEPENDENCY target_file)
|
||||||
|
_verify_boost_dynamic_dependency("${target_file}")
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Internal implementation that can be called from script mode or function mode
|
||||||
|
function(_verify_boost_dynamic_dependency target_file)
|
||||||
|
if(NOT EXISTS "${target_file}")
|
||||||
|
message(WARNING "SMO_VERIFY_BOOST_DYNAMIC_DEPENDENCY: Target file '${target_file}' does not exist")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Run ldd on the target file
|
||||||
|
execute_process(
|
||||||
|
COMMAND ldd "${target_file}"
|
||||||
|
OUTPUT_VARIABLE ldd_output
|
||||||
|
ERROR_VARIABLE ldd_error
|
||||||
|
RESULT_VARIABLE ldd_result
|
||||||
|
)
|
||||||
|
|
||||||
|
if(ldd_result)
|
||||||
|
message(WARNING "SMO_VERIFY_BOOST_DYNAMIC_DEPENDENCY: Failed to run ldd on '${target_file}': ${ldd_error}")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Check if output contains boost libraries
|
||||||
|
string(TOLOWER "${ldd_output}" ldd_output_lower)
|
||||||
|
string(FIND "${ldd_output_lower}" "libboost" boost_found)
|
||||||
|
|
||||||
|
if(boost_found EQUAL -1)
|
||||||
|
message(STATUS "SMO_VERIFY_BOOST_DYNAMIC_DEPENDENCY: WARNING - No Boost libraries found in dependencies of '${target_file}'")
|
||||||
|
message(STATUS "ldd output:")
|
||||||
|
message(STATUS "${ldd_output}")
|
||||||
|
else()
|
||||||
|
# Extract boost library lines
|
||||||
|
string(REGEX MATCHALL "libboost[^\n]*" boost_libs "${ldd_output}")
|
||||||
|
message(STATUS "SMO_VERIFY_BOOST_DYNAMIC_DEPENDENCY: SUCCESS - Boost libraries found in '${target_file}':")
|
||||||
|
foreach(boost_lib ${boost_libs})
|
||||||
|
string(STRIP "${boost_lib}" boost_lib_stripped)
|
||||||
|
message(STATUS " ${boost_lib_stripped}")
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Script mode: if VERIFY_FILE is defined, run the verification
|
||||||
|
if(VERIFY_FILE)
|
||||||
|
_verify_boost_dynamic_dependency("${VERIFY_FILE}")
|
||||||
|
endif()
|
||||||
|
|
||||||
@@ -11,3 +11,8 @@ target_include_directories(attachmentSupport PUBLIC
|
|||||||
${CMAKE_SOURCE_DIR}/include
|
${CMAKE_SOURCE_DIR}/include
|
||||||
${CMAKE_BINARY_DIR}/include
|
${CMAKE_BINARY_DIR}/include
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_link_libraries(attachmentSupport PUBLIC
|
||||||
|
Boost::system
|
||||||
|
Boost::log
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <componentThread.h>
|
#include <componentThread.h>
|
||||||
@@ -43,9 +44,6 @@ void StimulusBuffer::stop()
|
|||||||
|
|
||||||
void StimulusBuffer::scheduleNextTimeout(int delayMs)
|
void StimulusBuffer::scheduleNextTimeout(int delayMs)
|
||||||
{
|
{
|
||||||
std::cout << __func__ << ": being executed on thread "
|
|
||||||
<< smoHooksPtr->ComponentThread_getSelf()->name << std::endl;
|
|
||||||
|
|
||||||
if (!shouldContinue.load())
|
if (!shouldContinue.load())
|
||||||
{ return; }
|
{ return; }
|
||||||
|
|
||||||
@@ -60,8 +58,6 @@ std::cout << __func__ << ": being executed on thread "
|
|||||||
|
|
||||||
void StimulusBuffer::onTimeout(const boost::system::error_code& error)
|
void StimulusBuffer::onTimeout(const boost::system::error_code& error)
|
||||||
{
|
{
|
||||||
std::cout << __func__ << ": being executed on thread "
|
|
||||||
<< smoHooksPtr->ComponentThread_getSelf()->name << std::endl;
|
|
||||||
// Timer was cancelled, which is expected when stopping
|
// Timer was cancelled, which is expected when stopping
|
||||||
if (error == boost::asio::error::operation_aborted) {
|
if (error == boost::asio::error::operation_aborted) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -13,7 +13,14 @@ if(ENABLE_LIB_livoxProto1)
|
|||||||
# Set config define for header generation
|
# Set config define for header generation
|
||||||
add_compile_definitions(CONFIG_LIB_LIVOXPROTO1_ENABLED)
|
add_compile_definitions(CONFIG_LIB_LIVOXPROTO1_ENABLED)
|
||||||
target_include_directories(livoxProto1 PUBLIC ${Boost_INCLUDE_DIRS})
|
target_include_directories(livoxProto1 PUBLIC ${Boost_INCLUDE_DIRS})
|
||||||
target_link_libraries(livoxProto1 ${Boost_LIBRARIES})
|
target_link_libraries(livoxProto1 PUBLIC Boost::system Boost::log)
|
||||||
|
|
||||||
|
# Verify Boost dynamic dependencies after build
|
||||||
|
add_custom_command(TARGET livoxProto1 POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -DVERIFY_FILE="$<TARGET_FILE:livoxProto1>"
|
||||||
|
-P ${CMAKE_SOURCE_DIR}/cmake/VerifyBoostDynamic.cmake
|
||||||
|
COMMENT "Verifying Boost dynamic dependencies for livoxProto1"
|
||||||
|
)
|
||||||
|
|
||||||
# Install rules
|
# Install rules
|
||||||
install(TARGETS livoxProto1 DESTINATION lib)
|
install(TARGETS livoxProto1 DESTINATION lib)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef BROADCAST_LISTENER_H
|
#ifndef BROADCAST_LISTENER_H
|
||||||
#define BROADCAST_LISTENER_H
|
#define BROADCAST_LISTENER_H
|
||||||
|
|
||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef LIVOX_PROTO1_DEVICE_H
|
#ifndef LIVOX_PROTO1_DEVICE_H
|
||||||
#define LIVOX_PROTO1_DEVICE_H
|
#define LIVOX_PROTO1_DEVICE_H
|
||||||
|
|
||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <callback.h>
|
#include <callback.h>
|
||||||
#include <boost/asio/posix/stream_descriptor.hpp>
|
#include <boost/asio/posix/stream_descriptor.hpp>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef LIVOXPROTO1_H
|
#ifndef LIVOXPROTO1_H
|
||||||
#define LIVOXPROTO1_H
|
#define LIVOXPROTO1_H
|
||||||
|
|
||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef LIVOXPROTO1_PROTOCOL_H
|
#ifndef LIVOXPROTO1_PROTOCOL_H
|
||||||
#define LIVOXPROTO1_PROTOCOL_H
|
#define LIVOXPROTO1_PROTOCOL_H
|
||||||
|
|
||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef UDP_COMMAND_DEMUXER_H
|
#ifndef UDP_COMMAND_DEMUXER_H
|
||||||
#define UDP_COMMAND_DEMUXER_H
|
#define UDP_COMMAND_DEMUXER_H
|
||||||
|
|
||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <boost/asio/posix/stream_descriptor.hpp>
|
#include <boost/asio/posix/stream_descriptor.hpp>
|
||||||
|
|||||||
@@ -46,8 +46,13 @@ endif()
|
|||||||
target_include_directories(smocore PUBLIC
|
target_include_directories(smocore PUBLIC
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
${Boost_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Link against pthread for CPU affinity functions
|
# Link against pthread for CPU affinity functions
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
target_link_libraries(smocore PRIVATE Threads::Threads)
|
target_link_libraries(smocore PRIVATE
|
||||||
|
Threads::Threads
|
||||||
|
Boost::system
|
||||||
|
Boost::log
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef BOOST_ASIO_LINKAGE_FIX_H
|
||||||
|
#define BOOST_ASIO_LINKAGE_FIX_H
|
||||||
|
|
||||||
|
#include <boost/asio/detail/call_stack.hpp>
|
||||||
|
#include <boost/asio/detail/thread_context.hpp>
|
||||||
|
#include <boost/asio/detail/tss_ptr.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
/** EXPLANATION:
|
||||||
|
* Extern declaration of the template instantiation
|
||||||
|
* This ensures that the .o translation units don't have their
|
||||||
|
* own copies of `call_stack<>::top_` defined in them.
|
||||||
|
*/
|
||||||
|
extern template
|
||||||
|
tss_ptr<call_stack<thread_context, thread_info_base>::context>
|
||||||
|
call_stack<thread_context, thread_info_base>::top_;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_LINKAGE_FIX_H
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef COMPONENT_THREAD_H
|
#ifndef COMPONENT_THREAD_H
|
||||||
#define COMPONENT_THREAD_H
|
#define COMPONENT_THREAD_H
|
||||||
|
|
||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef DEVICEREATTACHER_H
|
#ifndef DEVICEREATTACHER_H
|
||||||
#define DEVICEREATTACHER_H
|
#define DEVICEREATTACHER_H
|
||||||
|
|
||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <boost/asio/deadline_timer.hpp>
|
#include <boost/asio/deadline_timer.hpp>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <exception>
|
#include <exception>
|
||||||
#include <opts.h>
|
#include <opts.h>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <boost/asio/signal_set.hpp>
|
#include <boost/asio/signal_set.hpp>
|
||||||
#include <asynchronousBridge.h>
|
#include <asynchronousBridge.h>
|
||||||
#include <mindManager/mindManager.h>
|
#include <mindManager/mindManager.h>
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ if(ENABLE_STIMBUFFAPI_livoxGen1)
|
|||||||
${CMAKE_SOURCE_DIR}/commonLibs
|
${CMAKE_SOURCE_DIR}/commonLibs
|
||||||
${URING_INCLUDE_DIRS}
|
${URING_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
target_link_libraries(livoxGen1
|
target_link_libraries(livoxGen1 PUBLIC
|
||||||
${Boost_LIBRARIES}
|
Boost::system
|
||||||
|
Boost::log
|
||||||
${URING_LIBRARIES}
|
${URING_LIBRARIES}
|
||||||
attachmentSupport
|
attachmentSupport
|
||||||
)
|
)
|
||||||
@@ -30,6 +31,13 @@ if(ENABLE_STIMBUFFAPI_livoxGen1)
|
|||||||
${URING_LIBRARY_DIRS}
|
${URING_LIBRARY_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Verify Boost dynamic dependencies after build
|
||||||
|
add_custom_command(TARGET livoxGen1 POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -DVERIFY_FILE="$<TARGET_FILE:livoxGen1>"
|
||||||
|
-P ${CMAKE_SOURCE_DIR}/cmake/VerifyBoostDynamic.cmake
|
||||||
|
COMMENT "Verifying Boost dynamic dependencies for livoxGen1"
|
||||||
|
)
|
||||||
|
|
||||||
# Install rules
|
# Install rules
|
||||||
install(TARGETS livoxGen1 DESTINATION lib)
|
install(TARGETS livoxGen1 DESTINATION lib)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef _LIVOX_GEN1_IOURING_ASSEMBLY_ENGINE_H
|
#ifndef _LIVOX_GEN1_IOURING_ASSEMBLY_ENGINE_H
|
||||||
#define _LIVOX_GEN1_IOURING_ASSEMBLY_ENGINE_H
|
#define _LIVOX_GEN1_IOURING_ASSEMBLY_ENGINE_H
|
||||||
|
|
||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <boostAsioLinkageFix.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -16,13 +17,14 @@
|
|||||||
#include <asynchronousContinuation.h>
|
#include <asynchronousContinuation.h>
|
||||||
#include <boost/asio/deadline_timer.hpp>
|
#include <boost/asio/deadline_timer.hpp>
|
||||||
#include "pcloudStimulusBuffer.h"
|
#include "pcloudStimulusBuffer.h"
|
||||||
|
#include "livoxGen1.h"
|
||||||
|
|
||||||
|
|
||||||
namespace smo {
|
namespace smo {
|
||||||
namespace stim_buff {
|
namespace stim_buff {
|
||||||
|
|
||||||
// Salmanoff hooks, obtained from SMO_GET_STIM_BUFF_API_DESC_FN_NAME().
|
// Salmanoff hooks, obtained from SMO_GET_STIM_BUFF_API_DESC_FN_NAME().
|
||||||
static const SmoCallbacks* smoHooksPtr = nullptr;
|
const SmoCallbacks* smoHooksPtr = nullptr;
|
||||||
static SmoThreadingModelDesc smoThreadingModelDesc;
|
static SmoThreadingModelDesc smoThreadingModelDesc;
|
||||||
|
|
||||||
// Local collection of stimulus buffers
|
// Local collection of stimulus buffers
|
||||||
|
|||||||
Reference in New Issue
Block a user