我一直从cache_store
获取TSAN报告。
该文档说,我需要防止在每个对象上进行并发访问,但是从TSAN的观点出发,我将其解释为在每个git_repository
对象上进行并发访问。所有派生对象都必须具有相同的锁(例如git_commit
,git_tree
等)。正确吗?
TSAN输出:
WARNING: ThreadSanitizer: data race (pid=28177)
Atomic write of size 4 at 0x55bc2dc780ec by thread T14 (mutexes: write M889877933370572712):
#0 __tsan_atomic32_fetch_add <null> (libtsan.so.0+0x6c101)
#1 git_atomic_add external/libgit2/src/thread-utils.h:82 (analyze_remote_git+0x46e240)
#2 cache_store external/libgit2/src/cache.c:200 (analyze_remote_git+0x46ed4c)
#3 git_cache_store_raw external/libgit2/src/cache.c:231 (analyze_remote_git+0x46eec0)
#4 odb_read_1 external/libgit2/src/odb.c:1095 (analyze_remote_git+0x413b73)
#5 git_odb_read external/libgit2/src/odb.c:1116 (analyze_remote_git+0x413cdf)
#6 git_object_lookup_prefix external/libgit2/src/object.c:221 (analyze_remote_git+0x4056ab)
#7 git_object_lookup external/libgit2/src/object.c:252 (analyze_remote_git+0x4057d1)
#8 git_commit_lookup external/libgit2/src/object_api.c:23 (analyze_remote_git+0x40f980)
#9 create_branch external/libgit2/src/clone.c:41 (analyze_remote_git+0x37c582)
#10 create_tracking_branch external/libgit2/src/clone.c:102 (analyze_remote_git+0x37c880)
#11 update_head_to_new_branch external/libgit2/src/clone.c:124 (analyze_remote_git+0x37c94e)
#12 update_head_to_remote external/libgit2/src/clone.c:189 (analyze_remote_git+0x37cc5c)
#13 checkout_branch external/libgit2/src/clone.c:315 (analyze_remote_git+0x37d1b1)
#14 clone_into external/libgit2/src/clone.c:348 (analyze_remote_git+0x37d460)
#15 git__clone external/libgit2/src/clone.c:432 (analyze_remote_git+0x37da83)
#16 git_clone external/libgit2/src/clone.c:463 (analyze_remote_git+0x37dbfc)
... ADDITIONAL STACK REMOVED ...
Previous read of size 4 at 0x55bc2dc780ec by thread T13 (mutexes: write M1852):
#0 cache_store external/libgit2/src/cache.c:192 (analyze_remote_git+0x46ec31)
#1 git_cache_store_parsed external/libgit2/src/cache.c:237 (analyze_remote_git+0x46ef20)
#2 git_object__from_odb_object external/libgit2/src/object.c:148 (analyze_remote_git+0x405314)
#3 git_object_lookup_prefix external/libgit2/src/object.c:244 (analyze_remote_git+0x405747)
#4 git_object_lookup external/libgit2/src/object.c:252 (analyze_remote_git+0x4057d1)
#5 git_tree_lookup external/libgit2/src/object_api.c:56 (analyze_remote_git+0x40fb0f)
#6 tree_walk external/libgit2/src/tree.c:978 (analyze_remote_git+0x3a22f5)
#7 tree_walk external/libgit2/src/tree.c:989 (analyze_remote_git+0x3a237e)
#8 tree_walk external/libgit2/src/tree.c:989 (analyze_remote_git+0x3a237e)
#9 git_tree_walk external/libgit2/src/tree.c:1025 (analyze_remote_git+0x3a2545)
... ADDITIONAL STACK REMOVED ...
Location is global 'git_cache__current_storage' of size 4 at 0x55bc2dc780ec (analyze_remote_git+0x0000011d60ec)
Mutex M889877933370572712 is already destroyed.
Mutex M1852 (0x7b4400019f28) created at:
#0 pthread_rwlock_init <null> (libtsan.so.0+0x2ef82)
#1 git_cache_init external/libgit2/src/cache.c:72 (analyze_remote_git+0x46e61f)
#2 repository_alloc external/libgit2/src/repository.c:245 (analyze_remote_git+0x416764)
#3 git_repository_open_ext external/libgit2/src/repository.c:829 (analyze_remote_git+0x418cfe)
#4 git_repository_open external/libgit2/src/repository.c:887 (analyze_remote_git+0x419127)
#5 git_repository_init_ext external/libgit2/src/repository.c:2112 (analyze_remote_git+0x41ced5)
#6 git_repository_init external/libgit2/src/repository.c:2056 (analyze_remote_git+0x41c97b)
#7 default_repository_create external/libgit2/src/clone.c:234 (analyze_remote_git+0x37ce3e)
#8 git__clone external/libgit2/src/clone.c:420 (analyze_remote_git+0x37d8cb)
#9 git_clone external/libgit2/src/clone.c:463 (analyze_remote_git+0x37dbfc)
... ADDITIONAL STACK REMOVED ...
该文档说,我需要防止在每个对象上进行并发访问,但是从TSAN的观点出发,我将其解释为在每个git_repository对象上进行并发访问。所有派生对象都必须具有相同的锁(例如git_commit,git_tree等)。正确吗?
是。git_repository
以及从它派生的所有对象仅应由单个线程使用。
git_repository
是轻量级的,并且可以与其他git_repository
安全地交互(以及其他进程中的其他git客户端,包括在命令行上使用git)。因此,您可以随意在多个线程中创建多个git_repository
对象。