rugged 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +1 -0
- data/README.md +3 -3
- data/ext/rugged/rugged.c +7 -4
- data/ext/rugged/rugged_commit.c +1 -1
- data/ext/rugged/rugged_config.c +1 -1
- data/ext/rugged/rugged_object.c +1 -1
- data/ext/rugged/rugged_remote.c +32 -2
- data/ext/rugged/rugged_repo.c +13 -3
- data/lib/rugged/commit.rb +17 -4
- data/lib/rugged/repository.rb +7 -8
- data/lib/rugged/submodule_collection.rb +4 -4
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +41 -74
- data/vendor/libgit2/COPYING +109 -1
- data/vendor/libgit2/cmake/{Modules/AddCFlagIfSupported.cmake → AddCFlagIfSupported.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/EnableWarnings.cmake → EnableWarnings.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindCoreFoundation.cmake → FindCoreFoundation.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindGSSAPI.cmake → FindGSSAPI.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindGSSFramework.cmake → FindGSSFramework.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindHTTP_Parser.cmake → FindHTTP_Parser.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindIconv.cmake → FindIconv.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindPCRE.cmake → FindPCRE.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindPCRE2.cmake → FindPCRE2.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindPkgLibraries.cmake → FindPkgLibraries.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindSecurity.cmake → FindSecurity.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindStatNsec.cmake → FindStatNsec.cmake} +0 -0
- data/vendor/libgit2/cmake/Findfutimens.cmake +14 -0
- data/vendor/libgit2/cmake/{Modules/FindmbedTLS.cmake → FindmbedTLS.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/IdeSplitSources.cmake → IdeSplitSources.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/PkgBuildConfig.cmake → PkgBuildConfig.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/SanitizeBool.cmake → SanitizeBool.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/SelectGSSAPI.cmake → SelectGSSAPI.cmake} +18 -26
- data/vendor/libgit2/cmake/{Modules/SelectHTTPSBackend.cmake → SelectHTTPSBackend.cmake} +29 -32
- data/vendor/libgit2/cmake/{Modules/SelectHashes.cmake → SelectHashes.cmake} +21 -28
- data/vendor/libgit2/deps/chromium-zlib/CMakeLists.txt +101 -0
- data/vendor/libgit2/deps/http-parser/CMakeLists.txt +4 -3
- data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +24 -10
- data/vendor/libgit2/deps/ntlmclient/compat.h +0 -27
- data/vendor/libgit2/deps/ntlmclient/crypt.h +14 -9
- data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +20 -20
- data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +3 -3
- data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +37 -36
- data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +4 -3
- data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +178 -51
- data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +74 -5
- data/vendor/libgit2/deps/ntlmclient/ntlm.c +164 -135
- data/vendor/libgit2/deps/ntlmclient/ntlm.h +13 -9
- data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +16 -3
- data/vendor/libgit2/deps/ntlmclient/unicode.h +10 -4
- data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +16 -27
- data/vendor/libgit2/deps/ntlmclient/unicode_builtin.h +20 -0
- data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +28 -52
- data/vendor/libgit2/deps/ntlmclient/unicode_iconv.h +22 -0
- data/vendor/libgit2/deps/ntlmclient/util.c +15 -1
- data/vendor/libgit2/deps/ntlmclient/util.h +2 -1
- data/vendor/libgit2/deps/pcre/LICENCE +93 -0
- data/vendor/libgit2/deps/pcre/pcre.h +2 -2
- data/vendor/libgit2/deps/pcre/pcre_compile.c +29 -17
- data/vendor/libgit2/deps/pcre/pcre_jit_compile.c +4 -4
- data/vendor/libgit2/deps/pcre/pcreposix.c +2 -3
- data/vendor/libgit2/deps/zlib/CMakeLists.txt +6 -5
- data/vendor/libgit2/deps/zlib/deflate.c +1 -0
- data/vendor/libgit2/include/git2/annotated_commit.h +1 -1
- data/vendor/libgit2/include/git2/apply.h +2 -0
- data/vendor/libgit2/include/git2/attr.h +89 -0
- data/vendor/libgit2/include/git2/blame.h +95 -42
- data/vendor/libgit2/include/git2/blob.h +31 -3
- data/vendor/libgit2/include/git2/branch.h +25 -0
- data/vendor/libgit2/include/git2/cert.h +42 -5
- data/vendor/libgit2/include/git2/checkout.h +28 -12
- data/vendor/libgit2/include/git2/commit.h +35 -19
- data/vendor/libgit2/include/git2/common.h +33 -6
- data/vendor/libgit2/include/git2/config.h +1 -1
- data/vendor/libgit2/include/git2/deprecated.h +248 -8
- data/vendor/libgit2/include/git2/diff.h +35 -20
- data/vendor/libgit2/include/git2/errors.h +8 -7
- data/vendor/libgit2/include/git2/filter.h +57 -17
- data/vendor/libgit2/include/git2/graph.h +20 -2
- data/vendor/libgit2/include/git2/index.h +4 -5
- data/vendor/libgit2/include/git2/indexer.h +2 -1
- data/vendor/libgit2/include/git2/odb.h +44 -20
- data/vendor/libgit2/include/git2/pack.h +1 -1
- data/vendor/libgit2/include/git2/patch.h +8 -0
- data/vendor/libgit2/include/git2/rebase.h +25 -1
- data/vendor/libgit2/include/git2/refs.h +9 -5
- data/vendor/libgit2/include/git2/remote.h +59 -6
- data/vendor/libgit2/include/git2/repository.h +95 -52
- data/vendor/libgit2/include/git2/revparse.h +5 -5
- data/vendor/libgit2/include/git2/status.h +115 -59
- data/vendor/libgit2/include/git2/strarray.h +6 -10
- data/vendor/libgit2/include/git2/submodule.h +9 -0
- data/vendor/libgit2/include/git2/sys/commit_graph.h +174 -0
- data/vendor/libgit2/include/git2/sys/filter.h +49 -28
- data/vendor/libgit2/include/git2/sys/midx.h +74 -0
- data/vendor/libgit2/include/git2/sys/odb_backend.h +7 -0
- data/vendor/libgit2/include/git2/sys/transport.h +1 -0
- data/vendor/libgit2/include/git2/tag.h +12 -0
- data/vendor/libgit2/include/git2/transport.h +1 -1
- data/vendor/libgit2/include/git2/tree.h +2 -14
- data/vendor/libgit2/include/git2/types.h +9 -0
- data/vendor/libgit2/include/git2/version.h +3 -3
- data/vendor/libgit2/include/git2/worktree.h +1 -0
- data/vendor/libgit2/src/CMakeLists.txt +77 -44
- data/vendor/libgit2/src/alloc.c +21 -8
- data/vendor/libgit2/src/allocators/failalloc.c +92 -0
- data/vendor/libgit2/src/allocators/failalloc.h +23 -0
- data/vendor/libgit2/src/allocators/stdalloc.c +41 -10
- data/vendor/libgit2/src/allocators/win32_leakcheck.c +118 -0
- data/vendor/libgit2/src/allocators/{win32_crtdbg.h → win32_leakcheck.h} +3 -3
- data/vendor/libgit2/src/annotated_commit.c +21 -9
- data/vendor/libgit2/src/apply.c +21 -8
- data/vendor/libgit2/src/array.h +11 -11
- data/vendor/libgit2/src/assert_safe.h +58 -0
- data/vendor/libgit2/src/attr.c +181 -74
- data/vendor/libgit2/src/attr_file.c +92 -42
- data/vendor/libgit2/src/attr_file.h +32 -11
- data/vendor/libgit2/src/attrcache.c +44 -40
- data/vendor/libgit2/src/attrcache.h +4 -5
- data/vendor/libgit2/src/blame.c +28 -15
- data/vendor/libgit2/src/blame_git.c +6 -3
- data/vendor/libgit2/src/blob.c +46 -24
- data/vendor/libgit2/src/branch.c +87 -37
- data/vendor/libgit2/src/buffer.c +339 -27
- data/vendor/libgit2/src/buffer.h +153 -2
- data/vendor/libgit2/src/cache.c +3 -24
- data/vendor/libgit2/src/cache.h +7 -7
- data/vendor/libgit2/src/cc-compat.h +10 -2
- data/vendor/libgit2/src/checkout.c +97 -98
- data/vendor/libgit2/src/cherrypick.c +8 -2
- data/vendor/libgit2/src/clone.c +104 -29
- data/vendor/libgit2/src/commit.c +41 -28
- data/vendor/libgit2/src/commit_graph.c +1209 -0
- data/vendor/libgit2/src/commit_graph.h +162 -0
- data/vendor/libgit2/src/commit_list.c +46 -0
- data/vendor/libgit2/src/commit_list.h +2 -0
- data/vendor/libgit2/src/common.h +26 -2
- data/vendor/libgit2/src/config.c +40 -22
- data/vendor/libgit2/src/config_cache.c +9 -4
- data/vendor/libgit2/src/config_entries.c +35 -27
- data/vendor/libgit2/src/config_file.c +25 -8
- data/vendor/libgit2/src/config_parse.c +5 -7
- data/vendor/libgit2/src/config_snapshot.c +2 -1
- data/vendor/libgit2/src/crlf.c +16 -6
- data/vendor/libgit2/src/date.c +4 -3
- data/vendor/libgit2/src/delta.c +1 -1
- data/vendor/libgit2/src/describe.c +11 -4
- data/vendor/libgit2/src/diff.c +23 -19
- data/vendor/libgit2/src/diff_driver.c +21 -17
- data/vendor/libgit2/src/diff_file.c +5 -7
- data/vendor/libgit2/src/diff_generate.c +56 -28
- data/vendor/libgit2/src/diff_parse.c +2 -3
- data/vendor/libgit2/src/diff_print.c +81 -65
- data/vendor/libgit2/src/diff_stats.c +19 -16
- data/vendor/libgit2/src/diff_tform.c +13 -13
- data/vendor/libgit2/src/diff_xdiff.c +4 -2
- data/vendor/libgit2/src/diff_xdiff.h +1 -1
- data/vendor/libgit2/src/errors.c +26 -19
- data/vendor/libgit2/src/features.h.in +5 -1
- data/vendor/libgit2/src/fetch.c +7 -2
- data/vendor/libgit2/src/fetchhead.c +8 -4
- data/vendor/libgit2/src/filebuf.c +9 -7
- data/vendor/libgit2/src/filter.c +209 -113
- data/vendor/libgit2/src/filter.h +24 -5
- data/vendor/libgit2/src/futils.c +8 -8
- data/vendor/libgit2/src/futils.h +4 -4
- data/vendor/libgit2/src/graph.c +64 -9
- data/vendor/libgit2/src/hash/sha1/collisiondetect.c +3 -3
- data/vendor/libgit2/src/hash/sha1/common_crypto.c +3 -3
- data/vendor/libgit2/src/hash/sha1/generic.h +1 -1
- data/vendor/libgit2/src/hash/sha1/mbedtls.c +12 -12
- data/vendor/libgit2/src/hash/sha1/openssl.c +3 -3
- data/vendor/libgit2/src/hash/sha1/sha1dc/sha1.c +0 -2
- data/vendor/libgit2/src/hash/sha1/win32.c +15 -11
- data/vendor/libgit2/src/hash.c +16 -13
- data/vendor/libgit2/src/hash.h +1 -1
- data/vendor/libgit2/src/hashsig.c +23 -10
- data/vendor/libgit2/src/ident.c +13 -3
- data/vendor/libgit2/src/idxmap.c +0 -22
- data/vendor/libgit2/src/ignore.c +35 -19
- data/vendor/libgit2/src/index.c +126 -84
- data/vendor/libgit2/src/index.h +1 -1
- data/vendor/libgit2/src/indexer.c +60 -36
- data/vendor/libgit2/src/integer.h +79 -2
- data/vendor/libgit2/src/iterator.c +40 -28
- data/vendor/libgit2/src/iterator.h +1 -1
- data/vendor/libgit2/src/khash.h +2 -11
- data/vendor/libgit2/src/{settings.c → libgit2.c} +125 -49
- data/vendor/libgit2/src/libgit2.h +15 -0
- data/vendor/libgit2/src/mailmap.c +23 -10
- data/vendor/libgit2/src/map.h +3 -3
- data/vendor/libgit2/src/merge.c +108 -46
- data/vendor/libgit2/src/merge.h +2 -1
- data/vendor/libgit2/src/merge_driver.c +19 -13
- data/vendor/libgit2/src/merge_file.c +15 -9
- data/vendor/libgit2/src/message.c +3 -1
- data/vendor/libgit2/src/midx.c +879 -0
- data/vendor/libgit2/src/midx.h +110 -0
- data/vendor/libgit2/src/mwindow.c +214 -95
- data/vendor/libgit2/src/mwindow.h +3 -3
- data/vendor/libgit2/src/net.c +133 -4
- data/vendor/libgit2/src/net.h +16 -2
- data/vendor/libgit2/src/netops.c +6 -4
- data/vendor/libgit2/src/netops.h +2 -2
- data/vendor/libgit2/src/notes.c +10 -10
- data/vendor/libgit2/src/object.c +24 -15
- data/vendor/libgit2/src/odb.c +298 -57
- data/vendor/libgit2/src/odb.h +16 -2
- data/vendor/libgit2/src/odb_loose.c +31 -21
- data/vendor/libgit2/src/odb_mempack.c +3 -1
- data/vendor/libgit2/src/odb_pack.c +391 -114
- data/vendor/libgit2/src/oid.c +7 -4
- data/vendor/libgit2/src/pack-objects.c +83 -69
- data/vendor/libgit2/src/pack.c +383 -150
- data/vendor/libgit2/src/pack.h +44 -9
- data/vendor/libgit2/src/patch.c +14 -7
- data/vendor/libgit2/src/patch_generate.c +3 -5
- data/vendor/libgit2/src/patch_parse.c +6 -3
- data/vendor/libgit2/src/path.c +102 -57
- data/vendor/libgit2/src/path.h +79 -6
- data/vendor/libgit2/src/pathspec.c +12 -11
- data/vendor/libgit2/src/pool.c +34 -22
- data/vendor/libgit2/src/pool.h +9 -1
- data/vendor/libgit2/src/posix.c +43 -12
- data/vendor/libgit2/src/posix.h +9 -0
- data/vendor/libgit2/src/proxy.c +2 -0
- data/vendor/libgit2/src/push.c +2 -0
- data/vendor/libgit2/src/reader.c +10 -6
- data/vendor/libgit2/src/rebase.c +95 -49
- data/vendor/libgit2/src/refdb.c +165 -13
- data/vendor/libgit2/src/refdb.h +69 -0
- data/vendor/libgit2/src/refdb_fs.c +144 -152
- data/vendor/libgit2/src/reflog.c +21 -20
- data/vendor/libgit2/src/refs.c +151 -231
- data/vendor/libgit2/src/refs.h +2 -20
- data/vendor/libgit2/src/refspec.c +80 -44
- data/vendor/libgit2/src/regexp.c +2 -2
- data/vendor/libgit2/src/remote.c +312 -121
- data/vendor/libgit2/src/remote.h +2 -1
- data/vendor/libgit2/src/repository.c +351 -189
- data/vendor/libgit2/src/repository.h +23 -29
- data/vendor/libgit2/src/reset.c +7 -6
- data/vendor/libgit2/src/revert.c +8 -2
- data/vendor/libgit2/src/revparse.c +19 -13
- data/vendor/libgit2/src/revwalk.c +35 -20
- data/vendor/libgit2/src/runtime.c +162 -0
- data/vendor/libgit2/src/runtime.h +62 -0
- data/vendor/libgit2/src/{refdb_fs.h → settings.h} +3 -11
- data/vendor/libgit2/src/signature.c +6 -5
- data/vendor/libgit2/src/sortedcache.c +2 -3
- data/vendor/libgit2/src/sortedcache.h +10 -8
- data/vendor/libgit2/src/stash.c +7 -3
- data/vendor/libgit2/src/status.c +9 -4
- data/vendor/libgit2/src/strarray.c +64 -0
- data/vendor/libgit2/src/streams/mbedtls.c +14 -17
- data/vendor/libgit2/src/streams/mbedtls.h +1 -1
- data/vendor/libgit2/src/streams/openssl.c +113 -207
- data/vendor/libgit2/src/streams/openssl.h +9 -1
- data/vendor/libgit2/src/streams/openssl_dynamic.c +309 -0
- data/vendor/libgit2/src/streams/openssl_dynamic.h +348 -0
- data/vendor/libgit2/src/streams/openssl_legacy.c +203 -0
- data/vendor/libgit2/src/streams/openssl_legacy.h +63 -0
- data/vendor/libgit2/src/streams/registry.c +10 -9
- data/vendor/libgit2/src/streams/socket.c +6 -2
- data/vendor/libgit2/src/streams/stransport.c +6 -3
- data/vendor/libgit2/src/streams/tls.c +5 -3
- data/vendor/libgit2/src/submodule.c +134 -66
- data/vendor/libgit2/src/submodule.h +9 -9
- data/vendor/libgit2/src/sysdir.c +8 -26
- data/vendor/libgit2/src/sysdir.h +0 -11
- data/vendor/libgit2/src/tag.c +49 -11
- data/vendor/libgit2/src/thread.c +140 -0
- data/vendor/libgit2/src/thread.h +479 -0
- data/vendor/libgit2/src/threadstate.c +83 -0
- data/vendor/libgit2/src/threadstate.h +24 -0
- data/vendor/libgit2/src/trace.c +2 -2
- data/vendor/libgit2/src/trace.h +17 -13
- data/vendor/libgit2/src/transaction.c +21 -9
- data/vendor/libgit2/src/transport.c +3 -3
- data/vendor/libgit2/src/transports/auth.c +1 -1
- data/vendor/libgit2/src/transports/auth_negotiate.c +11 -4
- data/vendor/libgit2/src/transports/auth_ntlm.c +10 -6
- data/vendor/libgit2/src/transports/credential.c +17 -7
- data/vendor/libgit2/src/transports/credential_helpers.c +2 -0
- data/vendor/libgit2/src/transports/git.c +1 -3
- data/vendor/libgit2/src/transports/http.c +19 -17
- data/vendor/libgit2/src/transports/http.h +1 -0
- data/vendor/libgit2/src/transports/httpclient.c +84 -42
- data/vendor/libgit2/src/transports/httpclient.h +1 -1
- data/vendor/libgit2/src/transports/local.c +5 -5
- data/vendor/libgit2/src/transports/smart.c +14 -9
- data/vendor/libgit2/src/transports/smart.h +1 -1
- data/vendor/libgit2/src/transports/smart_protocol.c +11 -5
- data/vendor/libgit2/src/transports/ssh.c +51 -17
- data/vendor/libgit2/src/transports/winhttp.c +156 -88
- data/vendor/libgit2/src/tree.c +100 -77
- data/vendor/libgit2/src/tree.h +1 -0
- data/vendor/libgit2/src/tsort.c +0 -2
- data/vendor/libgit2/src/unix/map.c +3 -1
- data/vendor/libgit2/src/unix/posix.h +16 -1
- data/vendor/libgit2/src/unix/pthread.h +2 -1
- data/vendor/libgit2/src/utf8.c +150 -0
- data/vendor/libgit2/src/utf8.h +52 -0
- data/vendor/libgit2/src/util.c +74 -183
- data/vendor/libgit2/src/util.h +33 -39
- data/vendor/libgit2/src/vector.c +23 -19
- data/vendor/libgit2/src/vector.h +4 -2
- data/vendor/libgit2/src/win32/findfile.c +4 -2
- data/vendor/libgit2/src/win32/git2.rc +18 -3
- data/vendor/libgit2/src/win32/map.c +1 -1
- data/vendor/libgit2/src/win32/msvc-compat.h +9 -1
- data/vendor/libgit2/src/win32/path_w32.c +23 -25
- data/vendor/libgit2/src/win32/path_w32.h +0 -1
- data/vendor/libgit2/src/win32/posix_w32.c +77 -1
- data/vendor/libgit2/src/win32/precompiled.h +0 -1
- data/vendor/libgit2/src/win32/reparse.h +4 -4
- data/vendor/libgit2/src/win32/thread.c +24 -15
- data/vendor/libgit2/src/win32/thread.h +1 -1
- data/vendor/libgit2/src/win32/w32_buffer.c +3 -3
- data/vendor/libgit2/src/win32/w32_common.h +18 -9
- data/vendor/libgit2/src/win32/{w32_crtdbg_stacktrace.c → w32_leakcheck.c} +269 -33
- data/vendor/libgit2/src/win32/w32_leakcheck.h +222 -0
- data/vendor/libgit2/src/win32/w32_util.h +6 -6
- data/vendor/libgit2/src/worktree.c +37 -15
- data/vendor/libgit2/src/zstream.c +1 -1
- metadata +56 -38
- data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.c.in +0 -29
- data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.cmake +0 -96
- data/vendor/libgit2/src/allocators/win32_crtdbg.c +0 -118
- data/vendor/libgit2/src/buf_text.c +0 -316
- data/vendor/libgit2/src/buf_text.h +0 -122
- data/vendor/libgit2/src/global.c +0 -361
- data/vendor/libgit2/src/global.h +0 -41
- data/vendor/libgit2/src/thread-utils.c +0 -58
- data/vendor/libgit2/src/thread-utils.h +0 -246
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +0 -127
- data/vendor/libgit2/src/win32/w32_stack.c +0 -188
- data/vendor/libgit2/src/win32/w32_stack.h +0 -140
|
@@ -26,18 +26,18 @@ typedef struct _GIT_REPARSE_DATA_BUFFER {
|
|
|
26
26
|
USHORT PrintNameLength;
|
|
27
27
|
ULONG Flags;
|
|
28
28
|
WCHAR PathBuffer[1];
|
|
29
|
-
}
|
|
29
|
+
} SymbolicLink;
|
|
30
30
|
struct {
|
|
31
31
|
USHORT SubstituteNameOffset;
|
|
32
32
|
USHORT SubstituteNameLength;
|
|
33
33
|
USHORT PrintNameOffset;
|
|
34
34
|
USHORT PrintNameLength;
|
|
35
35
|
WCHAR PathBuffer[1];
|
|
36
|
-
}
|
|
36
|
+
} MountPoint;
|
|
37
37
|
struct {
|
|
38
38
|
UCHAR DataBuffer[1];
|
|
39
|
-
}
|
|
40
|
-
};
|
|
39
|
+
} Generic;
|
|
40
|
+
} ReparseBuffer;
|
|
41
41
|
} GIT_REPARSE_DATA_BUFFER;
|
|
42
42
|
|
|
43
43
|
#define REPARSE_DATA_HEADER_SIZE 8
|
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
#include "thread.h"
|
|
9
|
-
|
|
10
|
-
#include "../global.h"
|
|
9
|
+
#include "runtime.h"
|
|
11
10
|
|
|
12
11
|
#define CLEAN_THREAD_EXIT 0x6F012842
|
|
13
12
|
|
|
@@ -19,6 +18,8 @@ static win32_srwlock_fn win32_srwlock_release_shared;
|
|
|
19
18
|
static win32_srwlock_fn win32_srwlock_acquire_exclusive;
|
|
20
19
|
static win32_srwlock_fn win32_srwlock_release_exclusive;
|
|
21
20
|
|
|
21
|
+
static DWORD fls_index;
|
|
22
|
+
|
|
22
23
|
/* The thread procedure stub used to invoke the caller's procedure
|
|
23
24
|
* and capture the return value for later collection. Windows will
|
|
24
25
|
* only hold a DWORD, but we need to be able to store an entire
|
|
@@ -28,14 +29,19 @@ static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter)
|
|
|
28
29
|
git_thread *thread = lpParameter;
|
|
29
30
|
|
|
30
31
|
/* Set the current thread for `git_thread_exit` */
|
|
31
|
-
|
|
32
|
+
FlsSetValue(fls_index, thread);
|
|
32
33
|
|
|
33
34
|
thread->result = thread->proc(thread->param);
|
|
34
35
|
|
|
35
36
|
return CLEAN_THREAD_EXIT;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
static void git_threads_global_shutdown(void)
|
|
40
|
+
{
|
|
41
|
+
FlsFree(fls_index);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
int git_threads_global_init(void)
|
|
39
45
|
{
|
|
40
46
|
HMODULE hModule = GetModuleHandleW(L"kernel32");
|
|
41
47
|
|
|
@@ -52,7 +58,10 @@ int git_threads_init(void)
|
|
|
52
58
|
GetProcAddress(hModule, "ReleaseSRWLockExclusive");
|
|
53
59
|
}
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
if ((fls_index = FlsAlloc(NULL)) == FLS_OUT_OF_INDEXES)
|
|
62
|
+
return -1;
|
|
63
|
+
|
|
64
|
+
return git_runtime_shutdown_register(git_threads_global_shutdown);
|
|
56
65
|
}
|
|
57
66
|
|
|
58
67
|
int git_thread_create(
|
|
@@ -85,10 +94,7 @@ int git_thread_join(
|
|
|
85
94
|
|
|
86
95
|
/* Check for the thread having exited uncleanly. If exit was unclean,
|
|
87
96
|
* then we don't have a return value to give back to the caller. */
|
|
88
|
-
|
|
89
|
-
assert(false);
|
|
90
|
-
thread->result = NULL;
|
|
91
|
-
}
|
|
97
|
+
GIT_ASSERT(exit == CLEAN_THREAD_EXIT);
|
|
92
98
|
|
|
93
99
|
if (value_ptr)
|
|
94
100
|
*value_ptr = thread->result;
|
|
@@ -99,8 +105,11 @@ int git_thread_join(
|
|
|
99
105
|
|
|
100
106
|
void git_thread_exit(void *value)
|
|
101
107
|
{
|
|
102
|
-
|
|
103
|
-
|
|
108
|
+
git_thread *thread = FlsGetValue(fls_index);
|
|
109
|
+
|
|
110
|
+
if (thread)
|
|
111
|
+
thread->result = value;
|
|
112
|
+
|
|
104
113
|
ExitThread(CLEAN_THREAD_EXIT);
|
|
105
114
|
}
|
|
106
115
|
|
|
@@ -137,7 +146,7 @@ int git_cond_init(git_cond *cond)
|
|
|
137
146
|
{
|
|
138
147
|
/* This is an auto-reset event. */
|
|
139
148
|
*cond = CreateEventW(NULL, FALSE, FALSE, NULL);
|
|
140
|
-
|
|
149
|
+
GIT_ASSERT(*cond);
|
|
141
150
|
|
|
142
151
|
/* If we can't create the event, claim that the reason was out-of-memory.
|
|
143
152
|
* The actual reason can be fetched with GetLastError(). */
|
|
@@ -152,7 +161,7 @@ int git_cond_free(git_cond *cond)
|
|
|
152
161
|
return EINVAL;
|
|
153
162
|
|
|
154
163
|
closed = CloseHandle(*cond);
|
|
155
|
-
|
|
164
|
+
GIT_ASSERT(closed);
|
|
156
165
|
GIT_UNUSED(closed);
|
|
157
166
|
|
|
158
167
|
*cond = NULL;
|
|
@@ -174,7 +183,7 @@ int git_cond_wait(git_cond *cond, git_mutex *mutex)
|
|
|
174
183
|
return error;
|
|
175
184
|
|
|
176
185
|
wait_result = WaitForSingleObject(*cond, INFINITE);
|
|
177
|
-
|
|
186
|
+
GIT_ASSERT(WAIT_OBJECT_0 == wait_result);
|
|
178
187
|
GIT_UNUSED(wait_result);
|
|
179
188
|
|
|
180
189
|
return git_mutex_lock(mutex);
|
|
@@ -188,7 +197,7 @@ int git_cond_signal(git_cond *cond)
|
|
|
188
197
|
return EINVAL;
|
|
189
198
|
|
|
190
199
|
signaled = SetEvent(*cond);
|
|
191
|
-
|
|
200
|
+
GIT_ASSERT(signaled);
|
|
192
201
|
GIT_UNUSED(signaled);
|
|
193
202
|
|
|
194
203
|
return 0;
|
|
@@ -32,13 +32,13 @@ int git_buf_put_w(git_buf *buf, const wchar_t *string_w, size_t len_w)
|
|
|
32
32
|
return -1;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
GIT_ASSERT(string_w);
|
|
36
36
|
|
|
37
37
|
/* Measure the string necessary for conversion */
|
|
38
38
|
if ((utf8_len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, string_w, (int)len_w, NULL, 0, NULL, NULL)) == 0)
|
|
39
39
|
return 0;
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
GIT_ASSERT(utf8_len > 0);
|
|
42
42
|
|
|
43
43
|
GIT_ERROR_CHECK_ALLOC_ADD(&new_size, buf->size, (size_t)utf8_len);
|
|
44
44
|
GIT_ERROR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
|
|
@@ -50,7 +50,7 @@ int git_buf_put_w(git_buf *buf, const wchar_t *string_w, size_t len_w)
|
|
|
50
50
|
CP_UTF8, WC_ERR_INVALID_CHARS, string_w, (int)len_w, &buf->ptr[buf->size], utf8_len, NULL, NULL)) == 0)
|
|
51
51
|
return handle_wc_error();
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
GIT_ASSERT(utf8_write_len == utf8_len);
|
|
54
54
|
|
|
55
55
|
buf->size += utf8_write_len;
|
|
56
56
|
buf->ptr[buf->size] = '\0';
|
|
@@ -8,24 +8,33 @@
|
|
|
8
8
|
#ifndef INCLUDE_win32_w32_common_h__
|
|
9
9
|
#define INCLUDE_win32_w32_common_h__
|
|
10
10
|
|
|
11
|
+
#include <git2/common.h>
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* 4096 is the max allowed Git path. `MAX_PATH` (260) is the typical max allowed
|
|
15
|
+
* Windows path length, however win32 Unicode APIs generally allow up to 32,767
|
|
16
|
+
* if prefixed with "\\?\" (i.e. converted to an NT-style name).
|
|
17
|
+
*/
|
|
18
|
+
#define GIT_WIN_PATH_MAX GIT_PATH_MAX
|
|
19
|
+
|
|
11
20
|
/*
|
|
12
|
-
* Provides a large enough buffer to support Windows paths:
|
|
13
|
-
*
|
|
14
|
-
* NULL terminator. Prefixing with "\\?\" adds 4 characters,
|
|
15
|
-
* original was a UNC path, then we turn "\\server\share" into
|
|
21
|
+
* Provides a large enough buffer to support Windows Git paths:
|
|
22
|
+
* GIT_WIN_PATH_MAX is 4096, corresponding to a maximum path length of 4095
|
|
23
|
+
* characters plus a NULL terminator. Prefixing with "\\?\" adds 4 characters,
|
|
24
|
+
* but if the original was a UNC path, then we turn "\\server\share" into
|
|
16
25
|
* "\\?\UNC\server\share". So we replace the first two characters with
|
|
17
|
-
* 8 characters, a net gain of 6, so the maximum length is
|
|
26
|
+
* 8 characters, a net gain of 6, so the maximum length is GIT_WIN_PATH_MAX+6.
|
|
18
27
|
*/
|
|
19
|
-
#define GIT_WIN_PATH_UTF16
|
|
28
|
+
#define GIT_WIN_PATH_UTF16 GIT_WIN_PATH_MAX+6
|
|
20
29
|
|
|
21
|
-
/* Maximum size of a UTF-8 Win32 path. We remove the "\\?\" or "\\?\UNC\"
|
|
22
|
-
* prefixes for presentation, bringing us back to
|
|
30
|
+
/* Maximum size of a UTF-8 Win32 Git path. We remove the "\\?\" or "\\?\UNC\"
|
|
31
|
+
* prefixes for presentation, bringing us back to 4095 (non-NULL)
|
|
23
32
|
* characters. UTF-8 does have 4-byte sequences, but they are encoded in
|
|
24
33
|
* UTF-16 using surrogate pairs, which takes up the space of two characters.
|
|
25
34
|
* Two characters in the range U+0800 -> U+FFFF take up more space in UTF-8
|
|
26
35
|
* (6 bytes) than one surrogate pair (4 bytes).
|
|
27
36
|
*/
|
|
28
|
-
#define GIT_WIN_PATH_UTF8 (
|
|
37
|
+
#define GIT_WIN_PATH_UTF8 ((GIT_WIN_PATH_MAX - 1) * 3 + 1)
|
|
29
38
|
|
|
30
39
|
/*
|
|
31
40
|
* The length of a Windows "shortname", for 8.3 compatibility.
|
|
@@ -5,12 +5,203 @@
|
|
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
#include "
|
|
8
|
+
#include "w32_leakcheck.h"
|
|
9
9
|
|
|
10
|
-
#if defined(
|
|
11
|
-
#include "w32_stack.h"
|
|
10
|
+
#if defined(GIT_WIN32_LEAKCHECK)
|
|
12
11
|
|
|
13
|
-
#
|
|
12
|
+
#include "Windows.h"
|
|
13
|
+
#include "Dbghelp.h"
|
|
14
|
+
#include "win32/posix.h"
|
|
15
|
+
#include "hash.h"
|
|
16
|
+
#include "runtime.h"
|
|
17
|
+
|
|
18
|
+
/* Stack frames (for stack tracing, below) */
|
|
19
|
+
|
|
20
|
+
static bool g_win32_stack_initialized = false;
|
|
21
|
+
static HANDLE g_win32_stack_process = INVALID_HANDLE_VALUE;
|
|
22
|
+
static git_win32_leakcheck_stack_aux_cb_alloc g_aux_cb_alloc = NULL;
|
|
23
|
+
static git_win32_leakcheck_stack_aux_cb_lookup g_aux_cb_lookup = NULL;
|
|
24
|
+
|
|
25
|
+
int git_win32_leakcheck_stack_set_aux_cb(
|
|
26
|
+
git_win32_leakcheck_stack_aux_cb_alloc cb_alloc,
|
|
27
|
+
git_win32_leakcheck_stack_aux_cb_lookup cb_lookup)
|
|
28
|
+
{
|
|
29
|
+
g_aux_cb_alloc = cb_alloc;
|
|
30
|
+
g_aux_cb_lookup = cb_lookup;
|
|
31
|
+
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Load symbol table data. This should be done in the primary
|
|
37
|
+
* thread at startup (under a lock if there are other threads
|
|
38
|
+
* active).
|
|
39
|
+
*/
|
|
40
|
+
void git_win32_leakcheck_stack_init(void)
|
|
41
|
+
{
|
|
42
|
+
if (!g_win32_stack_initialized) {
|
|
43
|
+
g_win32_stack_process = GetCurrentProcess();
|
|
44
|
+
SymSetOptions(SYMOPT_LOAD_LINES);
|
|
45
|
+
SymInitialize(g_win32_stack_process, NULL, TRUE);
|
|
46
|
+
g_win32_stack_initialized = true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Cleanup symbol table data. This should be done in the
|
|
52
|
+
* primary thead at shutdown (under a lock if there are other
|
|
53
|
+
* threads active).
|
|
54
|
+
*/
|
|
55
|
+
void git_win32_leakcheck_stack_cleanup(void)
|
|
56
|
+
{
|
|
57
|
+
if (g_win32_stack_initialized) {
|
|
58
|
+
SymCleanup(g_win32_stack_process);
|
|
59
|
+
g_win32_stack_process = INVALID_HANDLE_VALUE;
|
|
60
|
+
g_win32_stack_initialized = false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
int git_win32_leakcheck_stack_capture(git_win32_leakcheck_stack_raw_data *pdata, int skip)
|
|
65
|
+
{
|
|
66
|
+
if (!g_win32_stack_initialized) {
|
|
67
|
+
git_error_set(GIT_ERROR_INVALID, "git_win32_stack not initialized.");
|
|
68
|
+
return GIT_ERROR;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
memset(pdata, 0, sizeof(*pdata));
|
|
72
|
+
pdata->nr_frames = RtlCaptureStackBackTrace(
|
|
73
|
+
skip+1, GIT_WIN32_LEAKCHECK_STACK_MAX_FRAMES, pdata->frames, NULL);
|
|
74
|
+
|
|
75
|
+
/* If an "aux" data provider was registered, ask it to capture
|
|
76
|
+
* whatever data it needs and give us an "aux_id" to it so that
|
|
77
|
+
* we can refer to it later when reporting.
|
|
78
|
+
*/
|
|
79
|
+
if (g_aux_cb_alloc)
|
|
80
|
+
(g_aux_cb_alloc)(&pdata->aux_id);
|
|
81
|
+
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
int git_win32_leakcheck_stack_compare(
|
|
86
|
+
git_win32_leakcheck_stack_raw_data *d1,
|
|
87
|
+
git_win32_leakcheck_stack_raw_data *d2)
|
|
88
|
+
{
|
|
89
|
+
return memcmp(d1, d2, sizeof(*d1));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
int git_win32_leakcheck_stack_format(
|
|
93
|
+
char *pbuf, size_t buf_len,
|
|
94
|
+
const git_win32_leakcheck_stack_raw_data *pdata,
|
|
95
|
+
const char *prefix, const char *suffix)
|
|
96
|
+
{
|
|
97
|
+
#define MY_MAX_FILENAME 255
|
|
98
|
+
|
|
99
|
+
/* SYMBOL_INFO has char FileName[1] at the end. The docs say to
|
|
100
|
+
* to malloc it with extra space for your desired max filename.
|
|
101
|
+
*/
|
|
102
|
+
struct {
|
|
103
|
+
SYMBOL_INFO symbol;
|
|
104
|
+
char extra[MY_MAX_FILENAME + 1];
|
|
105
|
+
} s;
|
|
106
|
+
|
|
107
|
+
IMAGEHLP_LINE64 line;
|
|
108
|
+
size_t buf_used = 0;
|
|
109
|
+
unsigned int k;
|
|
110
|
+
char detail[MY_MAX_FILENAME * 2]; /* filename plus space for function name and formatting */
|
|
111
|
+
size_t detail_len;
|
|
112
|
+
|
|
113
|
+
if (!g_win32_stack_initialized) {
|
|
114
|
+
git_error_set(GIT_ERROR_INVALID, "git_win32_stack not initialized.");
|
|
115
|
+
return GIT_ERROR;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!prefix)
|
|
119
|
+
prefix = "\t";
|
|
120
|
+
if (!suffix)
|
|
121
|
+
suffix = "\n";
|
|
122
|
+
|
|
123
|
+
memset(pbuf, 0, buf_len);
|
|
124
|
+
|
|
125
|
+
memset(&s, 0, sizeof(s));
|
|
126
|
+
s.symbol.MaxNameLen = MY_MAX_FILENAME;
|
|
127
|
+
s.symbol.SizeOfStruct = sizeof(SYMBOL_INFO);
|
|
128
|
+
|
|
129
|
+
memset(&line, 0, sizeof(line));
|
|
130
|
+
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
|
131
|
+
|
|
132
|
+
for (k=0; k < pdata->nr_frames; k++) {
|
|
133
|
+
DWORD64 frame_k = (DWORD64)pdata->frames[k];
|
|
134
|
+
DWORD dwUnused;
|
|
135
|
+
|
|
136
|
+
if (SymFromAddr(g_win32_stack_process, frame_k, 0, &s.symbol) &&
|
|
137
|
+
SymGetLineFromAddr64(g_win32_stack_process, frame_k, &dwUnused, &line)) {
|
|
138
|
+
const char *pslash;
|
|
139
|
+
const char *pfile;
|
|
140
|
+
|
|
141
|
+
pslash = strrchr(line.FileName, '\\');
|
|
142
|
+
pfile = ((pslash) ? (pslash+1) : line.FileName);
|
|
143
|
+
p_snprintf(detail, sizeof(detail), "%s%s:%d> %s%s",
|
|
144
|
+
prefix, pfile, line.LineNumber, s.symbol.Name, suffix);
|
|
145
|
+
} else {
|
|
146
|
+
/* This happens when we cross into another module.
|
|
147
|
+
* For example, in CLAR tests, this is typically
|
|
148
|
+
* the CRT startup code. Just print an unknown
|
|
149
|
+
* frame and continue.
|
|
150
|
+
*/
|
|
151
|
+
p_snprintf(detail, sizeof(detail), "%s??%s", prefix, suffix);
|
|
152
|
+
}
|
|
153
|
+
detail_len = strlen(detail);
|
|
154
|
+
|
|
155
|
+
if (buf_len < (buf_used + detail_len + 1)) {
|
|
156
|
+
/* we don't have room for this frame in the buffer, so just stop. */
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
memcpy(&pbuf[buf_used], detail, detail_len);
|
|
161
|
+
buf_used += detail_len;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* "aux_id" 0 is reserved to mean no aux data. This is needed to handle
|
|
165
|
+
* allocs that occur before the aux callbacks were registered.
|
|
166
|
+
*/
|
|
167
|
+
if (pdata->aux_id > 0) {
|
|
168
|
+
p_snprintf(detail, sizeof(detail), "%saux_id: %d%s",
|
|
169
|
+
prefix, pdata->aux_id, suffix);
|
|
170
|
+
detail_len = strlen(detail);
|
|
171
|
+
if ((buf_used + detail_len + 1) < buf_len) {
|
|
172
|
+
memcpy(&pbuf[buf_used], detail, detail_len);
|
|
173
|
+
buf_used += detail_len;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* If an "aux" data provider is still registered, ask it to append its detailed
|
|
177
|
+
* data to the end of ours using the "aux_id" it gave us when this de-duped
|
|
178
|
+
* item was created.
|
|
179
|
+
*/
|
|
180
|
+
if (g_aux_cb_lookup)
|
|
181
|
+
(g_aux_cb_lookup)(pdata->aux_id, &pbuf[buf_used], (buf_len - buf_used - 1));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return GIT_OK;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
int git_win32_leakcheck_stack(
|
|
188
|
+
char * pbuf, size_t buf_len,
|
|
189
|
+
int skip,
|
|
190
|
+
const char *prefix, const char *suffix)
|
|
191
|
+
{
|
|
192
|
+
git_win32_leakcheck_stack_raw_data data;
|
|
193
|
+
int error;
|
|
194
|
+
|
|
195
|
+
if ((error = git_win32_leakcheck_stack_capture(&data, skip)) < 0)
|
|
196
|
+
return error;
|
|
197
|
+
if ((error = git_win32_leakcheck_stack_format(pbuf, buf_len, &data, prefix, suffix)) < 0)
|
|
198
|
+
return error;
|
|
199
|
+
return 0;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* Strack tracing */
|
|
203
|
+
|
|
204
|
+
#define STACKTRACE_UID_LEN (15)
|
|
14
205
|
|
|
15
206
|
/**
|
|
16
207
|
* The stacktrace of an allocation can be distilled
|
|
@@ -20,20 +211,20 @@
|
|
|
20
211
|
* give to the CRT malloc routines.
|
|
21
212
|
*/
|
|
22
213
|
typedef struct {
|
|
23
|
-
char uid[
|
|
24
|
-
}
|
|
214
|
+
char uid[STACKTRACE_UID_LEN + 1];
|
|
215
|
+
} git_win32_leakcheck_stacktrace_uid;
|
|
25
216
|
|
|
26
217
|
/**
|
|
27
218
|
* All mallocs with the same stacktrace will be de-duped
|
|
28
219
|
* and aggregated into this row.
|
|
29
220
|
*/
|
|
30
221
|
typedef struct {
|
|
31
|
-
|
|
32
|
-
|
|
222
|
+
git_win32_leakcheck_stacktrace_uid uid; /* must be first */
|
|
223
|
+
git_win32_leakcheck_stack_raw_data raw_data;
|
|
33
224
|
unsigned int count_allocs; /* times this alloc signature seen since init */
|
|
34
225
|
unsigned int count_allocs_at_last_checkpoint; /* times since last mark */
|
|
35
226
|
unsigned int transient_count_leaks; /* sum of leaks */
|
|
36
|
-
}
|
|
227
|
+
} git_win32_leakcheck_stacktrace_row;
|
|
37
228
|
|
|
38
229
|
static CRITICAL_SECTION g_crtdbg_stacktrace_cs;
|
|
39
230
|
|
|
@@ -57,9 +248,9 @@ static CRITICAL_SECTION g_crtdbg_stacktrace_cs;
|
|
|
57
248
|
* it and try again.
|
|
58
249
|
*/
|
|
59
250
|
|
|
60
|
-
#define MY_ROW_LIMIT (1024 * 1024)
|
|
61
|
-
static
|
|
62
|
-
static
|
|
251
|
+
#define MY_ROW_LIMIT (2 * 1024 * 1024)
|
|
252
|
+
static git_win32_leakcheck_stacktrace_row g_cs_rows[MY_ROW_LIMIT];
|
|
253
|
+
static git_win32_leakcheck_stacktrace_row *g_cs_index[MY_ROW_LIMIT];
|
|
63
254
|
|
|
64
255
|
static unsigned int g_cs_end = MY_ROW_LIMIT;
|
|
65
256
|
static unsigned int g_cs_ins = 0; /* insertion point == unique allocs seen */
|
|
@@ -76,18 +267,18 @@ static bool g_transient_leaks_since_mark = false; /* payload for hook */
|
|
|
76
267
|
*/
|
|
77
268
|
static int row_cmp(const void *v1, const void *v2)
|
|
78
269
|
{
|
|
79
|
-
|
|
80
|
-
|
|
270
|
+
git_win32_leakcheck_stack_raw_data *d1 = (git_win32_leakcheck_stack_raw_data*)v1;
|
|
271
|
+
git_win32_leakcheck_stacktrace_row *r2 = (git_win32_leakcheck_stacktrace_row *)v2;
|
|
81
272
|
|
|
82
|
-
return (
|
|
273
|
+
return (git_win32_leakcheck_stack_compare(d1, &r2->raw_data));
|
|
83
274
|
}
|
|
84
275
|
|
|
85
276
|
/**
|
|
86
277
|
* Unique insert the new data into the row and index tables.
|
|
87
278
|
* We have to sort by the stackframe data itself, not the uid.
|
|
88
279
|
*/
|
|
89
|
-
static
|
|
90
|
-
const
|
|
280
|
+
static git_win32_leakcheck_stacktrace_row * insert_unique(
|
|
281
|
+
const git_win32_leakcheck_stack_raw_data *pdata)
|
|
91
282
|
{
|
|
92
283
|
size_t pos;
|
|
93
284
|
if (git__bsearch(g_cs_index, g_cs_ins, pdata, row_cmp, &pos) < 0) {
|
|
@@ -206,7 +397,7 @@ static void dump_summary(const char *label)
|
|
|
206
397
|
g_cs_rows[k].count_allocs);
|
|
207
398
|
my_output(buf);
|
|
208
399
|
|
|
209
|
-
if (
|
|
400
|
+
if (git_win32_leakcheck_stack_format(
|
|
210
401
|
buf, sizeof(buf), &g_cs_rows[k].raw_data,
|
|
211
402
|
NULL, NULL) >= 0) {
|
|
212
403
|
my_output(buf);
|
|
@@ -219,7 +410,11 @@ static void dump_summary(const char *label)
|
|
|
219
410
|
fflush(stderr);
|
|
220
411
|
}
|
|
221
412
|
|
|
222
|
-
|
|
413
|
+
/**
|
|
414
|
+
* Initialize our memory leak tracking and de-dup data structures.
|
|
415
|
+
* This should ONLY be called by git_libgit2_init().
|
|
416
|
+
*/
|
|
417
|
+
void git_win32_leakcheck_stacktrace_init(void)
|
|
223
418
|
{
|
|
224
419
|
InitializeCriticalSection(&g_crtdbg_stacktrace_cs);
|
|
225
420
|
|
|
@@ -238,8 +433,8 @@ void git_win32__crtdbg_stacktrace_init(void)
|
|
|
238
433
|
LeaveCriticalSection(&g_crtdbg_stacktrace_cs);
|
|
239
434
|
}
|
|
240
435
|
|
|
241
|
-
int
|
|
242
|
-
|
|
436
|
+
int git_win32_leakcheck_stacktrace_dump(
|
|
437
|
+
git_win32_leakcheck_stacktrace_options opt,
|
|
243
438
|
const char *label)
|
|
244
439
|
{
|
|
245
440
|
_CRT_REPORT_HOOK old;
|
|
@@ -248,10 +443,10 @@ int git_win32__crtdbg_stacktrace__dump(
|
|
|
248
443
|
|
|
249
444
|
#define IS_BIT_SET(o,b) (((o) & (b)) != 0)
|
|
250
445
|
|
|
251
|
-
bool b_set_mark = IS_BIT_SET(opt,
|
|
252
|
-
bool b_leaks_since_mark = IS_BIT_SET(opt,
|
|
253
|
-
bool b_leaks_total = IS_BIT_SET(opt,
|
|
254
|
-
bool b_quiet = IS_BIT_SET(opt,
|
|
446
|
+
bool b_set_mark = IS_BIT_SET(opt, GIT_WIN32_LEAKCHECK_STACKTRACE_SET_MARK);
|
|
447
|
+
bool b_leaks_since_mark = IS_BIT_SET(opt, GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK);
|
|
448
|
+
bool b_leaks_total = IS_BIT_SET(opt, GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_TOTAL);
|
|
449
|
+
bool b_quiet = IS_BIT_SET(opt, GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET);
|
|
255
450
|
|
|
256
451
|
if (b_leaks_since_mark && b_leaks_total) {
|
|
257
452
|
git_error_set(GIT_ERROR_INVALID, "cannot combine LEAKS_SINCE_MARK and LEAKS_TOTAL.");
|
|
@@ -301,29 +496,44 @@ int git_win32__crtdbg_stacktrace__dump(
|
|
|
301
496
|
return r;
|
|
302
497
|
}
|
|
303
498
|
|
|
304
|
-
|
|
499
|
+
/**
|
|
500
|
+
* Shutdown our memory leak tracking and dump summary data.
|
|
501
|
+
* This should ONLY be called by git_libgit2_shutdown().
|
|
502
|
+
*
|
|
503
|
+
* We explicitly call _CrtDumpMemoryLeaks() during here so
|
|
504
|
+
* that we can compute summary data for the leaks. We print
|
|
505
|
+
* the stacktrace of each unique leak.
|
|
506
|
+
*
|
|
507
|
+
* This cleanup does not happen if the app calls exit()
|
|
508
|
+
* without calling the libgit2 shutdown code.
|
|
509
|
+
*
|
|
510
|
+
* This info we print here is independent of any automatic
|
|
511
|
+
* reporting during exit() caused by _CRTDBG_LEAK_CHECK_DF.
|
|
512
|
+
* Set it in your app if you also want traditional reporting.
|
|
513
|
+
*/
|
|
514
|
+
void git_win32_leakcheck_stacktrace_cleanup(void)
|
|
305
515
|
{
|
|
306
|
-
/* At shutdown/cleanup, dump
|
|
516
|
+
/* At shutdown/cleanup, dump cumulative leak info
|
|
307
517
|
* with everything since startup. This might generate
|
|
308
518
|
* extra noise if the caller has been doing checkpoint
|
|
309
519
|
* dumps, but it might also eliminate some false
|
|
310
520
|
* positives for resources previously reported during
|
|
311
521
|
* checkpoints.
|
|
312
522
|
*/
|
|
313
|
-
|
|
314
|
-
|
|
523
|
+
git_win32_leakcheck_stacktrace_dump(
|
|
524
|
+
GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_TOTAL,
|
|
315
525
|
"CLEANUP");
|
|
316
526
|
|
|
317
527
|
DeleteCriticalSection(&g_crtdbg_stacktrace_cs);
|
|
318
528
|
}
|
|
319
529
|
|
|
320
|
-
const char *
|
|
530
|
+
const char *git_win32_leakcheck_stacktrace(int skip, const char *file)
|
|
321
531
|
{
|
|
322
|
-
|
|
323
|
-
|
|
532
|
+
git_win32_leakcheck_stack_raw_data new_data;
|
|
533
|
+
git_win32_leakcheck_stacktrace_row *row;
|
|
324
534
|
const char * result = file;
|
|
325
535
|
|
|
326
|
-
if (
|
|
536
|
+
if (git_win32_leakcheck_stack_capture(&new_data, skip+1) < 0)
|
|
327
537
|
return result;
|
|
328
538
|
|
|
329
539
|
EnterCriticalSection(&g_crtdbg_stacktrace_cs);
|
|
@@ -342,4 +552,30 @@ const char *git_win32__crtdbg_stacktrace(int skip, const char *file)
|
|
|
342
552
|
return result;
|
|
343
553
|
}
|
|
344
554
|
|
|
555
|
+
static void git_win32_leakcheck_global_shutdown(void)
|
|
556
|
+
{
|
|
557
|
+
git_win32_leakcheck_stacktrace_cleanup();
|
|
558
|
+
git_win32_leakcheck_stack_cleanup();
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
bool git_win32_leakcheck_has_leaks(void)
|
|
562
|
+
{
|
|
563
|
+
return (g_transient_count_total_leaks > 0);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
int git_win32_leakcheck_global_init(void)
|
|
567
|
+
{
|
|
568
|
+
git_win32_leakcheck_stacktrace_init();
|
|
569
|
+
git_win32_leakcheck_stack_init();
|
|
570
|
+
|
|
571
|
+
return git_runtime_shutdown_register(git_win32_leakcheck_global_shutdown);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
#else
|
|
575
|
+
|
|
576
|
+
int git_win32_leakcheck_global_init(void)
|
|
577
|
+
{
|
|
578
|
+
return 0;
|
|
579
|
+
}
|
|
580
|
+
|
|
345
581
|
#endif
|