我已經蒸餾了一個更大的程序,直到底部顯示的代碼。在Valgrind的運行這個程序最終會報告這個錯誤:glibc,退出時關閉FILE *之間的可能競態條件?
==7234== Invalid read of size 4 ==7234== at 0x34A7275FC8: [email protected]@GLIBC_2.2.5 (in /usr/lib64/libc-2.15.so) ==7234== by 0x34A7275EA1: new_do_write (in /usr/lib64/libc-2.15.so) ==7234== by 0x34A7276D44: [email protected]@GLIBC_2.2.5 (in /usr/lib64/libc-2.15.so) ==7234== by 0x34A7278DB6: _IO_flush_all_lockp (in /usr/lib64/libc-2.15.so) ==7234== by 0x34A7278F07: _IO_cleanup (in /usr/lib64/libc-2.15.so) ==7234== by 0x34A7238BBF: __run_exit_handlers (in /usr/lib64/libc-2.15.so) ==7234== by 0x34A7238BF4: exit (in /usr/lib64/libc-2.15.so) ==7234== by 0x34A722173B: (below main) (in /usr/lib64/libc-2.15.so) ==7234== Address 0x542f2e0 is 0 bytes inside a block of size 568 free'd ==7234== at 0x4A079AE: free (vg_replace_malloc.c:427) ==7234== by 0x34A726B11C: [email protected]@GLIBC_2.2.5 (in /usr/lib64/libc-2.15.so) ==7234== by 0x40087C: writer (t.c:22) ==7234== by 0x34A7607D13: start_thread (in /usr/lib64/libpthread-2.15.so) ==7234== by 0x34A72F167C: clone (in /usr/lib64/libc-2.15.so)
從上面的輸出,這似乎是發生了什麼:
- 的main()返回,並開始運行退出處理程序關閉所有FILE *
- 作家()的線程,仍在運行,喚醒,關閉文件*
- 退出處理程序試圖訪問封閉FILE *,也就是現在的無效/ free()的倒是
據我所知,測試程序沒有做任何未定義的事情,但我很樂意在這方面出錯。
Valgrind鉤入各種函數,所以它可能是valgrind錯誤而不是glibc。
- 這是一個glibc錯誤?
或者它是一個valgrind錯誤?
有關如何確定它是valgrind還是glibc的任何想法?
TC:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *test(void *arg)
{
return NULL;
}
void *writer(void *arg)
{
for(;;) {
char a[100];
FILE *f = fopen("out", "w");
if(f == NULL)
abort();
fputs("Test", f);
if(fgets(a, 100, stdin))
fputs(a, f);
fclose(f); //line 22
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t tid1,tid2;
pthread_create(&tid1, NULL, writer, NULL);
pthread_create(&tid2, NULL, test, NULL);
pthread_join(tid2, NULL);
//pthread_join(tid1, NULL); //no bug if we wait for writer()
return 0;
}
//compile: gcc t.c -g -pthread
可能需要幾分鐘觸發從Valgrind的一個錯誤,用:
while [ true ]; do
echo test |valgrind --error-exitcode=2 ./a.out || break
done
環境:Fedora的17,glibc的2.15,GCC-4.7.0 -5,內核3.5.3-1.fc17.x86_64,valgrind-3.7.0-4
這裏真正的問題是什麼?那個valgrind抱怨?你已經知道正確的處理是加入tid1(可能在鼓勵它終止一個標誌後)。 – walrii
@walrit問題是valgrind,glibc或程序有bug,我想知道哪一個。這是一個簡單的測試用例 - 在退出時暫停所有線程並不總是可行的 - 如果退出多線程並不會導致運行時間垃圾內存,那麼這將是一個加號。 – nos