首页 > 其他分享 >dlopen 加载使用了std::thread 的so 导致crash的问题分析

dlopen 加载使用了std::thread 的so 导致crash的问题分析

时间:2024-08-23 16:25:58浏览次数:10  
标签:std gcc crash thread 符号 pthread foo dlopen

  1. c++11的 的create implement是在thread.cc 中实现的,这意味着创建代码在libstdc++.so 中,创建代码需要使用与平台有关的api
  2. gcc(g++ is a part of gcc)的预期:
    • 没有调用的thread的代码,不会产生对pthread的依赖,更重要的,不同配置的gcc的线程模型是不同的,依赖库也不同(即不一定是pthread),如果不去除依赖,这会导致链接的深刻耦合
    • 调用了thread的代码,必须要链接到pthread
  3. gcc 内部,通过弱符号机制来达到这个目的,以foo函数举例:
    • 通过一个包装的符号,如gcc_foo, 弱引用到foo
    • 声明foo 是一个弱符号,可以在链接时被强符号替代,弱符号默认是未定义的(可能也不是空指针)
    • g++的thread.cc 通过gcc_foo 包装后的函数,来创建线程,而不是直接使用平台api

通过弱符号,即便是业务代码没有链接pthread,thread.cc 相关的代码也不会产生链接报错。那么,g++ 又是如何完成2.2. 的呢? 答案是g++ 通过一个无用参数强制产生对pthread 的依赖,这部分实现是在 文件中,会被展开到业务代码里,让业务代码产生对pthread的依赖,注意不是libstdc++。

那么为什么dlopen 又会导致使用了std::thread的库crash呢? 这是因为符号加载顺序的问题,libdl 不是ld,他是glibc的一部分,他通过名字空间等机制支持符号的隔离等。名字空间一般有:local/global 以及其他(可能和加载顺序有关),dlopen 加载一个库时,其查找符号的顺序是:

  1. LOCAL
  2. GLOBAl
  3. 其他

前面说过,因为gcc内部搞了一个弱符号,他是存在应用程序的符号表中的,应用程序的符号表对于dlopen的so而言是全局的。可以明确的是LOCAL肯定没有pthread相关符号,GLOBAL中有gcc定义的弱符号,dl认为找到了,但实际是错误的,从而导致了不能debug的crash

标签:std,gcc,crash,thread,符号,pthread,foo,dlopen
From: https://www.cnblogs.com/fyyy94/p/18376351

相关文章

  • 什么?!90%的ThreadLocal都在滥用或错用!
    最近在看一个系统代码时,发现系统里面在使用到了ThreadLocal,乍一看,好像很高级的样子。我再仔细一看,这个场景并不会存在线程安全问题,完全只是在一个方法中传参使用的啊!(震惊)难道是我水平太低,看不懂这个高级用法?经过和架构师请教和确认,这完全就是一个ThreadLocal滥用的典型案......
  • 什么?!90%的ThreadLocal都在滥用或错用!
    最近在看一个系统代码时,发现系统里面在使用到了ThreadLocal,乍一看,好像很高级的样子。我再仔细一看,这个场景并不会存在线程安全问题,完全只是在一个方法中传参使用的啊!(震惊)难道是我水平太低,看不懂这个高级用法?经过和架构师请教和确认,这完全就是一个ThreadLocal滥用的典型案例啊!......
  • C# start thread include Thread,Task,Async/Await,BackgroundWorker,ThreadPool,Time
    usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Linq;usingSystem.Text;usingSystem.Threading;usingSystem.Threading.Tasks;usingSystem.Windows;usingSystem.Windows.Controls;usingSystem.Windows.Data;using......
  • 掌握C++中的std::list:高效处理插入与删除的最佳选择
    在C++标准模板库(STL)中,std::list是一个非常重要的容器,属于序列式容器。与std::vector和std::deque不同,std::list是一个双向链表(doublylinkedlist),其设计更适合于频繁的插入和删除操作,而不是随机访问。本文将深入探讨std::list的实现原理、使用场景以及与其他容器的对比......
  • jmeter压测组件bzm-Arrivals Thread Group使用Jenkins运行配置
    jmeter脚本设置Jenkins设置运行代码设置cd/home/jmeterWorkplace/performceTps/script/home/app/apache-jmeter-5.4.3/bin/jmeter-n-tjenkins_test.jmx-Jtarget_rate=${target_rate}-Jramp_up_time=${ramp_up_time}-Jramp_up_step_count=${ramp_up_step_count}-Jh......
  • 单张图像像素平均值和标准差:mean( ) meanStdDev( )
    学OpenCV===========================================根据公式,这个mean在这里是平均值mask只能用单通道的uchar类型。===========================================1#include<iostream>23#include<opencv2/opencv.hpp>4#include<opencv2/core/utils/logg......
  • MIL⁃STD⁃1553B总线介绍
    MIL⁃STD⁃1553B总线介绍MIL⁃STD⁃1553B是一种命令/响应型多路传输总线,它采用冗余的总线结构,在当前传输线发生故障时可立刻切换到冗余传输线上,防止通信中断。同时,1553B协议严格规定了消息格式,限定了每条消息的最大传输数据量及总线单元的最大响应时间,并规范了总线耦合方式、......
  • ThreadLocal ThreadLocalUtil
    ThreadLocalUtil.javapublicclassThreadLocalUtil{staticfinalThreadLocalTHREAD_LOCAL=newThreadLocal();publicstatic<T>Tget(){return(T)THREAD_LOCAL.get();}publicstaticvoidset(Objectvalue){TH......
  • 线程(Thread)的使用方法和锁(同步代码块,lock锁)的问题
    多线程:    进程:      正在运行的程序,是系统进行资源分配和调用的独立单位。      每一个进程都有它自己的内存空间和系统资源。      理解:一个正在运行的软件    线程:      是进程中的单个顺序控制流,是......
  • kworker和kthread
    kworker和kthread都是Linux内核中的组件,它们在内核中扮演着不同的角色,但也有着一定的联系。kworker定义与功能:定义:kworker是Linux内核中的一个工作线程,用于异步处理工作队列(workqueue)中的任务。这些任务包括但不限于处理硬件中断、文件系统事件、管理系统内存等。功能:kworker......