gpt4 book ai didi

c++ - std::condition_variable 的内存位置可能导致 futex 错误

转载 作者:行者123 更新时间:2023-12-01 14:47:45 25 4
gpt4 key购买 nike

我们的软件中有一个错误,结果很可怕:

The futex facility returned an unexpected error code.

我们将其追溯到一个问题,即 std::condition_variable 在 malloc 内存区域中的位置导致 futex 错误。如果 std::condition_variable 未在 16 字节字上对齐 - 那么当您尝试 wait 时它会导致 futex 错误。在示例中,前两个 wait_for 调用有效,但最后一个调用中止程序并出现 futex 错误。

void futex_error()
{
/* init */
std::mutex mtx;

/* Normal one works */
std::cout << "Doing normal" << "\n";
std::condition_variable* con_var = (std::condition_variable*)malloc(sizeof(std::condition_variable));
new (con_var) std::condition_variable{};

{
std::unique_lock<std::mutex> lck(mtx);
con_var->wait_for(lck, std::chrono::seconds(1));
}

/* Clean */
con_var->std::condition_variable::~condition_variable();
free(con_var);

std::cout << "Doing 16 bytes" << "\n";
/* Works on 16 byte alignment */
uint8_t* ptr_16 = (uint8_t*)malloc(sizeof(std::condition_variable) + 16);
std::condition_variable* con_var_16 = new (ptr_16 + 16) std::condition_variable{};

{
std::unique_lock<std::mutex> lck(mtx);
con_var_16->wait_for(lck, std::chrono::seconds(1));
}

/* Clean */
con_var_16->std::condition_variable::~condition_variable();
free(ptr_16);

std::cout << "Doing 1 byte" << "\n";
/* Futex error */
uint8_t* bad_ptr = (uint8_t*)malloc(sizeof(std::condition_variable) + 1);
std::condition_variable* bad = new (bad_ptr + 1) std::condition_variable{};

{
std::unique_lock<std::mutex> lck(mtx);
bad->wait_for(lck, std::chrono::seconds(1)); //<--- error here?
}

/* Clean */
bad->std::condition_variable::~condition_variable();
free(con_var);
}

我似乎无法找到有关 futex 错误的文档以及对齐会导致此错误的原因。有谁知道为什么会发生这种情况?这是在 linux(Arch 和 Ubuntu)上,同时使用 gcc 9.3。

最佳答案

why the alignment would cause this

来自 C++ draft Alignment p1 :

Object types have alignment requirements ([basic.fundamental], [basic.compound]) which place restrictions on the addresses at which an object of that type may be allocated.

表达式:

new (bad_ptr + 1) std::condition_variable{};

bad_ptr + 1 未与 alignof(std::condition_variable) 对齐的系统上调用未定义的行为。在 godbolt 上测试对于 gcc10,alignof(std::confition_variable) 等于 8

bad-> 访问都是未对齐的访问,都是未定义的行为。

Does anyone know why this would occur?

检查可执行文件执行时的 strace 输出,我们可以看到:

futex(0x557da3e262e9, FUTEX_WAIT_BITSET_PRIVATE, 0, {tv_sec=2439, tv_nsec=619296657}, FUTEX_BITSET_MATCH_ANY) = -1 EINVAL (Invalid argument)

因为 uaddr 第一个参数应该是指向 futex 调用的 int 的指针没有与 _Alignof(int)< 对齐,内核检测到它 here和 futex 返回 EINVAL。然后标准库就退出应用程序,这对于未定义的行为来说是一个非常好的行为。

关于c++ - std::condition_variable 的内存位置可能导致 futex 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62058325/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com