代码 bug 嗅探器:Sanitizer

Android native开发严重问题总结 本文用于总结开发过程中遇到的重要问题分析原因及其解决方案 1、libnativeloader.so" is not accessible for the namespace “classloader-namespace” 原因:安卓高版本中将会限制三方APP访问非NDK公开so库,即不能访问system/lib/lib64下面的私有so库。 两种情况的解决方案: 第一:若是系统system app,该问题的产生原因是app是通过install的,这样不可行,必须将该模块在编译产品后的system/app路径 阅读详情

代码 bug 总在不经意间出现,导演了一出出 crash 的悲剧。为了扼杀 bug 于襁褓之中,本文介绍的主角 Sanitize 挺身而出,致力于解决内存泄露、缓冲区溢出和未定义行为。

本文将从原理来探索 Sanitize 的相关能力实现,介绍 ASan、MSan、UBSan、TSan,而关于如何使用,在官方教程都有,不会过多介绍。

AddressSanitizer (ASan)

ASan 是用来检测 释放后使用(use-after-free)、多次释放(double-free)、缓冲区溢出(buffer overflows)和下溢(underflows) 的内存问题。

该工具包含有编译器插桩模块(a compiler instrumentation module,现在是一个 LLVM 的 pass 了),还有一个运行时的库用来替换 malloc 函数。

插桩模块主要用在栈内存上,而运行时库主要用在堆内存上。

run-time library

ASan 的运行时库会使用 __asan_malloc 来替换掉所有对 malloc 的调用。

在 malloc 函数所分配的字节周围,插入雷区,对于 free 释放掉的内存进行投毒,从而跟踪 malloc / free 行为。

void *__asan_malloc(size_t sz) {
    void *rz = malloc(RED_SZ);  // 上接雷区
    Poison(rz, RED_SZ);
    void *addr = malloc(sz);    // 真正分配的内存
    UnPoison(addr, sz);
    rz = malloc(RED_SZ);        // 下接雷区
    Poison(rz, RED_SZ);
    return addr;                // 返回分配的内存首地址
}

Instrumentation

ASan 的编译器插桩模块,会对每一个 store 和 load 的内存读写指令,进行编译时的插桩。

可以在上图的代码部分看到,ASan 在使用的内存周围,插入了 instrumented code。

在 x86_64 平台上,其插桩后的指令如下:

# long load8(long *a) { return *a; }                 # 原函数实现
0000000000000030 <load8>:
  30:   48 89 f8                mov    %rdi,%rax               # 读取参数
  33:   48 c1 e8 03             shr    $0x3,%rax               # 右移 3 位,获取影子内存的操作
  37:   80 b8 00 80 ff 7f 00    cmpb   $0x0,0x7fff8000(%rax)   # 对对应的影子内存判断值是否异常
  3e:   75 04                   jne    44 <load8+0x14>         # 如果不正常则跳到第 9 行,0x44
  40:   48 8b 07                mov    (%rdi),%rax   <<<<<< original load 原本的操作
  43:   c3                      retq   
  44:   52                      push   %rdx
  45:   e8 00 00 00 00          callq  __asan_report_load8      # 报错

Mapping

虚拟内存空间会被划分为以下两个类别:

  • Main application memory 主应用程序内存:即应用程序代码所使用的内存。
  • Shadow memory 影子内存:即包含有影子数据的内存。与主应用程序内存相关,对主存的一个字节投毒,意味着在对应影子内存中写入特殊数据。
shadow_address = MemToShadow(address);
if (ShadowIsPoisoned(shadow_address)) {
  ReportError(address, kAccessSize, kIsWrite);
}

ASan 会把 8 字节的程序内存映射为 1 字节的影子内存。

这 1 字节会保存一个值,来表示程序内存的状态(对齐状态下):

  • 0,表示整个 8 字节内存都正常
  • 负数,表示整个 8 字节内存都被投毒了
  • k,表示头 k 个字节正常、后 8-k 个字节被投毒了

对于不对齐的内存读取,需要采用特殊处理。以下是越界读取(out-of-bound,OOB)的案例:

int *x = new int[2]; // 8 bytes: [0,7].
int *u = (int*)((char*)x + 6);
*u = 1;  // Access to range [6-9]

不对齐的内存读取,其开销是很大的,所以编译器和运行时内存分配器一般会优化代码,来使大多数的内存读取是对齐的。

对比

ASan 性能影响大概 ~2x,内存影响大概 ~2x。

MemorySanitizer (MSan)

ASan 无法覆盖到未初始化的内存,对于未初始化的内存,进行读取的行为同样危险,这时候就需要 MSan 出马了。

MSan 实现的是一个 bit to bit 的影子内存,每一比特都有映射,所以在计算影子内存的位置时,十分高效。

0 代表已初始化过的,1 代表未初始化的,所以开始时,影子内存填满了 0xFF。

MSan 的性能开销大概 ~3x,内存开销大概 ~2x。

Shadow propagation

大多数编译器,是允许加载未初始化 int 或 float 值,来达到期望的效果的。

而且在类或结构体中,对其中内存对齐的部分的加载,也应该是合乎逻辑的。

所以 MSan 允许对未初始化内存的复制、以及一些安全的操作的。为了能达到这一目的,MSan 实现了 shadow propagation。

对于未初始化内存的读取结果是 undefined value(未定义值),它会被临时赋值给一个 shadow value(影子值) 来管理,然后当 application value(程序里的变量值) 被保存时,把这个 shadow value 存到对应的影子内存中。

某一些对 application value 的操作,需要是已初始化的,包括 conditional branch(有状态跳转)、system call(系统调用)、pointer dereference(解指针)。

instrumentation 主要就是对这些操作,进行封装插桩。

MSan 还能开启溯源操作,将源头的 shadow value 传播出去。

run-time library

除了插桩指令以外,MSan 同样需要运行时库的支持,用来在启动时,将低地址内存设置为不可读,然后映射为影子内存。

被 malloc 返回的内存、以及被 dealloc 的内存、局部的栈对象都会被标记为未初始化的。

UndefinedBehaviorSanitizer (UBSan)

UBSan 主要就是检查未定义行为(undefined behavior),包括有符号整型溢出、空指针的使用、除 0 操作、越界读取等。

UBSan 在编译时对可疑操作进行插桩,以捕获程序运行时的未定义行为,如果检查到是 UB 行为,则会调用 __ubsan_handle_ 函数进行处理,输出报错信息。

UBSan 会有 ~1.25x 的性能开销,不会有内存开销。

ThreadSanitizer (TSan)

TSan 用来检查数据争用(data race)、死锁(deadlock) 的。

当多个线程同时操作同一个变量的时候,而至少一个的操作是写操作时,就会发生数据争用。

当多个线程因争夺资源而造成的一种互相等待的想象,若无外力介入,它们都无法继续推进,就是死锁。

TSan 需要所有代码都以 -fsanitize=thread 编译参数进行编译,不然某些代码可能会导致误判。

TSan 会有 2x~20x 的性能开销,有 5x~10x 的内存开销。

state machine

TSan 的运行时主要是维护了状态机的使用,对 libc/pthread 的大部分函数也进行了拦截操作。

程序执行可以看作是一连串的事件:

  • 内存存取事件:读、写
  • 同步事件:锁、happen-before(signal & wait)

TSan 包含有全局的和 内存 ID (per-ID,a unique ID of a memory location) 的状态。全局状态是关于同步事件的信息,而 per-ID 状态是内存地址的信息。

下图中的 SS 代表 set of segment,segment 表示一个线程上包含的一连串的内存存取事件,比如对于一个内存 ID 而言,SSWr 表示对某个内存 ID 进行读操作的事件的集合。

判断是否存在数据争用,其主要逻辑是:对同一内存 ID 进行操作时,却没有进行相同的锁来限制。

还有很多的状态机算法,就不过多介绍了,在文末论文链接可以查看。

Instrumentation

在编译时,TSan 会在每一个内存存取操作、函数的调用、函数的 entry 和 exit 进行插桩。

同样,TSan 会采用影子内存来存取相关的信息。

参考

sanitizers:https://github.com/google/sanitizers

Be Wise, Sanitize - Keeping Your C++ Code Free From Bugs:https://m-peko.github.io/craft-cpp/posts/be-wise-sanitize-keeping-your-cpp-code-free-from-bugs/

AddressSanitizer:https://clang.llvm.org/docs/AddressSanitizer.html

AddressSanitizer - wiki:https://github.com/google/sanitizers/wiki/AddressSanitizer

Automated Test-Case Generation:Address Sanitizer:https://ece.uwaterloo.ca/~agurfink/stqam.w20/assets/pdf/W04-ASan.pdf

《MemorySanitizer: fast detector of uninitialized memory use in C++》:https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43308.pdf

UBSan: run-time undefined behavior sanity checker:https://lwn.net/Articles/617364/

《ThreadSanitizer – data race detection in practice》:https://static.googleusercontent.com/media/research.google.com/zh-TW//pubs/archive/35604.pdf

Finding races and memory errorswith LLVM instrumentation:https://llvm.org/devmtg/2011-11/Serebryany_FindingRacesMemoryErrors.pdf

ThreadSanitizer, MemorySanitizer:https://llvm.org/devmtg/2012-11

理解ASAN的shadow memory和读懂报错信息 什么是ASAN ASAN(Address Sanitizer)是一个内存检测工具。gcc4.8版本及以上自带。支持多平台(x86, ARM, MIPS (both 32- and 64-bit versions of all architectures), PowerPC64)、多操作系统(Linux, Darwin (OS X and iOS Simulator), FreeBSD, Android)。 ASAN主要由两部分构成:instrumentation module和run-time librar 阅读详情

相关推荐

tinyalsa tinyplay播放音频报错

tinyplay 使用usb声卡设备播放音频文件时候报错,这个文件用aplay播放是正常的。原因是音频文件格式和声卡支持的格式不一致。这里只需要把wav文件格式改为 48k 双通道,就行了。

JCYAO_的博客 1720

ASAN报错汇总

启动错误:Shadow memory range interleaves with an existing memory mapping. ASan cannot proceed correctly. ABORTING ASan shadow was supposed to be located in the [0x1ffff000-0x3fffffff] range. 地址消毒使用影子内存判断读...

qq_23350817的博客 5334

保姆级教程:用Python+OpenCV搞定Orbbec Gemini深度与彩色流对齐(附完整代码)

本文提供了一份详细的Orbbec Gemini深度与彩色流对齐教程,涵盖从环境配置到完整代码实现的每一步。通过解析深度流对齐原理,对比不同对齐模式,并提供工业级应用中的问题排查方法,帮助开发者快速掌握Orbbec Gemini相机的使用技巧。文章还包含进阶应用如点云生成与三维重建的实战代码。

weixin_29090917的博客 470

程序分析-klee查找bug过程

klee查找bug的过程

qq_44370676的博客 1666

C语言专升本编程题

湖南省专升本选拔考试,C语言程序设计内部习题

weixin_45729947的博客 2117

Mask2former自定义数据集实现滑坡语义分割

先介绍一下这次用的数据集:Bijie Landslide Dataset,是武汉大学在Triplesat卫星上裁剪的数据集,包含770张滑坡(image、mask、dem、边界坐标txt)和2003张非滑坡数据(dem、image)。直接在ade20k修改,按照路径和设置将预处理数据放好,该步骤很快就能结束,打开的图片是全黑的,因为0和1在图片上肉眼较难区分。bijie的数据集可以直接使用,接下去的步骤是1、预处理数据。配置文件修改训练类别和训练类型,由于我们分割的是滑坡,所以进行语义分割。

weixin_57812838的博客 2216

面向开发的内存调试神器,如何使用ASAN检测内存泄漏、堆栈溢出等问题

GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。 [toc] 介绍 首先,先介绍一下 Sanitizer 项目,该项目是谷歌出品的一个开源项目,该项目包含了 ASAN、LSAN、MSAN、TSAN等内存、线程错误的检测工具,这里简单介绍一下这几个工具的作用: ASAN: 内存错误检测工具,在编译命令中添加-fsanitize=address启用 LSAN: 内存泄漏检测工具,已经集成到 ASAN 中,可以通过设置环境变量ASAN_OPTIONS=detect_leaks=.

GreatSQL2021的博客 7046

VHDL按键消抖(状态机版本)

检测下降沿:设置一个和,分别代表之前的之前和之前的信号状态,若两个信号key_in_d2=1,key_in_d1=0,他俩的not key_in_d2 and key_in_d1为1,则说明下降沿产生,把它设置为标志位key_flag。延时计数:50MHz的板子每次计数需要20ns,而抖动时间大约为5-10ms。所以取7ms,作为延时时间。可以看见当检测到下降沿时,开始计数计数计满再次检测,若为低电平则为按下按键,否则为抖动。通过检测下降沿来临,延时计数再次检测,如果为低电平则为按键按下。

qq_69639216的博客 1084

Sanitizer-代码问题嗅探器介绍

本文主要从Sanitizer相关的实现探索其使用的场景,ASan,MSan,UBSan,TSan;介绍其如何解决内存泄漏,缓存区溢出和未定义行为的bug问题

u010830462的博客 1811

R 绘制环形树状图

按大类小类的从属关系绘制环形图,并把不同值的节点设置为相应大小。要求同一类的节点应为同一颜色。 按照输入,处理代码和输出记录

weixin_43718786的博客 1873

CANbus收发器TJA1051T/3/1J应用原理图设计

该收发器是为汽车工业中的高速CAN应用而设计的,为(一个带有)CAN协议控制器的微控制器)提供差分传输和接收能力。它提供了改进的电磁兼容性(EMC)和静电放电(ESD)性能,还具有:当电源电压关闭时,TJA1051T/3和TJA1051TK/3可以直接与电源电压从3V到5V的微控制器接口。这种实现能够在CAN FD快速阶段以高达5 Mbit/s的数据速率进行可靠的通信。TJA1051T/3和TJA1051TK/3上的VIO输入允许直接连接3 V至5 V微控制器(分别提供SO8和极小的HVSON8封装)

zhusl6688的博客 3599

AddressSanitizer 和 valgrind 和mprotect+libseg。。。

1)./configure --prefix=/home/xiaoming/valgirnd-install/ --enable-only32bit \ //linux32 ./configure //若有configure关于glibc版本问题可以修改configure中版本检测:加上本地glibc的版本支持 make make install //测试后因为程序有大数组,错误: val...

makeiteasier的博客 1162

52-Halcon-- smooth_object_model_3d函数功能(滑处理3D对象模型)

Halcon中smooth_object_model_3d算子详解 该算子用于3D模型平滑处理,提供三种算法:'laplacian'(快速去噪)、'taubin'(高质量防收缩)和'low_pass'(频域滤波)。核心参数包括迭代次数(默认5)、平滑强度(0-1)和边缘保护选项。典型应用包括扫描数据去噪、CAD模型光顺和逆向工程优化。支持自适应平滑、结合模型简化等高级技巧,并可通过分块处理优化大型模型性能。参数组合需根据具体场景选择,如快速去噪推荐拉普拉斯方法(5次迭代,强度0.3),特征保持推荐低通滤波(

weixin_45590420的博客 873

iOS7.1以及iOS9.2与之前的不同

先说下要适配iOS9要做的事: 1.更改http为https  两种方案: 一.公司后台服务器更改; 二.作为开发者,可在Xcode暂时退回到http协议.  开发者更改方法如下: 1.在Info.plist中添加App Transport Security Settings (或NSAppTransportSecurity), 类型Dictionary。 2.在A

ZZ825194632的博客 2200

ppt保存时嵌入字体,但找不到字体使用的位置的解决办法

摘要 当PPT提示无法保存嵌入字体时,可通过VBA代码快速定位使用该字体的文本。具体步骤如下: 按ALT+F11打开VBA编辑器,新建模块并粘贴提供的代码; 运行代码后输入目标字体名称(如“方正兰亭黑简体”); 程序将列出所有使用该字体的幻灯片编号及对应文本内容; 修改这些文本的字体即可解决保存问题。该方法高效精准,适用于排查PPT字体嵌入失败的情况。(150字)

智慧空间实验室 1401

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

非法检测之UBSAN

UBSAN:全称Undefined Behavior Sanitizer,用于运行时检测一些未定义行为。未定义,是一个统称,并非是代码中的变量等没有定义,如果是此类错误,编译就会进行拦截。此含义就可以理解为一个非法行为的检测,比如定义的变量超过范围,数组使用不正确的下标,左右移不符合规范,或者超过变量的范围,对齐不匹配等等。

fangjun791350的博客 5670

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Sanitizers 系列之 address sanitizer 原理篇

本文主要介绍asan的算法,asan的各种优势本质上是源自于它的算法,本节的内容主要基于 asan 的论文 《AddressSanitizer: A Fast Address Sanity Checker 》。

netease_im的博客 1258

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

20190ctf ageis

Analysis checksec franex@franex-virtual-machine:~/桌面/babyaegis$ checksec aegis [*] '/home/franex/\xe6\xa1\x8c\xe9\x9d\xa2/babyaegis/aegis' Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE:

qq_46441427的博客 1103

Asan检测原理(AddressSanitizerAlgorithm chatgpt翻译记录)

这是由malloc返回8字节对齐的内存块所保证的。唯一的情况是对齐的qword的不同字节具有不同的状态,是malloc分配的区域的尾部。例如,如果我们调用malloc(13),我们将有一个完整的未污染的qword和一个有5个未污染字节的qword。free将整个区域的阴影值标记为污染,并将内存块放入隔离队列中(这样在某段时间内,malloc不会再次返回该块)。相应于红区的阴影值被标记为污染,主内存区域的阴影值被清除。AddressSanitizer将应用程序内存的8个字节映射为影子内存的1个字节。

qq_33243369的博客 1117

FAQ for ASAN on Android10/Android11/Android12/8155/8295

FAQ for ASAN on Android10/Android11/Android12/8155/8295

漂流瓶の海岸 3400

GCC软件内存使用问题定位方法

GCC软件内存使用问题定位@TOC AddressSanitizer介绍 AddressSanitizer is a fast memory error detector. It consists of a compiler instrumentation module and a run-time library. The tool can detect the following types of bugs: Out-of-bounds accesses to heap, stack and glob

StarEmbedded的博客 781

AddressSanitizer 内存检测工具

还有另一个内存检查工具valgrind 转自:https://code.google.com/p/address-sanitizer/ AddressSanitizer: a fast memory error detector Updated Apr 22, 2014 by konstant...@gmail.com IntroductionGet

haima1998的专栏 1万+

Linux中的常用内存问题检测工具

C/C++等底层语言在提供强大功能及性能的同时,其灵活的内存访问也带来了各种纠结的问题。如果crash的地方正是内存使用错误的地方,说明你人品好。如果crash的地方内存明显不是consistent的,或者内存管理信息都已被破坏,并且还是随机出现的,那就比较麻烦了。当然,祼看code打log是一个办法,但其效率不是太高,尤其是在运行成本高或重现概率低的情况下。另外,静态检查也是一类方法,有很多工具(lint, cpp

世事难料,保持低调 4万+

异常处理与MiniDump详解(4) MiniDump

在此我非常感谢博客版主 九天雁翎(JTianLing) 先生/女士 做出的辛苦劳动,写了这么好的文章,本人受益匪浅,特此感谢!原文地址:http://blog.youkuaiyun.com/vagrxie/archive/2009/07/31/4398721.aspx 异常处理与MiniDump详解(4) MiniDumpwrite by 九天雁翎(JTianLing) -- blog.csd

1827

通过asan和tsan对内存越界、内存泄露、死锁等进行检测

ASan/TSan的性能开销通常比Valgrind/Helgrind低,ASan/TSan是通过编译时插入的代码来检测内存错误,因此在运行时的性能开销相对较小。注意:tsan的死锁检测是基于运行态(data race也一样),只有当thread2_main函数被执行到时,死锁问题才能被发现,所以需要完备的测试用例覆盖尽可能多的分支。AddressSanitizer(ASan)是一种内存错误检测工具,可以帮助我们发现C/C++程序中的内存错误,如缓冲区溢出、使用已释放的内存、内存泄露等。

qq_37174816的博客 2483
上一篇: 跨语言调 C 库:DragonFFI
下一篇: 【译】LLVM 类型相等判断
流左沙
博客等级 码龄11年 46粉丝 55原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值