意外的 SIGSEGV

Unexpected SIGSEGV

提问人:Chameleon 提问时间:11/12/2023 最后编辑:Chameleon 更新时间:11/12/2023 访问量:56

问:

谁能解释一下为什么以下密集简化的代码会产生 SIGSEGV?

一些信息:

  • 它使用编译器生成 SIGSEGVg++ (MinGW-W64 x86_64-ucrt-mcf-seh, built by Brecht Sanders) 13.2.0
  • 它仅在相对较新的处理器上使用 g++ 生成 SIGSEGV(例如,10 年及更新的处理器 - 不在我的 Core 2 Duo 中)-march=native
  • 如果我删除无用(仅在简化代码中无用)成员,我永远不会有 SIGSEGV。这意味着对于 32 字节的结构大小,我有问题,而不是 24 字节。band_matrix_jump_iterator::v
  • 并非所有时间都以 SIGSEGV 结束。对我来说,它大约是 6 次运行正常和 1 次 SIGSEGV 终止。

可编译的简化代码如下:

#include <iostream>

template<typename It>
struct container_view
{
    typedef typename It::reference reference;
    typedef std::remove_reference_t<reference> value_type;
    typedef const reference const_reference;

    constexpr container_view(It it, size_t s) noexcept : it(it), s(s) {}

    constexpr It begin() const noexcept { return it; }
    constexpr It end() const noexcept { return it + size(); }

    constexpr reference operator[](size_t i) noexcept { return *(it + i); }

    /// Size of container.
    constexpr size_t size() const noexcept { return s; }

private:
    It it;
    size_t s;
};


template<typename T, typename S = const size_t>
struct shifted_vector
{
    typedef std::remove_reference_t<T> vector_type;     ///< The type of vector.
    T vec;                                              ///< DenseVector of sequential non-zero elements.
    S offset;                                           ///< Offset of first non-zero element.
};


struct band_matrix_jump_iterator
{
    typedef short value_type;
    typedef short* pointer;
    typedef short& reference;

private:
    size_t b;   // matrix's bandwidth
    size_t v;   // matrix's column
    size_t e;   // matrix's column's element's index.
    pointer p;  // Pointer to current element.

public:

    constexpr band_matrix_jump_iterator(pointer p, size_t b, size_t v, size_t e) noexcept
        : b{b}, v{v}, e{e}, p{p} {}

    constexpr band_matrix_jump_iterator &operator++() noexcept { ++e; ++p; return *this; }
    constexpr band_matrix_jump_iterator &operator+=(ptrdiff_t i) noexcept { e += i; p += i; return *this; }
    constexpr band_matrix_jump_iterator operator+(ptrdiff_t i) const noexcept
        { band_matrix_jump_iterator t(*this); t += i; return t; }
    constexpr reference operator*() const noexcept { return *p; }
    constexpr bool operator==(const band_matrix_jump_iterator &it) const noexcept { return e == it.e; }
};


struct band_matrix
{
    typedef short value_type;
    typedef value_type* pointer;

    constexpr size_t columns() const noexcept { return 10; }

    size_t b;
    pointer elements;


//---------------------------------------------------------------- TYPEDEFS OF ITERATORS AND VECTORS


    typedef band_matrix_jump_iterator column_iterator;
    typedef shifted_vector<container_view<column_iterator>, const uint8_t> column_vector;



//--------------------------------------------------------------------------- CONSTRUCTORS / ASSIGNS

    constexpr band_matrix(size_t b) : b{b}, elements(new value_type[10]) {}
    constexpr ~band_matrix() noexcept { delete[] elements; }


//------------------------------------------ GET ROWS, COLUMNS, DIAGONAL AND CORRESPONDING ITERATORS


    /// Return a beginning iterator to column \c i vector.
    constexpr column_iterator column_begin(size_t i) noexcept
    { return column_iterator(elements + i, 0, i, 0); }


    /// Return a vector view of column \c i.
    constexpr column_vector column(size_t i) noexcept
    { return {typename column_vector::vector_type{column_begin(i), 1}, (uint8_t) i}; }
};




using namespace std;

int main()
{
    band_matrix m(0);
    for (size_t i = 0; i < 10; ++i) m.elements[i] = i;

    // checking columns
    for (size_t i = 0; i < m.columns(); ++i)
    {
        auto v = m.column(i);
        cout << (int) v.offset << ": { ";
        for (auto i : v.vec) cout << i << " ";
        cout << "}\n";
    }
}

出现问题的程序集如下:

0x7ff7f8fd3436  call   0x7ff7f8fd33b0 <band_matrix::column_begin(unsigned long long)>
0x7ff7f8fd343b  vmovdqu -0x20(%rbp),%ymm0
0x7ff7f8fd3440  vmovdqa %ymm0,-0x40(%rbp)     ; <--- THE NASTY INSTRUCTION
0x7ff7f8fd3445  lea    -0x40(%rbp),%rax
0x7ff7f8fd3449  mov    0x10(%rbp),%rcx
0x7ff7f8fd344d  mov    $0x1,%r8d
0x7ff7f8fd3453  mov    %rax,%rdx
0x7ff7f8fd3456  call   0x7ff7f8fd34f0 <container_view<band_matrix_jump_iterator>::container_view(band_matrix_jump_iterator, unsigned long long)>

谁能解释一下我的,我在哪里用未定义的行为做一些事情?

C++ 分段错误 C++23

评论

0赞 Chameleon 11/12/2023
@273K 甚至没有警告我。g++ -std=c++23 -march=native -g 1.cpp
0赞 Chameleon 11/12/2023
我在这里问,如果我犯了一个错误,在将代码提交给 gcc 错误跟踪器之前。
2赞 273K 11/12/2023
无法复制 godbolt.org/z/E9rW7ErKx
0赞 Chameleon 11/12/2023
@273K 这意味着它可能是一个 g++ 错误?
1赞 273K 11/12/2023
它可能是DLL地狱。

答: 暂无答案