Can GCC';s ASAN提供与Rust相同的内存安全性?
Rust是一种内存安全语言,但GCC中有一个安全特性,称为(ASAN):Can GCC';s ASAN提供与Rust相同的内存安全性?,gcc,rust,address-sanitizer,Gcc,Rust,Address Sanitizer,Rust是一种内存安全语言,但GCC中有一个安全特性,称为(ASAN): /configure CFLAGS=“-fsanitize=address-g”cxflags=“-fsanitize=address-g”LDFLAGS=“-fsanitize=address” 制作 核对 ASAN能否提供与Rust相同的内存安全性,或者Rust是否有更多的技巧?甚至可以将两者进行比较吗 免责声明:我不是程序员 还没听说过这个选项,但听起来好像它修改了输出程序。换句话说,它在程序运行时进行检查 另一方
/configure CFLAGS=“-fsanitize=address-g”cxflags=“-fsanitize=address-g”LDFLAGS=“-fsanitize=address”
制作
核对
ASAN能否提供与Rust相同的内存安全性,或者Rust是否有更多的技巧?甚至可以将两者进行比较吗
免责声明:我不是程序员 还没听说过这个选项,但听起来好像它修改了输出程序。换句话说,它在程序运行时进行检查 另一方面,Rust会检查程序的创建时间(或者用程序员的话说编译),所以一开始就不存在这些内存安全缺陷
链接文章提到它只涉及一个案例,返回后使用 不,这两个特征不可比较 地址清理不是一种安全功能,也不提供内存安全:它是一种调试工具。程序员已经有了一些工具来检测他们编写的代码是否存在内存问题,例如空闲后使用或内存泄漏。Valgrind可能是最著名的例子。这个gcc特性提供了(部分)相同的功能:唯一的新功能是它与编译器集成,因此更易于使用 您不会在生产环境中启用此功能:它仅用于调试。使用此标志编译测试,测试会自动检测由测试触发的内存错误。如果您的测试不足以触发问题,那么您仍然存在问题,并且仍然会在生产中导致相同的安全缺陷 Rust的所有权模型通过使包含这些缺陷的程序无效来防止这些缺陷:编译器不会编译它们。您不必担心测试不会触发问题,因为如果代码编译,就不会有问题 这两个特性适用于不同的问题集。地址清理的一个特性是检测内存泄漏(分配内存而忽略以后释放内存)。RIST比C或C++更难编写内存泄漏,但仍然是可能的(如果你有循环引用)。Rust的所有权模型防止了顺序和多线程情况下的数据竞争(见下文)。地址消毒的目的不是检测这两种情况 顺序代码中的数据竞争的一个例子是,如果您在对象集合上进行迭代,同时添加或删除元素。在C++中,改变大多数集合会使任何迭代器无效,但程序员必须意识到这一点:没有检测到(虽然有些集合在调试构建中有额外的检查)。在Rust中,当集合上存在迭代器时,不可能对集合进行变异,因为所有权模型阻止了这一点
多线程代码中的数据竞争的一个例子是,两个线程共享一个对象,访问受互斥锁保护。在C++中,程序员可以在改变对象时忘记锁定互斥体。在Rust中,互斥锁本身拥有它所保护的对象,因此不可能不安全地访问它。(不过,还有许多其他类型的并发错误,所以不要忘乎所以!)消毒剂 GCC和Clang都有一套消毒剂;到目前为止,它们是在Clang中开发的,然后移植到GCC,因此Clang拥有最先进的版本:
- (ASan):检测越界访问、释放后使用、作用域后使用、双重释放/无效释放,并增加对内存泄漏的支持(预期内存开销为3倍)
- (MemSan):检测未初始化的读取(预期慢3倍)
- (TSan):检测数据争用(预期速度为5x-15x,内存开销为5x-10x)
- (UBSan):各种本地未定义行为,如未对齐指针、整数/浮点溢出等。。。(最低速度减慢,代码大小略有增加)
消毒剂与防锈剂的对比 不幸的是,不可能使用杀菌剂使C++达到锈病的安全水平;即使将所有现有的消毒剂组合在一起,仍然会留下空白,众所周知,它们是不完整的 您可以在幻灯片上看到John Regher关于未定义行为的演示,我们从中获得当前的报道: 这并不能解释清洁剂彼此不兼容的事实。也就是说,即使您愿意接受组合的减速(15X-45 x?)和内存开销(15x30x?),您仍然不能管理C++程序的安全性。
强化与调试 清理器如此需要CPU/内存的原因是因为它们是调试工具;它们试图为开发人员提供尽可能精确的诊断,以便对调试最有用 对于在生产环境中运行代码,您需要的是强化。强化是指以尽可能低的开销消除未定义的行为。例如,Clang支持多种硬化二进制文件的方法:
- (CFI):防止控制流hi劫持(虚拟调用、间接调用等)
- :防止堆栈缓冲区溢出
- 未定义的行为消毒剂
结论 我没有看到任何方式将C++带入RID结合的安全级别,没有任何一个:
- 对语言的严格限制:参见MISRA/JSF指南
- 非常严重的性能损失:消毒剂、消毒剂