pthread_cond_broadcast 被 dlsym 破坏? [英] pthread_cond_broadcast broken with dlsym?

查看:20
本文介绍了pthread_cond_broadcast 被 dlsym 破坏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 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).有什么线索吗?

I am trying to interpose calls to pthread_cond_broadcast using LD_PRELOAD mechanism. My interposed pthread_cond_broadcast function just calls the original pthread_cond_broadcast. However, for a very simple pthread code where both pthread_cond_wait and pthread_cond_broadcast get invoked, I either end up with a segfault in glibc (for glibc 2.11.1) or the program hangs (for glibc 2.15). Any clues on that is going on?

插入代码(编译为共享库):

The interposition code (that gets compiled as a shared library):

#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!!!
");
        exit(1);
    }
}

__attribute__((__visibility__("default")))
int pthread_cond_broadcast(pthread_cond_t *cond) {
    return orig_pthread_cond_broadcast(cond);
}

简单的 pthread 程序:

The simple pthread program:

#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
");
    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
");
        pthread_cond_wait(&cond_var, &cond_mutex);
        printf("Done waiting
");
    }
    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 给出:

For glibc 2.11.1, gdb bt gives:

(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/

(Solved) As suggested by R.. (thanks!), the issue is that on my platform pthread_cond_broadcast is a versioned symbol, and dlsym gives the wrong version. This blog explains this situation in great detail: http://blog.fesnel.com/blog/2009/08/25/preloading-with-multiple-symbol-versions/

推荐答案

通过你的函数的调用似乎以不同版本的函数结束:

The call through your function seems to end up in a different version of the function:

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 函数版本:符号版本控制和dlsym

So your situation is similar to this question, i.e. you are getting incompatible versions of pthread functions: symbol versioning and dlsym

这个页面提供了一种解决问题的方法,虽然有点复杂:http://blog.fesnel.com/blog/2009/08/25/preloading-with-multiple-symbol-versions/

This page gives one way to solve the problem, though a bit complex: http://blog.fesnel.com/blog/2009/08/25/preloading-with-multiple-symbol-versions/

这篇关于pthread_cond_broadcast 被 dlsym 破坏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆