다음을 시도합니다. pthreads 라이브러리의 래퍼를 작성하여 각 API를 호출 할 때마다 일부 정보를 기록합니다. 기록하고 싶은 정보는 스택 추적입니다.리눅스 x86에서 backtrace()를 호출 할 때 세그먼테이션 오류가 발생했습니다.
다음은 컴파일하고 그대로 실행할 수있는 원본 코드의 최소 코드입니다.
의 초기화 (파일 libmutex.c
) :
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <dlfcn.h>
static int (*real_mutex_lock)(pthread_mutex_t *) __attribute__((__may_alias__));
static void *pthread_libhandle;
#ifdef _BIT64
#define PTHREAD_PATH "/lib64/libpthread.so.0"
#else
#define PTHREAD_PATH "/lib/libpthread.so.0"
#endif
static inline void load_real_function(char* function_name, void** real_func) {
char* msg;
*(void**) (real_func) = dlsym(pthread_libhandle, function_name);
msg = dlerror();
if (msg != NULL)
printf("init: real_%s load error %s\n", function_name, msg);
}
void __attribute__((constructor)) my_init(void) {
printf("init: trying to dlopen '%s'\n", PTHREAD_PATH);
pthread_libhandle = dlopen(PTHREAD_PATH, RTLD_LAZY);
if (pthread_libhandle == NULL) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
load_real_function("pthread_mutex_lock", (void**) &real_mutex_lock);
}
래퍼 및 역 추적 할 수있는 전화. 나는 가능한 한 많이 다듬 었으므로, 예를 들어 pthread_mutex_lock이라는 함수를 호출하지 않는다는 것을 알고있다. 여기
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int main (int argc, char *argv[]) {
pthread_mutex_t x;
printf("Before mutex\n"); fflush(stdout);
pthread_mutex_lock(&x);
printf("after mutex\n");fflush(stdout);
return 0;
}
이 컴파일되는 모든 방법은 다음과 같습니다 :
void my_backtrace(void) {
#define SIZE 100
void *buffer[SIZE];
int nptrs;
nptrs = backtrace(buffer, SIZE);
printf("backtrace() returned %d addresses\n", nptrs);
}
int pthread_mutex_lock(pthread_mutex_t *mutex) {
printf("In pthread_mutex_lock\n"); fflush(stdout);
my_backtrace();
return 0;
}
은 내가 사용하는 바이너리 (파일
tst_mutex.c
을)이를 테스트하려면
rm -f *.o *.so tst_mutex
cc -Wall -D_BIT64 -c -m64 -fPIC libmutex.c
cc -m64 -o libmutex.so -shared -fPIC -ldl -lpthread libmutex.o
cc -Wall -m64 tst_mutex.c -o tst_mutex
실행
LD_PRELOAD=$(pwd)/libmutex.so ./tst_mutex
다음과 같이 충돌합니다. Linux x86에서 세그먼트 화 오류. Linux PPC에서는 모든 것이 완벽하게 작동합니다. GCC 컴파일러, GLIBC 라이브러리 및 Linux 배포판의 몇 가지 버전을 사용해 보았습니다. 모두 실패합니다.
출력은 재귀 여기 있다는 것을 시사
init: trying to dlopen '/lib64/libpthread.so.0'
Before mutex
In pthread_mutex_lock
In pthread_mutex_lock
In pthread_mutex_lock
...
...
./run.sh: line 1: 25023 Segmentation fault LD_PRELOAD=$(pwd)/libmutex.so ./tst_mutex
이다. backtrace()
의 소스 코드를 보았습니다. 잠금 메커니즘에 이없고이 없습니다. 스택 프레임 링크 된 목록을 둘러 보는 것만으로 간단합니다. 또한 objdump를 사용하여 라이브러리 코드를 검사했지만 그 결과는 비정상적으로 밝혀지지 않았습니다.
여기 무슨 일입니까? 모든 해결책/해결 방법은 무엇입니까?
아, 아마도 가장 중요한 것입니다. 이것은 pthread_mutex_lock 함수에서만 발생합니다 !! 오버라이드 된 다른 pthread_ * 함수에서 스택을 인쇄하면 정상적으로 작동합니다 ...
RTLD_NOW로 시도해 보셨나요? – stark
문제는 pthreads 라이브러리를 여는 것이 아닙니다. –
당신의 단계를 시도했지만'./tst_mutex : symbol lookup error : libmutex.so : undefined symbol : dlopen' 오류가납니다. 지금 문제를 해결하지는 않겠지 만 문제를 재현하기위한 단계에서 뭔가가 누락되었을 수 있습니다. –