-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

コードは の戻り値の型のない 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()

$ 

他の 2 つのアプローチとしては、次のようなものがあります。

  • function を書き、my_pthread_self()どこでも使用し、real を呼び出すようにするpthread_self()

  • PTHREAD_SELF内部的に real を呼び出すラッパーを呼び出すマクロを用意します。pthread_self()

于 2013-01-28T18:43:19.617 に答える
0

以下は少しハックですが、C で動作するはずです。以下をヘッダーに入れます。これは、pthread.h のまたは代わりに含める必要があります<pthread.h>(ただし、 pthread.hの後には決して含めないでください)。

pthread_t _pthread_self(void);

#define pthread_self _pthread_self

対応する .c ファイルでは、次のようになります。

#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();
}

ここで、その .c ファイル以外のファイルに書き込むと、ラッパー関数に展開されますpthread_self。上記の .c ファイル内では、このハックが行われていないため、ラッパー内の呼び出しでライブラリ関数が呼び出されます。

于 2013-01-28T18:45:56.557 に答える
0

これにより、いくつかのアイデアが得られるはずです。実行可能ファイルのリンクを制御する場合、LD_PRELOAD を使用する必要はありません。

于 2013-01-28T18:46:46.850 に答える
0

皆さんのお陰で。主にこれらの 2 つのリンクIntercepting Arbitrary Functions on...Tutorial: Function Interposition in Linux show by @Carl Norum と @Arkadyi に基づいて、考えられる解決策を示します。

2 つのソース ファイルと 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

test.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 に答える