You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm not sure if this is the same issue described in #62 given there's no reproduction case available, but I encountered a similar segfault when using binaries built from the Cargo.lock file at the current HEAD (219e386ff665b4fd360b397752ce51a658c5e1d6). This is also the case with the latest prebuilt binaries from GitHub (git-absorb-0.6.7-x86_64-unknown-linux-musl.tar.gz).
Unfortunately I can't share the repository to reproduce this either, but I did manage to find a solution to my problem.
I was seeing a segmentation fault on a specific repository:
# in the repo with changes
$ git add -u .
$ git absorb
Segmentation fault (core dumped)
(Also apologies if I got to my conclusions in a roundabout way, this was my first time looking at Rust code, so do let me know if there's a better way of doing things)
Debugging
Since the prebuilt binaries don't have debug symbols, I tried building from source and ensured that things were still failing. This gave the following message:
# in the tummychow/git-absorb repo
$ cargo clean && cargo build --locked
# in the repo with changes
$ git absorb
free(): double free detected in tcache 2
Aborted (core dumped)
Running this under rust-gdb gives the following backtrace:
>>> bt
#0 0x00007ffff7dac00b in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff7d8b859 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff7df626e in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#3 0x00007ffff7dfe2fc in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x00007ffff7dfff6d in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#5 0x000055555564fe5b in stdalloc__free (ptr=0x5555559ee2e0) at libgit2/src/allocators/stdalloc.c:104
#6 0x0000555555611277 in git_mwindow_close_lru_window () at libgit2/src/mwindow.c:269
#7 0x00005555556114c2 in new_window (fd=7, size=92396285398, offset=49063184399) at libgit2/src/mwindow.c:337
#8 0x00005555556116df in git_mwindow_open (mwf=0x5555559d50e0, cursor=0x7fffffff1f58, offset=49063184399, extra=20, left=0x7fffffff1ee0) at libgit2/src/mwindow.c:407
#9 0x000055555564c156 in git_packfile_unpack_header (size_p=0x7fffffff1f70, type_p=0x7fffffff1f4c, mwf=0x5555559d50e0, w_curs=0x7fffffff1f58, curpos=0x7fffffff1f60) at libgit2/src/pack.c:455
#10 0x000055555564c6c2 in pack_dependency_chain (chain_out=0x7fffffff2040, cached_out=0x7fffffff2010, cached_off=0x7fffffff2920, small_stack=0x7fffffff20a0, stack_sz=0x7fffffff2018, p=0x5555559d50e0, obj_offset=49063184399) at libgit2/src/pack.c:581
#11 0x000055555564c8bc in git_packfile_unpack (obj=0x7fffffff2900, p=0x5555559d50e0, obj_offset=0x7fffffff2920) at libgit2/src/pack.c:637
#12 0x0000555555667e74 in pack_backend__read (buffer_p=0x7fffffff29b0, len_p=0x7fffffff29b8, type_p=0x7fffffff29c0, backend=0x5555559c4f90, oid=0x555555abb145) at libgit2/src/odb_pack.c:400
#13 0x000055555564292d in odb_read_1 (out=0x7fffffff2a88, db=0x5555559ca3d0, id=0x555555abb145, only_refreshed=false) at libgit2/src/odb.c:1065
#14 0x0000555555642b3c in git_odb_read (out=0x7fffffff2a88, db=0x5555559ca3d0, id=0x555555abb145) at libgit2/src/odb.c:1116
#15 0x0000555555611ff5 in git_object_lookup_prefix (object_out=0x7fffffff2b50, repo=0x5555559b4fe0, id=0x555555abb145, len=40, type=GIT_OBJECT_TREE) at libgit2/src/object.c:222
#16 0x00005555556120c7 in git_object_lookup (object_out=0x7fffffff2b50, repo=0x5555559b4fe0, id=0x555555abb145, type=GIT_OBJECT_TREE) at libgit2/src/object.c:253
#17 0x00005555556097aa in git_tree_lookup (out=0x7fffffff2b50, repo=0x5555559b4fe0, id=0x555555abb145) at libgit2/src/object_api.c:56
#18 0x000055555566ab6c in tree_iterator_frame_push (iter=0x5555559cdd70, entry=0x555555ab6c48) at libgit2/src/iterator.c:660
#19 0x000055555566b130 in tree_iterator_advance (out=0x7fffffff2ca8, i=0x5555559cdd70) at libgit2/src/iterator.c:813
#20 0x0000555555625006 in git_iterator_advance (entry=0x7fffffff2ca8, iter=0x5555559cdd70) at libgit2/src/iterator.h:184
#21 0x000055555562739c in iterator_advance (entry=0x7fffffff2ca8, iterator=0x5555559cdd70) at libgit2/src/diff_generate.c:925
#22 0x0000555555627aaf in handle_matched_item (diff=0x5555559cb200, info=0x7fffffff2c90) at libgit2/src/diff_generate.c:1179
#23 0x0000555555627cf7 in git_diff__from_iterators (out=0x7fffffff2d20, repo=0x5555559b4fe0, old_iter=0x5555559cdd70, new_iter=0x5555559ca200, opts=0x7fffffff3730) at libgit2/src/diff_generate.c:1249
#24 0x00005555556280a0 in git_diff_tree_to_tree (out=0x7fffffff2e08, repo=0x5555559b4fe0, old_tree=0x5555559d8f50, new_tree=0x5555559cc120, opts=0x7fffffff3730) at libgit2/src/diff_generate.c:1319
#25 0x00005555555eb58e in git2::repo::Repository::diff_tree_to_tree (self=0x7fffffff34c0, old_tree=..., new_tree=..., opts=...) at src/repo.rs:2374
#26 0x00005555555b5791 in git_absorb::run (config=0x7fffffffce00) at src/lib.rs:42
#27 0x000055555559c416 in git_absorb::main () at src/main.rs:102
The backtrace was somewhere in libgit2, and I noticed that the pinned version was rather old. So the first thing I tried was updating the dependencies.
After updating dependencies via cargo update, the double free no longer occurs.
# in the tummychow/git-absorb repo
$ cargo clean && cargo update && cargo build --locked
$ git diff | grep -A3 'libgit2-sys'
name = "libgit2-sys"
-version = "0.12.13+1.0.1"
+version = "0.12.26+1.3.0"
# in the repo with changes
$ git absorb
(success)
This updated the transitive libgit2-sys dependency in the Cargo.lock file from 0.12.13+1.0.1 to 0.12.26+1.3.0. Since this works, it indicates that the issue I was seeing was fixed upstream already.
I then tried explicitly adding libgit2-sys as a dependency and setting an exact version to override the Cargo dependency resolver (without updating git2). The first libgit2-sys after the current version in the Cargo.lock file that fixes this seems to be =0.12.14+1.1.0.
$ nvim Cargo.toml
# add libgit2-sys = "=0.12.14+1.1.0" under [dependencies]
# regenerate the Cargo.lock file + rebuild
That release bumps the libgit2 dependency, so most likely some change in libgit2 between 1.0.0 and 1.1.0 (there's 335 commits here).
At this point, I was happy that things were working so I stopped looking further into this to see what commit in libgit2 fixes the issue.
TL; DR
Updating Cargo.lock to pull in a newer upstream libgit2 dependency seems to fix a double free
The text was updated successfully, but these errors were encountered:
karlding
added a commit
to karlding/git-absorb
that referenced
this issue
Nov 17, 2022
There is a double free in libgit2 that is fixed somewhere between
v1.0.0 and v1.1.0. This means that the transitive libgit2-sys
dependency needs to be after 0.12.14+1.1.0.
This manifests itself via the following error message on certain
repositories:
$ git absorb
free(): double free detected in tcache 2
Aborted (core dumped)
Bump git2 to the latest version, which also updates the transitive
libgit2-sys (and libgit2) dependency.
Fixestummychow#69
I'm not sure if this is the same issue described in #62 given there's no reproduction case available, but I encountered a similar segfault when using binaries built from the
Cargo.lock
file at the currentHEAD
(219e386ff665b4fd360b397752ce51a658c5e1d6
). This is also the case with the latest prebuilt binaries from GitHub (git-absorb-0.6.7-x86_64-unknown-linux-musl.tar.gz
).Unfortunately I can't share the repository to reproduce this either, but I did manage to find a solution to my problem.
I was seeing a segmentation fault on a specific repository:
(Also apologies if I got to my conclusions in a roundabout way, this was my first time looking at Rust code, so do let me know if there's a better way of doing things)
Debugging
Since the prebuilt binaries don't have debug symbols, I tried building from source and ensured that things were still failing. This gave the following message:
Running this under
rust-gdb
gives the following backtrace:The backtrace was somewhere in
libgit2
, and I noticed that the pinned version was rather old. So the first thing I tried was updating the dependencies.After updating dependencies via
cargo update
, the double free no longer occurs.This updated the transitive
libgit2-sys
dependency in theCargo.lock
file from0.12.13+1.0.1
to0.12.26+1.3.0
. Since this works, it indicates that the issue I was seeing was fixed upstream already.I then tried explicitly adding
libgit2-sys
as a dependency and setting an exact version to override the Cargo dependency resolver (without updatinggit2
). The firstlibgit2-sys
after the current version in theCargo.lock
file that fixes this seems to be=0.12.14+1.1.0
.That release bumps the
libgit2
dependency, so most likely some change inlibgit2
between1.0.0
and1.1.0
(there's 335 commits here).At this point, I was happy that things were working so I stopped looking further into this to see what commit in
libgit2
fixes the issue.TL; DR
Updating
Cargo.lock
to pull in a newer upstreamlibgit2
dependency seems to fix a double freeThe text was updated successfully, but these errors were encountered: