-1

我想使用个人的“pthread_self”功能。我想重写“pthread_self()”,最后调用真正的“pthread_self”。在 C/C++ 中可能吗?

例子:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>

pthread_t pthread_self(void)
{
  // Do something else.....
  // ...
  // And finally call to de real pthread_self():
  return ::pthread_self();  // This doesn't work
}

main()
{
    printf("\nThis is my main thread: %lu\n", pthread_self());
}
4

5 回答 5

0

The following is a bit hacky but should work in C. Put the following in a header which you would have to include before or instead of <pthread.h> (but never after pthread.h):

pthread_t _pthread_self(void);

#define pthread_self _pthread_self

And in the corresponding .c file:

#include <pthread>
#include "wrapper.h"
#undef pthread_self    // undo the hack locally

pthread_t _pthread_self(void)
{
  // Do something else.....
  // ...
  // And finally call to the real pthread_self():
  return pthread_self();
}

Now, when you write pthread_self in some other file than that .c file, it expands to your wrapper function. Within the .c file above, since this hack is not done, the call within the wrapper will call the library function.

于 2013-01-28T18:45:56.557 回答
0

This should give you some ideas. If you control the linking of your executable, you don't need to use LD_PRELOAD.

于 2013-01-28T18:46:46.850 回答
0

代码似乎是没有返回类型的 C89 main。所以我建议你删除函数中前面的::运算符并重新编译。pthread_self()pthread_self(void)

也可以用其他名称称呼您pthread_self(),例如pthread_self_2(void)

于 2013-01-28T18:38:57.590 回答
0

是否允许pthread_self()使用虚拟变量(从未使用过)重载?

pthread_t pthread_self( bool )
{
    // Do something else.....
    // ...
    // And finally call to de real pthread_self():
    printf( "%s\n", __PRETTY_FUNCTION__ );
    return ::pthread_self();  // This doesn't work
}

int main()
{
    printf( "%s\n", __PRETTY_FUNCTION__ );
    pthread_self( false );
    printf( "%s\n", __PRETTY_FUNCTION__ );
}

生产

$ g++ test.cpp -lpthread

$ ./a.out
int main()
pthread_t pthread_self(bool)
int main()

$ 

另外两种方法可能是:

  • 编写一个函数my_pthread_self(),到处使用它,并让它调用真实的pthread_self()

  • 有一个宏PTHREAD_SELF,它调用你的包装器,它在内部调用 realpthread_self()

于 2013-01-28T18:43:19.617 回答
0

感谢大家。主要基于这两个链接Intercepting Arbitrary Functions on...Tutorial: Function Interposition in Linux show by @Carl Norum 和 @Arkadyi,我向您展示了一个可能的解决方案:

我有两个源文件和一个 Makefile:

mipthread_self.C

#include <stdio.h>
#include <pthread.h>

#if defined (__STDC__) || defined (__cplusplus) || defined (c__plusplus)

#if defined (__cplusplus) || defined (c__plusplus)
extern "C" {
#endif

pthread_t __real_pthread_self();

pthread_t __wrap_pthread_self(void)
{
   printf("This is mipthread_self %lu\n", __real_pthread_self());
   return __real_pthread_self();
}

#if defined (__cplusplus) || defined (c__plusplus)
}
#endif

#endif

测试.C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>


void* start_function(void* value)
{
    printf("Thread start function is running for: %u\n", (unsigned int)pthread_self());
    sleep(5);
    pthread_exit(value);
}

int main()
{
    int res;
    pthread_t thread1, thread2;
    void* threadReturnValue;

    res = pthread_create(&thread1, NULL, start_function, (void*)"thread-one");
    if (res != 0) {
        perror("Creation of thread failed");
        exit(EXIT_FAILURE);
    }
    printf("Thread1 created with id: %u\n", (unsigned int)thread1);

    res = pthread_create(&thread2, NULL, start_function, (void*)"thread-two");
    if (res != 0) {
        perror("Creation of thread failed");
        exit(EXIT_FAILURE);
    }
    printf("Thread2 created with id: %u\n", (unsigned int)thread2);

    res = pthread_join(thread1, &threadReturnValue);
    if (res != 0) {
        perror("Joining of thread failed");
        exit(EXIT_FAILURE);
    }
    printf("%s joined.\n", (char*)threadReturnValue);

    res = pthread_join(thread2, &threadReturnValue);
    if (res != 0) {
        perror("Joining of thread failed");
        exit(EXIT_FAILURE);
    }
    printf("%s joined.\n", (char*)threadReturnValue);

    return 0;
}

Makefile

BIN=test

CFLAGS=-g -m32 -fPIC -Wall $(DEFINES)
TIPO=-m32

PWD=`pwd`
DIR_OBJ=$(PWD)
DIR_BIN=$(DIR_OBJ)

INCLUDES=
LD_LIBRARIES=-L$(DIR_OBJ) -lmipthread -Xlinker --wrap -Xlinker pthread_self -lpthread -lstdc++


$(BIN): libmipthread.a
        @echo ""
        @echo "Se va a generar el binario $@"
        @echo ""
        gcc $(CFLAGS) test.C -o $(DIR_BIN)/$@ $(LD_LIBRARIES)

libmipthread.a: mipthread_self.o
        ar crv $(DIR_OBJ)/$@ $(DIR_OBJ)/$<

mipthread_self.o: mipthread_self.C
        gcc $(CFLAGS) -c ${PWD}/$< -o $(DIR_OBJ)/$@ $(INCLUDES)

clean:
        rm $(DIR_OBJ)/*.o
        rm $(DIR_OBJ)/*.a
        rm $(DIR_OBJ)/test
于 2013-01-29T11:31:08.407 回答