Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error while running tests (ldlt_app.cpp) #140

Closed
bharswami opened this issue Sep 20, 2023 · 3 comments · Fixed by #145
Closed

Error while running tests (ldlt_app.cpp) #140

bharswami opened this issue Sep 20, 2023 · 3 comments · Fixed by #145
Labels

Comments

@bharswami
Copy link

bharswami commented Sep 20, 2023

I am getting the following index error
Unhandled exception at 0x00007FFBB78B829C (ucrtbased.dll) in spraltestfull.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(
_Pos < static_cast<size_type>(_My_data._Mylast - _My_data._Myfirst), "vector subscript out of range");
#endif // _CONTAINER_DEBUG_LEVEL > 0
The higher level functions are (in order, last call first)

  1. copy_failed_rect(
    get_nrow(nblk - 1, m, block_size), get_ncol(jblk, n, block_size),
    get_ncol(nblk - 1, n, block_size), cdata[jblk],
    &failed_rect[jfail * (m - n) + (nblk - 1) * block_size - n], m - n,
    &a[jblk * block_size * lda + (nblk - 1) * block_size], lda
    );
  2. int q1 = LDLT
    <T, INNER_BLOCK_SIZE, CopyBackup, use_tasks, debug>
    ::factor(
    m, n, perm, l, lda, d, backup, options, options.pivot_method,
    outer_block_size, 0.0, nullptr, 0, work
    );
  3. TEST((
    ldlt_test<double, 2, false, false>(0.01, 1e-20, true, false, false, 4, 2)
    ));
  4. int temp;
    temp = run_ldlt_app_tests();
    Please clarify.
@mjacobse
Copy link
Collaborator

mjacobse commented Sep 22, 2023

I can confirm this. The problem is that operator[] of the std::vector failed_rect is called out of bounds. However, in this case, nothing seems to be done with the value other than taking the address. That's why this does not really cause issues in practice and why this is not found by address sanitizer or valgrind. But still, calling operator[] out of bounds is undefined behaviour, so the Microsoft STL is correctly detecting this as an error. Compiling with -D_GLIBCXX_DEBUG makes gcc's stdlibc++ reveal the error too. In fact there are a handful of these in a few places in the code, as this pattern of taking the address of operator[]'s return value is used quite frequently.

A simple fix would be to use the data() member function instead. That allows doing the pointer arithmetic without indexing into the vector with operator[]. So &failed_rect[jfail*(m-n)+(nblk-1)*block_size-n] would become failed_rect.data() + jfail*(m-n)+(nblk-1)*block_size-n.

Should we do that for the few cases flagged by -D_GLIBCXX_DEBUG? Or should we replace every case of the &something[] pattern? The ones that do not cause an error appear to only be used in-bounds, making a change unnecessary. But it's also possible that the tests just do not run into error cases which could potentially still be triggered by different inputs to the library.

@jfowkes jfowkes added the bug label Sep 22, 2023
@jfowkes
Copy link
Contributor

jfowkes commented Sep 22, 2023

Thank you @bharswami for reporting and @mjacobse for confirming.

I'd be tempted for now to just fix the cases flagged up by -D_GLIBCXX_DEBUG and keep the other (presumably in-bounds) uses of the &something[] pattern as is since these make the pointer arithmetic involved clearer (at least to me) and avoid a potentially very large change to the codebase that could inadvertently introduce other bugs.

@mjacobse would you be happy to make a PR that fixes the -D_GLIBCXX_DEBUG cases?

@jfowkes jfowkes mentioned this issue Sep 22, 2023
mjacobse added a commit to mjacobse/spral that referenced this issue Sep 22, 2023
In several places, the std::vector subscript operator[] is used
together with the addressof operator to obtain a pointer into the
vector. In some cases, this is intended to yield a pointer past the
end of the vector. In such cases, the pointer is not actually used
to read from or write to. Thus it causes no actual problems in
practice and even address sanitizer and valgrind are happy with it.
However, operator[] is still called with an out of bounds index,
which is undefined behaviour. This is correctly detected by
Microsofts standard library debug checks and also by GNU's library
once compiling with -D_GLIBCXX_DEBUG.

As a fix, we use .data() and pointer arithmetic to get to the
intended pointer without any out of bound access. Fixes ralna#140
jfowkes pushed a commit that referenced this issue Sep 22, 2023
In several places, the std::vector subscript operator[] is used
together with the addressof operator to obtain a pointer into the
vector. In some cases, this is intended to yield a pointer past the
end of the vector. In such cases, the pointer is not actually used
to read from or write to. Thus it causes no actual problems in
practice and even address sanitizer and valgrind are happy with it.
However, operator[] is still called with an out of bounds index,
which is undefined behaviour. This is correctly detected by
Microsofts standard library debug checks and also by GNU's library
once compiling with -D_GLIBCXX_DEBUG.

As a fix, we use .data() and pointer arithmetic to get to the
intended pointer without any out of bound access. Fixes #140
@jfowkes
Copy link
Contributor

jfowkes commented Sep 22, 2023

Fixed in #145

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

Successfully merging a pull request may close this issue.

3 participants