- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试使用 LD_PRELOAD 机制插入对 pthread_cond_broadcast 的调用。我插入的 pthread_cond_broadcast 函数只是调用原始的 pthread_cond_broadcast。但是,对于同时调用 pthread_cond_wait 和 pthread_cond_broadcast 的非常简单的 pthread 代码,我要么在 glibc 中出现段错误(对于 glibc 2.11.1),要么程序挂起(对于 glibc 2.15)。有什么线索吗?
插入代码(被编译为共享库):
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <dlfcn.h>
static int (*orig_pthread_cond_broadcast)(pthread_cond_t *cond) = NULL;
__attribute__((constructor))
static void start() {
orig_pthread_cond_broadcast =
(int (*)()) dlsym(RTLD_NEXT, "pthread_cond_broadcast");
if (orig_pthread_cond_broadcast == NULL) {
printf("pthread_cond_broadcast not found!!!\n");
exit(1);
}
}
__attribute__((__visibility__("default")))
int pthread_cond_broadcast(pthread_cond_t *cond) {
return orig_pthread_cond_broadcast(cond);
}
简单的 pthread 程序:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t cond_mutex;
pthread_cond_t cond_var;
int condition;
void *thread0_work(void *arg) {
pthread_mutex_lock(&cond_mutex);
printf("Signal\n");
condition = 1;
pthread_cond_broadcast(&cond_var);
pthread_mutex_unlock(&cond_mutex);
return NULL;
}
void *thread1_work(void *arg) {
pthread_mutex_lock(&cond_mutex);
while (condition == 0) {
printf("Wait\n");
pthread_cond_wait(&cond_var, &cond_mutex);
printf("Done waiting\n");
}
pthread_mutex_unlock(&cond_mutex);
return NULL;
}
int main() {
pthread_t thread1;
pthread_mutex_init(&cond_mutex, NULL);
pthread_cond_init(&cond_var, NULL);
pthread_create(&thread1, NULL, thread1_work, NULL);
// Slowdown this thread, so the thread 1 does pthread_cond_wait.
usleep(1000);
thread0_work(NULL);
pthread_join(thread1, NULL);
return 0;
}
编辑:
对于 glibc 2.11.1,gdb bt 给出:
(gdb) set environment LD_PRELOAD=./libintercept.so
(gdb) run
Starting program: /home/seguljac/intercept/main
[Thread debugging using libthread_db enabled]
[New Thread 0x7ffff7436700 (LWP 19165)]
Wait
Signal
Before pthread_cond_broadcast
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff79ca0e7 in pthread_cond_broadcast@@GLIBC_2.3.2 () from /lib/libpthread.so.0
(gdb) bt
#0 0x00007ffff79ca0e7 in pthread_cond_broadcast@@GLIBC_2.3.2 () from /lib/libpthread.so.0
#1 0x00007ffff7bdb769 in pthread_cond_broadcast () from ./libintercept.so
#2 0x00000000004008e8 in thread0_work ()
#3 0x00000000004009a4 in main ()
编辑 2:
(已解决)正如 R.. 所建议的(谢谢!),问题是在我的平台上 pthread_cond_broadcast 是一个版本符号,而 dlsym 给出了错误的版本。此博客非常详细地解释了这种情况:http://blog.fesnel.com/blog/2009/08/25/preloading-with-multiple-symbol-versions/
最佳答案
通过您的函数进行的调用似乎以不同版本的函数结束:
With LD_PRELOAD: __pthread_cond_broadcast_2_0 (cond=0x804a060) at old_pthread_cond_broadcast.c:37
Without LD_PRELOAD: pthread_cond_broadcast@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/pthread_cond_broadcast.S:39
所以你的情况类似于这个问题,即你得到的 pthread 函数版本不兼容:symbol versioning and dlsym
此页面提供了一种解决问题的方法,尽管有点复杂:http://blog.fesnel.com/blog/2009/08/25/preloading-with-multiple-symbol-versions/
关于c - pthread_cond_broadcast 被 dlsym 破坏了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12342133/
是否可以使用 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
我是一名优秀的程序员,十分优秀!