- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当使用 dlsym()
调用时,我在 Ubuntu 20.04 (gcc v 9.3.0) 上遇到了一个奇怪的运行时行为。
请看下面一个简单的例子:
#include <iostream>
#include <dlfcn.h>
#include <execinfo.h>
#include <typeinfo>
#include <string>
#include <memory>
#include <cxxabi.h>
#include <cstdlib>
extern "C"
{
void __cxa_throw(void *ex, void *info, void (*dest)(void *))
{
std::cout << "__cxa_throw() invoked \n";
static void (*const rethrow)(void *, void *, void (*)(void *)) __attribute__((noreturn))
= (void (*)(void *, void *, void (*)(void *)))dlsym(RTLD_NEXT, "__cxa_throw");
std::cout << "addr in lib=" << &rethrow << "\n";
rethrow(ex, info, dest);
std::terminate();
}
}
#include <iostream>
void foo()
{
throw std::runtime_error("error");
}
int main()
{
foo();
return 0;
}
按如下方式构建这 2 个文件:
g++ -fPIC -std=c++17 test.cpp -g -c -o test.o
g++ -shared ./test.o -o libtest.so
g++ main.cpp -std=c++17 -g -pedantic -L./ -ltest -ldl
将 ldd 馈送到 ./a.out 得到:
ldd a.out
linux-vdso.so.1 (0x00007ffe01186000)
/usr/local/lib/AppProtection/libAppProtection.so (0x00007f1dbd738000)
libtest.so (0x00007f1dbd733000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1dbd708000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1dbd526000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1dbd50b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1dbd319000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1dbd2f4000)
libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007f1dbd1b7000)
libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f1dbd18d000)
libXi.so.6 => /lib/x86_64-linux-gnu/libXi.so.6 (0x00007f1dbd17b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1dbd964000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1dbd02c000)
libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x00007f1dbd024000)
libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f1dbd01c000)
libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6 (0x00007f1dbd007000)
libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007f1dbcfed000)
我们可以看到libtest.so
在libstdc++.so
之前被解析。我期望这段代码应该如何工作:
__cxa_throw()
在 2 个共享库中定义:libtest.so
和 libstdc++.so
foo()
调用中抛出异常时,__cxa_throw
从 libtest.so
解析并调用。dlsym(RTLD_NEXT, "__cxa_throw");
在共享库列表中进一步查找 __cxa_throw
,在 libstdc++.so 中找到并调用。这在除 Ubuntu 20.04 以外的所有平台上都按预期工作,其中 rethrow
引用 libtest.so
中的 __cxa_throw
(但不是 libstc++.so
) 从而导致无限递归。
请协助,因为我对运行时行为感到困惑。
最佳答案
Citrix ICA 客户端的“应用程序保护”组件安装库 /usr/local/lib/AppProtection/libAppProtection.so
并将其添加到 /etc/ld .so.preload
,导致它被加载到每个动态链接的进程中。除此之外,该库用它自己的函数替换了 dlsym
函数。 (如果您好奇这为什么不总是通过进入无限循环来破坏一切,请参阅 How can I intercept dlsym calls using LD_PRELOAD? 。实际上,Citrix 的代码似乎是直接从该答案中复制和粘贴的。)问题是,自从RTLD_NEXT
取决于能够检查返回地址,需要特别注意避免在挂接 dlsym
时破坏它,而他们没有特别注意。结果,RTLD_NEXT
将在 libAppProtection.so
之后的下一个库中查找符号,而不是在您的代码之后的下一个库中查找符号,这正是您运行的问题进入。
这里有一些关于如何处理它的选择:
sudo apt-get purge icaclient
(之后可选择重新安装,但是 choosing no when asked about the app protection component)libdl.so
加载真正的 dlsym
,然后将其用于任何使用 RTLD_NEXT
关于c++ - dlsym() + RTLD_NEXT 在 Ubuntu 20.04 上无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68128568/
是否可以使用 dlsym 从框架加载已命名的未导出符号? ? 我尝试导入的符号有一个名称,在框架内引用它。这是我需要调用的函数。 我正在尝试照常进行 dlopen + dlsym方式,但是当我尝试加载
我收到此链接器错误: system/core/libacc/tests/main.cpp:42: error: undefined reference to 'dlsym' 您能告诉我 ubuntu
我使用 dlsym() 来调用我的 malloc 版本,而不是默认库 malloc: lt_malloc = (void*(*)(size_t))dlsym(RTLD_NEXT, "malloc")
1).直接打印函数地址: printf("strerror=%p, strerror_r=%p\n", strerror, strerror_r); strerror=0x8049ec0, strer
所以我一直试图从本地 dylib 获取符号,但每当我尝试做任何事情时,我都会遇到段错误,我不确定为什么会发生这种情况。我已经在其他程序中看到过这样做并且它们工作正常,所以我知道它有效但我似乎无法做到:
我真的很讨厌在这里提问。但我一直在看some of the other posts ,并且诸如此类的解决方案似乎不起作用。这可能是我对语法的误解。 我正在改进我的一些旧代码。问题中的函数循环通过一些加
作为 malloc 包装器,我使用了这段经典的代码片段: #define _GNU_SOURCE #include #include #include void* malloc(size_t s
我正在用 C 编写一个插件应用程序,我正在使用 dlopen/dlsym 动态加载某些功能的“实现”。例如,我有以下指向函数的指针 struct cti_t* (*create)() = 0; 然后我
我使用 dlopen 在我的程序中加载 pthread 库,并使用 dlsym 获取处理程序到 pthread_create 和 pthread_join >. 如何确保两个处理程序的版本兼容?我不在
man page dlsym() 列表 *(void **) (&cosine) = dlsym(handle, "cos"); 作为转换 dlsym() 返回值的解决方法。 这里的*(void
我在 C 中使用 dlsym() 我有一个问题 dlsym() 的返回值是否应该显式转换或者它是否被正确地隐式转换。这是函数: double (*(compile)(void))(double x,
我有一个动态加载库的应用程序,它动态加载库... 在 Windows 中,我能够遍历所有加载的模块以查找我感兴趣的符号。不知道如何在 Unix/Linux 环境中执行此操作。我知道我可以对前两个符号使
奇怪的是 dlsym 可以从剥离的二进制文件中导入函数。 谁能告诉我为什么/怎么做? === FILE: a.c === int a1() { return 1; } int a2() { retur
我正在尝试使用 Qt 5.3.0 在 Linux Mint 17 中编译 C++ 程序。我已将以下行添加到 .pro 文件中: QMAKE_LFLAGS += -ldl -fPIC 我的程序使用了 d
我正在使用 POSIX dlopen/dlsym API 在运行时加载动态库,然后按名称从这些库中调用函数。 存储 dlsym 的结果在性能方面是个好主意吗?某处?或者 dlsym 是否已经进行了自己
有没有跑路的希望dlopen(NULL, ...)并为静态编译的二进制文件获取符号? 例如,使用以下代码,如果程序是动态编译的并且我使用 -rdynamic,我可以获得符号。 . $ gcc -o f
我正在从共享对象 (a.so) 调用函数。我使用 dlopen 加载 a.so 并使用 dlsym 加载映射函数。 int (*funcPtr)() = reinterpret_cast(dl
我正在尝试使用 dlsym() 在 libcrypto.so 文件中查找 connect 符号,并希望用我的方法替换此 connect 。 void * lib_orig_tols = dlopen
我想从我的共享库 (.so) 中访问一个类符号这是我需要做的正确方法吗? MyClass* pMyClass= (MyClass*)dlsym(phandle, "MyClass"); 如果这是正确的
dlsym为枚举值返回 null NSLog(@"%s",dlsym(RTLD_DEFAULT, "NSTextAlignmentCenter")); 输出 2014-01-28 13:07:04.2
我是一名优秀的程序员,十分优秀!