Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

tiennou
Copy link
Contributor

@tiennou tiennou commented Sep 11, 2018

Previously we would assert in index_free because the reader incrementation would not be balanced. Release the snapshot normally, so the variable gets decremented before the index is freed.

Fixes #4802.

Previously we would assert in index_free because the reader incrementation
would not be balanced. Release the snapshot normally, so the variable gets
decremented before the index is freed.
@ethomson
Copy link
Member

Fixes half of it, anyway - we need to not malloc(0) as well. 😀

@ethomson
Copy link
Member

/rebuild

@libgit2-azure-pipelines
Copy link

Okay, @ethomson, I started to rebuild this pull request.

@ethomson
Copy link
Member

(That wasn't meant as snark, BTW, I just meant that we need to not close the issue after merging this.)

@tiennou
Copy link
Contributor Author

tiennou commented Sep 12, 2018

I was under the impression that NULL was a valid return value from malloc(0), but it happens that the other value allowed by the standard is a non-NULL, non-dereferencable pointer (thanks, but no thanks 😁).

Would it be acceptable to just MIN_ALLOCSIZE a 0-sized vector on dup then ? Or should I just skip the allocation altogether ?

@tiennou
Copy link
Contributor Author

tiennou commented Sep 14, 2018

Fixed the malloc(0) issue when duping empty/unallocated vectors. I'm still not sure the vector code is completely safe in that regard though, as resize_vector calls realloc, which has the same caveat.

src/vector.c Outdated

memcpy(v->contents, src->contents, bytes);
GITERR_CHECK_ALLOC_MULTIPLY(&bytes, src->length, sizeof(void *));
if (bytes != 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (src->length) {
    size_t bytes;
    GITERR_CHECKALLOC_MULTIPLY(&bytes, src->length, sizeof(void *));
    ...
}

No need to do unnecessary work in case where src->length is already 0. I think like this intentions also become a bit clearer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. I was attempting to remove the different codepaths when duping vs a normal init (ie. make dup go through init/resize/memcpy instead of doing its own malloc), but I don't think it's worthwhile.

GITERR_CHECK_ALLOC_MULTIPLY(&bytes, src->length, sizeof(void *));
v->contents = git__malloc(bytes);
GITERR_CHECK_ALLOC(v->contents);
v->_alloc_size = src->length;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jeez, this _alloc_size member is really confusing. One tends to think it is the actual size (as you also seem to have interpreted it in your first go), but it actually is the allocated length. We should probably refactor this in another PR

@@ -32,6 +32,9 @@ GIT_INLINE(int) resize_vector(git_vector *v, size_t new_size)
{
void *new_contents;

if (new_size == 0)
return 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One might tend to think that resizing to 0 might mean that we should deallocate the vector. But resize_vector is only called from git_vector_init, git_vector_insert, git_vector_insert_sorted, git_vector_insert_null, git_vector_size_hint and git_vector_resize_to. Only for the last two it might make sense to do the deallocation dance, though.

  • git_vector_resize_to is only used in git_vector_set, so the deallocation path could never be hit here.
  • git_vector_size_hint will only do any work if the new size hint is bigger than alloc_size. So it also cannot ever hit the deallocation path.

So the dealloc would in fact be useless.

I think the only code path that can actually invoke resize_vector(v, 0) is git_vector_size_hint. And I can imagine a caller trivially invoking it e.g. if he wants to allocate a vector for a set of n items, where n might also be 0.

Anyway, long story short: makes sense to me.

@pks-t pks-t merged commit 367f624 into libgit2:master Sep 28, 2018
@pks-t
Copy link
Member

pks-t commented Sep 28, 2018

Thanks @tiennou!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants