pthread에 버그가 있는 듯 합니다.
글쓴이: Hyun / 작성시간: 화, 2004/03/09 - 5:27오후
이럴 수가...
코드는 ...
#include <pthread.h> #include <stdio.h> pthread_t thread; void *thread_fun( void *arg ) { printf( "thread...\n" ); pthread_cleanup_push( (void(*)(void*))printf, (void*)"cleanup1 called...\n" ); pthread_cleanup_push( (void(*)(void*))printf, (void*)"cleanup2 called...\n" ); pthread_cleanup_push( (void(*)(void*))printf, (void*)"cleanup3 called...\n" ); printf( "cleanup registered.\n" ); sleep( 10 ); printf( "sleep done.\n" ); pthread_cleanup_pop( 1 ); pthread_cleanup_pop( 1 ); pthread_cleanup_pop( 1 ); return NULL; } int main( void ) { pthread_create( &thread, NULL, thread_fun, NULL ); sleep( 2 ); printf( "cancel...\n" ); pthread_cancel( thread ); printf( "canceled.\n" ); pthread_join( thread, NULL ); printf( "joined...\n" ); return 0; }
와 같이 했구요.
Makefile은...
CROSS = powerpc-405-linux-gnu- CC = $(CROSS)gcc target = test objs = main.o all: $(target) $(target): $(objs) $(CC) $(CFLAGS) -lpthread -o $@ $^ .c.o: $(CC) $(CFLAGS) -c -o $@ $< clean: rm -f $(objs) $(target) install: all cp $(target) /home/parkhw00/target/home/parkhw00/tmp/
와 같이 했습니다.
Makefile 첫부분을 주석으로 만들어 pc에서 돌렸을때는...
[parkhw00@daebak pthread_test]$ make clean all rm -f main.o test gcc -c -o main.o main.c gcc -lpthread -o test main.o [parkhw00@daebak pthread_test]$ ./test thread... cleanup registered. cancel... canceled. cleanup3 called... cleanup2 called... cleanup1 called... joined... [parkhw00@daebak pthread_test]$
이렇게 의도한 대로 되는데...
powerpc에서 돌렸을때는
[root@12.34.56.78 parkhw00]# ./tmp/test thread... cleanup registered. cancel... canceled. cleanup3 called... joined... [root@12.34.56.78 parkhw00]#
처럽 됩니다.
똑같은 소스로 컴파일 했는데...
다른 결과가 나오는군요.
cleanup 함수를 첫번째꺼만 호출하고 바로 쓰래드가 죽어버립니다.
어떻게 하면 좋죠...
pc환경은 페도라코어1이며.
powerpc 환경은 http://kegel.com/crosstool/ 에 있는 크로스 컴파일러를 사용해서 구축했습니다.
타겟보드의 라이브러리 버전은...
-rwxr-xr-x 1 parkhw00 parkhw00 1593370 Feb 4 2004 /lib/libc-2.3.2.so -rwxr-xr-x 1 parkhw00 parkhw00 90079 Feb 4 2004 /lib/libpthread-0.10.so
이구요...
경험 있으신 분 있나요???
누가 크로스컴파일러로 이런허접질을 할까요...
답글이 달리기를... 라이브러리 버그가 아니기를 기원합니다.
File attachments:
Forums:
printf 를 바로 주지 말고 한번 감싸는 다른 청소 함수를 주면 어떻
printf 를 바로 주지 말고 한번 감싸는 다른 청소 함수를 주면 어떻게 됩니까? 실험 부탁드립니다.
[code:1]void print( void *arg )
욜케 해봤는데...
그래도 똑같네요...
아궁아궁...
시껍이군요...
그래두... 관심 있는분이 있으니 다행이군요... :lol:
pop( 0 ) 으로 하면 어떻게 됩니까? 또 실험해주셔야겠네요... -
pop( 0 ) 으로 하면 어떻게 됩니까? 또 실험해주셔야겠네요... -_-;
결과는 똑같습니다.맨페이지를 보면...[quote] p
결과는 똑같습니다.
맨페이지를 보면...
pthread_cleanup_pop( 0 )
이라고 하면 program counter가 그 까지 갔을때 등록한 cleanup함수를 호출안하고 그냥 목록에서 지우는것 같습니다.
몬타비스타에서 제공한 powerpc용 pthread library를 사용하면 위와 같은 버그는 없더라구요.
제가 컴파일을 한 것에서만 위와같은 문제가 생기는거 같은데...
컴파일을 잘못한것인지... 패치를 덜 적용한것인지 궁굼하군요...
패치를 어디가면 구할 수 있을지...
버그 수정했습니다.
버그 수정했습니다.
powerpc의 c컴파일러가 함수를 호출할대는 스택을 밑을로 자라게 하는데.
한 함수안에서 중괄호를 이용할때는 스택을 위로 자라게 하더군요...
pthread안에서 스택포인터의 위치를 비교하는 루틴이 있어서 제일 마지막에 등록한 하나의 cleanup함수만 등록이 되고 나머지는 등록이 안되던 버그를 수정했습니다.
glibc-linuxthread-2.2.2까지는 버그가 없던데 그 이후버전부터 2.3.2(현재의 최신버전)까지 버그가 있더군요...
x86에서는 문제가 안되는 버그인데... ppc나 다른 프로세서(mips에서도 생긴다는거 같더군요...)에서도 버그가 생긴다고 합니다.
pthread_cleanup_push, pthread_perform_cleanup(pthread_exit에서 호출됨)함수를 수정했습니다.
댓글 달기