race_check_and_mem_leak_on_cpp
问题代码
v1_race 版本
test_race_and_leak.cpp
#include <pthread.h> #include <iostream> static int a; void *_work_1(void *args) { for (int i = 0; i < 1000; i++) { a += 1; } int *x = new int; return 0; } int main(int argc, char *argv[]) { a = 0; int count = 1000; pthread_t cThreads[count]; for (int i = 0; i < count; i++) { pthread_create(&cThreads[i], NULL, _work_1, NULL); } for (int i = 0; i < count; i++) { pthread_join(cThreads[i], NULL); } std::cout << " a : " << a << std::endl; return 0; }
build code
g++ -o test_race_and_leak test_race_and_leak.cpp -lpthread # 正确结果 应该是 1000000 # 多次 运行 结果 都小于 1000000 # 说明出现了 data race 数据 争抢 以及 脏读 ./test_race_and_leak a : 999700
race 数据 竞争 分析
检查后 提示 出现了 数据争抢 发生在
0x10C158 同时被 线程 2 线程 3 写入 4 bytes, 也就是 一个 整形的大小
apt install valgrind -y valgrind --tool=memcheck <your_app> <your_apps_params> valgrind --tool=memcheck test_race_and_leak ./test_race_and_leak a : 999779 # 数据 竞争 检查 valgrind --tool=helgrind ./test_race_and_leak # ==2592589== Possible data race during write of size 4 at 0x10C158 by thread #3 # ==2592589== Locks held: none # ==2592589== at 0x10924E: _work_1(void*) (in /root/learn_threads/test_race_and_leak) # ==2592589== by 0x4842B1A: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so) # ==2592589== by 0x4865608: start_thread (pthread_create.c:477) # ==2592589== by 0x4B83292: clone (clone.S:95) # ==2592589== # ==2592589== This conflicts with a previous write of size 4 by thread #2 # ==2592589== Locks held: none # ==2592589== at 0x10924E: _work_1(void*) (in /root/learn_threads/test_race_and_leak) # ==2592589== by 0x4842B1A: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so) # ==2592589== by 0x4865608: start_thread (pthread_create.c:477) # ==2592589== by 0x4B83292: clone (clone.S:95) # ==2592589== Address 0x10c158 is 0 bytes inside data symbol "_ZL1a" # ==2592589== # a : 1000000 # ==2592589== # ==2592589== Use --history-level=approx or =none to gain increased speed, at # ==2592589== the cost of reduced accuracy of conflicting-access information # ==2592589== For lists of detected and suppressed errors, rerun with: -s # ==2592589== ERROR SUMMARY: 1998 errors from 2 contexts (suppressed: 0 from 0)
内存泄露检查
检查后 提示 出现了 内存 泄露 发生在
malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x10942E: main (in /root/learn_threads/test_race_and_leak)
# 内存 泄露检查 valgrind --tool=memcheck --leak-check=full -s ./test_race_and_leak # ==2599297== HEAP SUMMARY: # ==2599297== in use at exit: 100 bytes in 1 blocks # ==2599297== total heap usage: 1,003 allocs, 1,002 frees, 361,828 bytes allocated # ==2599297== # ==2599297== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1 # ==2599297== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) # ==2599297== by 0x10942E: main (in /root/learn_threads/test_race_and_leak) # ==2599297== # ==2599297== LEAK SUMMARY: # ==2599297== definitely lost: 100 bytes in 1 blocks # ==2599297== indirectly lost: 0 bytes in 0 blocks # ==2599297== possibly lost: 0 bytes in 0 blocks # ==2599297== still reachable: 0 bytes in 0 blocks # ==2599297== suppressed: 0 bytes in 0 blocks # ==2599297== # ==2599297== For lists of detected and suppressed errors, rerun with: -s # ==2599297== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)