-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Reproduction steps
The Rust program here reliably reproduces the issue on my system when run against a directory with 32 copies of a large repository (I used the rust repository).
The program spawns a thread for each repository which opens the repository and calls git_status_list_new.
Reducing the number of threads or the size of the repositories seems to prevent the issue occurring.
fn main() {
let join_handles: Vec<thread::JoinHandle<()>> =
std::fs::read_dir(std::env::args_os().nth(1).expect("expected argument"))
.unwrap()
.map(|entry| std::thread::spawn(|| get_status(entry.unwrap().path())))
.collect();
for handle in join_handles {
handle.join().unwrap();
}
}
fn get_status(path: PathBuf) {
let repo = git2::Repository::open(path).unwrap();
let _ = repo.statuses(None).unwrap();
}
Expected behavior
Success (or possibly an resouce exhaustion error?)
Actual behavior
The program crashes with (exit code: 0xc0000374, STATUS_HEAP_CORRUPTION). The stack trace of the failing thread:
mgit-crash-repro.exe!git_mwindow_close_lru_window() Line 269 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\mwindow.c:269)
mgit-crash-repro.exe!new_window(int fd, __int64 size, __int64 offset) Line 336 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\mwindow.c:336)
mgit-crash-repro.exe!git_mwindow_open(git_mwindow_file * mwf, git_mwindow * * cursor, __int64 offset, unsigned __int64 extra, unsigned int * left) Line 407 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\mwindow.c:407)
mgit-crash-repro.exe!git_packfile_unpack_header(unsigned __int64 * size_p, git_object_t * type_p, git_mwindow_file * mwf, git_mwindow * * w_curs, __int64 * curpos) Line 455 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\pack.c:455)
mgit-crash-repro.exe!pack_dependency_chain(git_dependency_chain * chain_out, git_pack_cache_entry * * cached_out, __int64 * cached_off, pack_chain_elem * small_stack, unsigned __int64 * stack_sz, git_pack_file * p, __int64 obj_offset) Line 581 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\pack.c:581)
mgit-crash-repro.exe!git_packfile_unpack(git_rawobj * obj, git_pack_file * p, __int64 * obj_offset) Line 637 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\pack.c:637)
mgit-crash-repro.exe!pack_backend__read(void * * buffer_p, unsigned __int64 * len_p, git_object_t * type_p, git_odb_backend * backend, const git_oid * oid) Line 399 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\odb_pack.c:399)
mgit-crash-repro.exe!odb_read_1(git_odb_object * * out, git_odb * db, const git_oid * id, unsigned char only_refreshed) Line 1065 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\odb.c:1065)
mgit-crash-repro.exe!git_odb_read(git_odb_object * * out, git_odb * db, const git_oid * id) Line 1116 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\odb.c:1116)
mgit-crash-repro.exe!git_object_lookup_prefix(git_object * * object_out, git_repository * repo, const git_oid * id, unsigned __int64 len, git_object_t type) Line 222 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\object.c:222)
mgit-crash-repro.exe!git_object_lookup(git_object * * object_out, git_repository * repo, const git_oid * id, git_object_t type) Line 254 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\object.c:254)
mgit-crash-repro.exe!git_tree_lookup(git_tree * * out, git_repository * repo, const git_oid * id) Line 57 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\object_api.c:57)
mgit-crash-repro.exe!tree_iterator_frame_push(tree_iterator * iter, tree_iterator_entry * entry) Line 661 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\iterator.c:661)
mgit-crash-repro.exe!tree_iterator_advance(const git_index_entry * * out, git_iterator * i) Line 813 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\iterator.c:813)
mgit-crash-repro.exe!git_iterator_advance(const git_index_entry * * entry, git_iterator * iter) Line 185 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\iterator.h:185)
mgit-crash-repro.exe!iterator_advance(const git_index_entry * * entry, git_iterator * iterator) Line 925 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\diff_generate.c:925)
mgit-crash-repro.exe!handle_matched_item(git_diff_generated * diff, diff_in_progress * info) Line 1179 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\diff_generate.c:1179)
mgit-crash-repro.exe!git_diff__from_iterators(git_diff * * out, git_repository * repo, git_iterator * old_iter, git_iterator * new_iter, const git_diff_options * opts) Line 1249 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\diff_generate.c:1249)
mgit-crash-repro.exe!git_diff_tree_to_index(git_diff * * out, git_repository * repo, git_tree * old_tree, git_index * index, const git_diff_options * opts) Line 1372 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\diff_generate.c:1372)
mgit-crash-repro.exe!git_status_list_new(git_status_list * * out, git_repository * repo, const git_status_options * opts) Line 341 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\libgit2-sys-0.12.9+1.0.1\libgit2\src\status.c:341)
mgit-crash-repro.exe!git2::repo::Repository::statuses(core::option::Option<mut git2::status::StatusOptions*> self) Line 848 (c:\Users\andre\.cargo\registry\src\github.com-1ecc6299db9ec823\git2-0.13.8\src\repo.rs:848)
mgit-crash-repro.exe!mgit_crash_repro::get_status(std::path::PathBuf path) Line 20 (c:\Users\andre\Repositories\mgit-crash-repro\src\main.rs:20)
mgit-crash-repro.exe!mgit_crash_repro::main::{{closure}}::{{closure}}(mgit_crash_repro::main::{{closure}}::closure-0) Line 10 (c:\Users\andre\Repositories\mgit-crash-repro\src\main.rs:10)
mgit-crash-repro.exe!std::sys_common::backtrace::__rust_begin_short_backtrace<closure-0,()>(mgit_crash_repro::main::{{closure}}::closure-0 f) Line 131 (c:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\sys_common\backtrace.rs:131)
mgit-crash-repro.exe!std::thread::{{impl}}::spawn_unchecked::{{closure}}::{{closure}}<closure-0,()>(std::thread::{{impl}}::spawn_unchecked::{{closure}}::closure-0) Line 476 (c:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\thread\mod.rs:476)
mgit-crash-repro.exe!std::panic::{{impl}}::call_once<(),closure-0>(std::panic::AssertUnwindSafe<closure-0> self) Line 319 (c:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\panic.rs:319)
mgit-crash-repro.exe!std::panicking::try::do_call<std::panic::AssertUnwindSafe<closure-0>,()>(unsigned char * data) Line 299 (c:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\panicking.rs:299)
mgit-crash-repro.exe!_ZN3std9panicking3try17h47d996d239b4b0a6E�() (Unknown Source:0)
mgit-crash-repro.exe!std::panicking::try<(),std::panic::AssertUnwindSafe<closure-0>>(std::panic::AssertUnwindSafe<closure-0> f) Line 274 (c:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\panicking.rs:274)
mgit-crash-repro.exe!std::panic::catch_unwind<std::panic::AssertUnwindSafe<closure-0>,()>(std::panic::AssertUnwindSafe<closure-0> f) Line 394 (c:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\panic.rs:394)
mgit-crash-repro.exe!std::thread::{{impl}}::spawn_unchecked::{{closure}}<closure-0,()>(std::thread::{{impl}}::spawn_unchecked::closure-0) Line 474 (c:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\thread\mod.rs:474)
mgit-crash-repro.exe!core::ops::function::FnOnce::call_once<closure-0,()>(std::thread::{{impl}}::spawn_unchecked::closure-0 *) Line 232 (c:\Users\andre\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\ops\function.rs:232)
[Inline Frame] mgit-crash-repro.exe!alloc::boxed::{{impl}}::call_once() Line 1076 (c:\rustc\c367798cfd3817ca6ae908ce675d1d99242af148\src\liballoc\boxed.rs:1076)
[Inline Frame] mgit-crash-repro.exe!alloc::boxed::{{impl}}::call_once() Line 1076 (c:\rustc\c367798cfd3817ca6ae908ce675d1d99242af148\src\liballoc\boxed.rs:1076)
mgit-crash-repro.exe!std::sys::windows::thread::{{impl}}::new::thread_start() Line 56 (c:\rustc\c367798cfd3817ca6ae908ce675d1d99242af148\src\libstd\sys\windows\thread.rs:56)
kernel32.dll!00007ffadb5e7bd4() (Unknown Source:0)
ntdll.dll!00007ffadc62ce51() (Unknown Source:0)
I noted most of the other threads were blocked on the mutex lock in git_mwindow_open on line 386
Version of libgit2 (release number or SHA1)
Commit a83fd51
(Used in the rust bindings here)
Operating system(s) tested
Windows 10. I also tested with WSL but didn't manage to reproduce it.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels