首页 > 解决方案 > 如何找出共享库中的静态析构函数列表

问题描述

我们的项目加载了数百个由不同团队构建的共享 c++ 库。常见的问题之一是由于同一类对象的多次破坏而在退出时崩溃。这是由于(无意)在不同库之间共享相同类变量的实例而发生的。

问题在于寻找罪魁祸首代码。崩溃堆栈通常不会显示有用的信息,并且运行调试器很困难并且需要时间。有什么帮助的是一个应用程序,它至少可以列出一组在退出时为特定so lib调用的析构函数。我认为,有可能从 .fini_array 部分获得。我只是想知道是否有人有经验或可以推荐一个应用程序来这样做。有什么建议怎么做吗?

标签: linuxshared-librariesld

解决方案


如何找出共享库中的静态析构函数列表

您可以反汇编代码并解析对atexit()内部__static_initailization_and_destrution_0函数的调用。像这样:

$ objdump -CD a.out | awk '/<__static_initialization_and_destruction_0\(int, int\)>/{f=1}  /^$/{f=0}  f && /__cxa_atexit@plt/{print to}   /<[^>]*>$/{ gsub(/.*</,""); gsub(/(\+.*)?>/,""); to=$0; }'
std::ios_base::Init::~Init()
B::~B()@@Base
A::~A()@@Base

请注意,优化的构建在装配中将具有不同的结构。atexit在看起来像析构函数之前,你可以得到任何东西:

$ objdump -CD a.out | awk '/__cxa_atexit@plt/{print to}   /~/ && /<[^>]*>$/{ gsub(/.*</,""); gsub(/(\+.*)?>/,""); to=$0; }'
std::ios_base::Init::~Init()
B::~B()@@Base
A::~A()@@Base

但无论如何方法 - 解析反汇编并获取注册的函数atexit

我已经测试过:

#include <iostream>
struct A { ~A() { std::cout << "obi one kenobi"; } };
struct B { ~B() { std::cout << "hello there"; } };
volatile B b;
volatile A a;

gcc -shared -fPIC.


推荐阅读