• Kirill Smelkov's avatar
    *: Replace usage of &vector[0] with vector.data() · 39dde7eb
    Kirill Smelkov authored
    We use &vector[0] in several places to get the pointer to vector data,
    but std::vector[i] states invariant that i must be < vector.size(). If
    the vector is not empty - then &vector[0] works ok. However if the
    vector is empty - then the invariant is broken.
    Normally it should not be a problem, since with empty vector we usually
    use (&vector[0], vector.size()) pair, and for empty vector its size is
    zero. In other words even if &vector[0] returns some not good pointer
    with zero size that data should never be accessed. But a build of
    libstdc++ could have asserts turned on and verify that i is actually <
    size. For example with default install on Fedora the following program
    with plain select()
        from golang import select
    crashes with assert triggered on the breakage of that invariant
        [Thread debugging using libthread_db enabled]
        Using host libthread_db library "/lib64/libthread_db.so.1".
        /usr/include/c++/10/bits/stl_vector.h:1042: std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::operator[](std::vector<_Tp, _Alloc>::size_type) [with _Tp = golang::_selcase; _Alloc = std::allocator<golang::_selcase>; std::vector<_Tp, _Alloc>::reference = golang::_selcase&; std::vector<_Tp, _Alloc>::size_type = long unsigned int]: Assertion '__builtin_expect(__n < this->size(), true)' failed.
        Program received signal SIGABRT, Aborted.
        0x00007ffff7e22a25 in raise () from /lib64/libc.so.6
        (gdb) bt
        #0  0x00007ffff7e22a25 in raise () from /lib64/libc.so.6
        #1  0x00007ffff7e0b895 in abort () from /lib64/libc.so.6
        #2  0x00007fffea638d6d in std::__replacement_assert (__condition=0x7fffea63ea88 "__builtin_expect(__n < this->size(), true)",
            __function=0x7fffea63eab8 "std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::operator[](std::vector<_Tp, _Alloc>::size_type) [with _Tp = golang::_selcase; _Alloc = std::allocator<golang::_selcase>; std::vector<_Tp, "..., __line=1042, __file=0x7fffea63ebe8 "/usr/include/c++/10/bits/stl_vector.h")
            at /usr/include/c++/10/x86_64-redhat-linux/bits/c++config.h:2552
        #3  std::vector<golang::_selcase, std::allocator<golang::_selcase> >::operator[] (this=<synthetic pointer>, __n=0)
            at /usr/include/c++/10/bits/stl_vector.h:1042
        #4  std::vector<golang::_selcase, std::allocator<golang::_selcase> >::operator[] (__n=0, this=<synthetic pointer>)
            at /usr/include/c++/10/bits/stl_vector.h:1040
        #5  __pyx_pf_6golang_7_golang_6pyselect (__pyx_self=<optimized out>, __pyx_v_pycasev=<optimized out>) at golang/_golang.cpp:7930
        #6  __pyx_pw_6golang_7_golang_7pyselect (__pyx_self=<optimized out>, __pyx_args=<optimized out>, __pyx_kwds=<optimized out>) at golang/_golang.cpp:7284
        #7  0x00007ffff7bceeab in cfunction_call_varargs (func=<built-in function pyselect>, args=(), kwargs=0x0)
            at /usr/src/debug/python3-3.8.10-1.fc32.x86_64/Objects/call.c:743
    -> Fix it all via replacing &vector[0] with vector.data() everywhere.
    No need to add new test since select() is used by test_blockforever()
    and running that test on Fedora was crashing as well.
    /reviewed-by @jerome
    /reviewed-at !22
Last commit
Last update
3rdparty/include/linux Loading commit data...
golang Loading commit data...
gpython Loading commit data...
.gitignore Loading commit data...
.nxdtest Loading commit data...
CHANGELOG.rst Loading commit data...
COPYING Loading commit data...
MANIFEST.in Loading commit data...
README.rst Loading commit data...
pyproject.toml Loading commit data...
setup.py Loading commit data...
tox.ini Loading commit data...
trun Loading commit data...