关于服务器:Sanitizers-系列之-Sanitizers-概述

45次阅读

共计 2887 个字符,预计需要花费 8 分钟才能阅读完成。

Challenge

C/C++ 提供了间接操作内存的弱小能力,然而使用不当也会导致许多问题,上面是 Google chromium 团队的一组统计数据: 

“Around 70% of our high severity security bugs are memory unsafety problems (that is, mistakes with C/C++ pointers). Half of those are use-after-free bugs.”

与内存相干的问题往往排查难度较大,耗时较多。网易云信的 IM、RTC 等 SDK 都是应用 C/C++ 来进行开发的,作为软件供应商,网易云信面临的挑战更大:

须要反对更多的操作系统;

须要反对更多的开发框架。

上述挑战促使咱们应用更弱小、更通用的 Sanitizer 工具来帮忙工程师疾速排查与定位内存问题,进步生产力,本系列文章共四篇,旨在向读者介绍网易云信的工程实际,本文为第一篇。

Sanitizers 简介

Sanitizers 是由 Google 研发团队提出的用于检测 C/C++ 程序常见内存谬误的工具集,Google 工程师公开了它们的源代码和算法:

https://github.com/google/san…

并在 LLVM clang 上实现,它们曾经被用于多个工程中。比方 Chromium、Firefox 等出名我的项目中。

下表汇总整顿了 Sanitizers 的各个工具和它们的作用:

从表格的内容能够看出,Sanitizers 除了可能检测内存谬误外,还可能检测一些其它常见的谬误。前面笔者将分章节介绍上述几种 Sanitizer 的用法与原理。

Sanitizers 的劣势

以后市面上存在着多种用于检测内存谬误的工具,在投入生产应用之前,能够从如下维度来评估: 

在后续介绍各种 Sanitizer 工具时,会从上述几个维度进行介绍。Sanitizer 并不是第一个被创造进去用于检测内存谬误的工具,在它之前,同类的工具曾经十分多了,Sanitizer 其实是在前人的成绩上改良加翻新而来,因而它在上述几个方面比起同类工具有着劣势。

Sanitizers 具备如下劣势

与 Compiler 集成,支流 IDE 都提供了不同水平的集成,因而应用起来绝对简略;

目前支流 OS 的 Compiler 都可能不同水平上反对 Sanitizer,其通用性更强,因而对于须要跨平台的我的项目而言,它具备很大的劣势;

相比同类工具,可用性更强,老本更低;

能力更强,可能检测的谬误类型较多,诊断信息十分精确,可能帮忙疾速定位问题。

支流编译器对 Sanitizers 的反对状况

目前支流编译器都在肯定水平上反对 Sanitizers,本节整顿了 clang、GCC、MSVC 这三款支流编译器对 Sanitizers 的反对状况。

  • LLVM clang

Google 工程师最后在 LLVM clang 上实现了 Sanitizers,LLVM clang 对各种 Sanitizer 反对十分全面,具体能够参见 LLVM clang 的官网文档:

  • Apple clang

须要留神的是,Apple clang 是基于 LLVM clang 然而不是齐全照搬 LLVM clang,两者是存在区别的。目前 Apple clang 不反对 lsan,反对其它几种 Sanitizer,macOS 的 Instruments 工具提供了检测 Memory leakage 的能力。

  • MSVC

目前 MSVC 仅反对 asan,不反对检测 use-after-return 类谬误,从实际来看,MSVC 在开启 asan 后,在一些特定状况下会呈现比拟奇怪的问题,用户能够思考设计编译器版本。

更多内容参见:

https://github.com/google/san…

  • GCC

从实际和 GCC 反对的编译选项来看,GCC 不反对 msan,反对其它几种 Sanitizer。

更多内容参见:

https://gcc.gnu.org/onlinedoc…

What every programer should know about memory

在介绍正式的内容之前,咱们一起回顾一下对于 Memory 的常识。

Virtual memory

当今 OS 广泛采纳 Virtual memory 技术,下图形象地展现了 Virtual memory。

上图源自:

https://en.wikipedia.org/wiki…

Process memory address space

下图展现过程的地址空间布局:

上图源自:

https://en.wikipedia.org/wiki…

Memory error 分类

Memory error 的分类有多种,下表是依据 Sanitizer 工具的能力划分的一种分类形式:

在前面的章节中,对每一类谬误都会进行具体介绍,并提供具体的例子。

更多对于 Memory 的常识,参见:

https://en.wikipedia.org/wiki…

https://en.wikipedia.org/wiki…

https://people.freebsd.org/~l…

C++ 语言规范对 Memory 的形象

C++ 作为一门可能间接操作内存的语言,它的规范在语言层面对 Memory 进行形象,概括的说,每个 C++ object 会占用一片内存区域,依据 C++ object 所处的内存地位对 object 的分类如下:

下面表格中应用的“storage”术语其实是 C++ 语言规范应用的,读者能够参见: 

https://en.cppreference.com/w…

这个术语所表白的其实是 object 所占用的内存。本系列后续的文章将会对 heap object、stack object、global object 的不同类型的内存谬误进行介绍。

C++ 语言规范对 object lifetime 进行了标准,概括地说,一个 C++object lifetime 如下:

C++ 规范明确指出“access outside of object lifetime”是谬误的,读者能够参见:

https://en.cppreference.com/w…。

因为每个 C++ object 对应一片内存区域,这提醒咱们能够从 object lifetime 的角度来剖析 Memory error,在这里能够提前通知读者,前面行将介绍的很多内存谬误都能够纳入“access outside of lifetime”领域。

后续将持续推出 Sanitizers 系列文章之 Address Sanitizer 用法篇、Address Sanitizer 原理篇、Leak Sanitizer 介绍等相干文章,请大家继续关注。

参考资料

  • Memory safety: https://www.chromium.org/Home…
  • Introduction to Memory Unsafety for VPs of Engineering: https://alexgaynor.net/2019/a…
  • AddressSanitizerComparisonOfMemoryTools: https://github.com/google/san…
  • https://en.cppreference.com/w…
正文完
 0