如何使用 C++ 期货和对局部变量的引用来引发崩溃?
How to provoke crash with c++ futures and reference to local variables?
我非常想了解 Eric Niebler's warnings 关于 c++ 期货和悬挂本地引用(在标题为“线程的问题”的部分中)。因此,我写了一个小程序,重复如下:
#include <iostream>
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/chrono.hpp>
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
void computeResult(int& i) {
boost::this_thread::sleep_for(boost::chrono::seconds(1));
std::cout << i << std::endl;
i += 1;
}
boost::future<int> doThing() {
int local_state{0};
auto lam = [&]() { return computeResult(local_state); };
auto fut = boost::async(lam);
return fut.then([&](auto&&) { return local_state; }); // OOPS
}
int main() {
auto fun = doThing();
int out = fun.get();
std::cout << out << std::endl;
}
文中指出:
If you’ve programmed with futures before, you’re probably screaming, “Nooooo!” The .then() on the last line queues up some work to run after computeResult() completes. doThing() then returns the resulting future. The trouble is, when doThing() returns, the lifetime of the State object ends, and the continuation is still referencing it. That is now a dangling reference, and will likely cause a crash.
我稍微修改了 doThing
函数以异步调用 computeResult
,但在其他方面尝试按照文中的示例进行操作。不幸的是,这个程序在我的电脑上运行得很好。有人可以像 Eric Niebler 的描述中概述的那样,概述如何编写可靠地崩溃的程序吗?
正如大家所说,相信 Undefined Behaviour 会导致崩溃是错误的。
这是一个危险的信念,因为当存在静默的数据损坏、死锁,或者实际上 多年来没有什么容易观察到的东西(直到你的程序突然发射那枚核导弹)。
有一些工具(例如 asan/ubsan 和 valgrind/helgrind)可以在许多病例给您带来更多痛苦之前对其进行诊断。
让我们 运行 使用 GCC 或 Clang 的 -fsanitize=address,undefined
选项的示例:
1264
AddressSanitizerAddressSanitizer:DEADLYSIGNAL
:DEADLYSIGNAL
=================================================================
==13854==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x7fc8d475b88e bp 0x613000000040 sp 0x7fc8c4cfe9b0 T1)
==13854==The signal is caused by a READ memory access.
==13854==Hint: this fault was caused by a dereference of a high value address (see register values below). Dissassemble the provided pc to learn which register was used.
/home/sehe/custom/boost_1_77_0/boost/thread/lock_types.hpp:346:14: runtime error: member call on misaligned address 0x6120000004f1 for type 'struct mutex', which requires 8 byte alignment
0x6120000004f1: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
/home/sehe/custom/boost_1_77_0/boost/thread/pthread/mutex.hpp:61:48: runtime error: member access within misaligned address 0x6120000004f1 for type 'struct mutex', which requires 8 byte alignment
0x6120000004f1: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
/home/sehe/custom/boost_1_77_0/boost/thread/lock_types.hpp:331:18: runtime error: member call on misaligned address 0x6120000004f1 for type 'struct mutex', which requires 8 byte alignment
0x6120000004f1: note: pointer points here
00 00 00 00 01 00 00 00 00 00 00 00 1e 36 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
/home/sehe/custom/boost_1_77_0/boost/thread/pthread/mutex.hpp:70:13: runtime error: member access within misaligned address 0x6120000004f1 for type 'struct mutex', which requires 8 byte alignment
0x6120000004f1: note: pointer points here
00 00 00 00 01 00 00 00 00 00 00 00 1e 36 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
1265
(作为旁注,即使没有消毒剂,给定的程序也会导致我的 machine/compiler 崩溃)
我非常想了解 Eric Niebler's warnings 关于 c++ 期货和悬挂本地引用(在标题为“线程的问题”的部分中)。因此,我写了一个小程序,重复如下:
#include <iostream>
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/chrono.hpp>
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
void computeResult(int& i) {
boost::this_thread::sleep_for(boost::chrono::seconds(1));
std::cout << i << std::endl;
i += 1;
}
boost::future<int> doThing() {
int local_state{0};
auto lam = [&]() { return computeResult(local_state); };
auto fut = boost::async(lam);
return fut.then([&](auto&&) { return local_state; }); // OOPS
}
int main() {
auto fun = doThing();
int out = fun.get();
std::cout << out << std::endl;
}
文中指出:
If you’ve programmed with futures before, you’re probably screaming, “Nooooo!” The .then() on the last line queues up some work to run after computeResult() completes. doThing() then returns the resulting future. The trouble is, when doThing() returns, the lifetime of the State object ends, and the continuation is still referencing it. That is now a dangling reference, and will likely cause a crash.
我稍微修改了 doThing
函数以异步调用 computeResult
,但在其他方面尝试按照文中的示例进行操作。不幸的是,这个程序在我的电脑上运行得很好。有人可以像 Eric Niebler 的描述中概述的那样,概述如何编写可靠地崩溃的程序吗?
正如大家所说,相信 Undefined Behaviour 会导致崩溃是错误的。
这是一个危险的信念,因为当存在静默的数据损坏、死锁,或者实际上 多年来没有什么容易观察到的东西(直到你的程序突然发射那枚核导弹)。
有一些工具(例如 asan/ubsan 和 valgrind/helgrind)可以在许多病例给您带来更多痛苦之前对其进行诊断。
让我们 运行 使用 GCC 或 Clang 的 -fsanitize=address,undefined
选项的示例:
1264
AddressSanitizerAddressSanitizer:DEADLYSIGNAL
:DEADLYSIGNAL
=================================================================
==13854==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x7fc8d475b88e bp 0x613000000040 sp 0x7fc8c4cfe9b0 T1)
==13854==The signal is caused by a READ memory access.
==13854==Hint: this fault was caused by a dereference of a high value address (see register values below). Dissassemble the provided pc to learn which register was used.
/home/sehe/custom/boost_1_77_0/boost/thread/lock_types.hpp:346:14: runtime error: member call on misaligned address 0x6120000004f1 for type 'struct mutex', which requires 8 byte alignment
0x6120000004f1: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
/home/sehe/custom/boost_1_77_0/boost/thread/pthread/mutex.hpp:61:48: runtime error: member access within misaligned address 0x6120000004f1 for type 'struct mutex', which requires 8 byte alignment
0x6120000004f1: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
/home/sehe/custom/boost_1_77_0/boost/thread/lock_types.hpp:331:18: runtime error: member call on misaligned address 0x6120000004f1 for type 'struct mutex', which requires 8 byte alignment
0x6120000004f1: note: pointer points here
00 00 00 00 01 00 00 00 00 00 00 00 1e 36 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
/home/sehe/custom/boost_1_77_0/boost/thread/pthread/mutex.hpp:70:13: runtime error: member access within misaligned address 0x6120000004f1 for type 'struct mutex', which requires 8 byte alignment
0x6120000004f1: note: pointer points here
00 00 00 00 01 00 00 00 00 00 00 00 1e 36 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
1265
(作为旁注,即使没有消毒剂,给定的程序也会导致我的 machine/compiler 崩溃)