Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Fix/assertion error#182

Merged
mgeplf merged 3 commits intoBlueBrain:masterfrom
sanjayankur31:fix/assertion-error
Mar 17, 2022
Merged

Fix/assertion error#182
mgeplf merged 3 commits intoBlueBrain:masterfrom
sanjayankur31:fix/assertion-error

Conversation

@sanjayankur31
Copy link
Contributor

@sanjayankur31 sanjayankur31 commented Mar 9, 2022

Fixes an assertion error thrown when _GLIBCXX_ASSERTIONS is defined, and enables the option by default

With `-Wp,-D_GLIBCXX_ASSERTIONS`, tests fail with an assertion error of
the form:

```
/usr/include/c++/12/bits/stl_vector.h:1122: std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::operator[](size_type) [with _T
p = float; _Alloc = std::allocator<float>; reference = float&; size_type = long unsigned int]: Assertion '__n < this->size()' failed.
```

The assertion failure happens on line 473 in report_reader.cpp:
```
std::copy(&buffer[gid_start], &buffer[gid_end], &data_ptr[offset]);
```

The problem is that `gid_end` can equal the size of `buffer`, and
`&buffer[gid_end]` triggers the assertion failure in that case.

Diagnosed and fixed suggested by Jerry James in the Fedora package
review:
https://bugzilla.redhat.com/show_bug.cgi?id=2061077#c6
@pramodk pramodk requested a review from matz-e March 9, 2022 08:44
Copy link
Member

@matz-e matz-e left a comment

Choose a reason for hiding this comment

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

Seems sensible from my side, wondering if this will work on all compilers though.

@sanjayankur31
Copy link
Contributor Author

I'm not sure what the corresponding flags for clang are, but I see that the CI builds completed fine so perhaps these extra definitions are simply ignored?

@matz-e matz-e requested a review from sergiorg-hpc March 9, 2022 09:58
@sergiorg-hpc sergiorg-hpc requested a review from mgeplf March 9, 2022 13:07
} else { // Elements report
uint64_t gid_end = range.second - min;
std::copy(&buffer[gid_start], &buffer[gid_end], &data_ptr[offset]);
std::copy(buffer.begin() + gid_start, buffer.begin() + gid_end, &data_ptr[offset]);
Copy link
Contributor

@sergiorg-hpc sergiorg-hpc Mar 9, 2022

Choose a reason for hiding this comment

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

Hmmmm... Do you mind to clarify why the change, please? I don't mind, but if we do change this, we should also change the code in line 470 and we must verify that the performance of the copies remains the same (e.g., this operation is executed thousands of times in thousands of timesteps, it matters!).

On a side note, perhaps using something like std::next(buffer.begin(), gid_start) as well, but this is irrelevant.

Copy link
Contributor

Choose a reason for hiding this comment

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

Turning on the _GLIBCXX_ASSERTIONS makes doing the subscript on buffer look like &buffer[buffer.size()], which would be an out of bounds error and thus undefined behavior. AFAIK, this is ok in this specific case as long as std::copy doesn't deref the pointer.

The change means we use the std::copy overload that takes iterators, and is "safer", because there is no chance there is an OOB deref, as long as gid_end never is larger than the size of the array.

The ASM will look the same from both of them, I'd expect, at a reasonable optimization level.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks @mgeplf for clarifying. My point was that accessing the array with [] in std::copy might avoid boundary checks or additional code, but if you feel that it should be the same, then no complains at all.

I'd still prefer the use of std::next(buffer.begin(), gid_start) and std::next(buffer.begin(), gid_end) with iterators, although I don't mind leaving the code as it is with the + operator.

Copy link
Contributor

Choose a reason for hiding this comment

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

but if you feel that it should be the same, then no complains at all.

Had a quick look on godbolt to confirm (which I never take as conclusive), but it seems that compiler sees through this:
https://godbolt.org/z/8dez5nEM3

I'd still prefer the use of std::next(buffer.begin(), gid_start)

Ok, I'll make those changes, and another one to remove the pointer usage altogether.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've made the changes; any/all reviews welcome.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All tests pass in my Fedora build with the newest changes 👍

} else { // Elements report
uint64_t gid_end = range.second - min;
std::copy(&buffer[gid_start], &buffer[gid_end], &data_ptr[offset]);
std::copy(buffer.begin() + gid_start, buffer.begin() + gid_end, &data_ptr[offset]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Turning on the _GLIBCXX_ASSERTIONS makes doing the subscript on buffer look like &buffer[buffer.size()], which would be an out of bounds error and thus undefined behavior. AFAIK, this is ok in this specific case as long as std::copy doesn't deref the pointer.

The change means we use the std::copy overload that takes iterators, and is "safer", because there is no chance there is an OOB deref, as long as gid_end never is larger than the size of the array.

The ASM will look the same from both of them, I'd expect, at a reasonable optimization level.

* move _GLIBCXX_ASSERTIONS behind CMake option SONATA_CXX_WARNINGS
* don't use off_t, use size_t instead
* use iterator style access instead of raw pointers
Copy link
Contributor

@sergiorg-hpc sergiorg-hpc left a comment

Choose a reason for hiding this comment

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

Sorry for the delay, looks good to me 👍. Thank you @mgeplf and @sanjayankur31 for the improvements!

@mgeplf mgeplf merged commit bfdf6f5 into BlueBrain:master Mar 17, 2022
@sergiorg-hpc sergiorg-hpc mentioned this pull request Mar 22, 2022
sergiorg-hpc added a commit that referenced this pull request Mar 22, 2022
sergiorg-hpc added a commit that referenced this pull request Mar 22, 2022
sergiorg-hpc added a commit that referenced this pull request Mar 30, 2022
sergiorg-hpc added a commit that referenced this pull request Mar 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants