内存越界检查有没有什么样工具可以在运行时检查出来?如何排查大型C程序中的内存写越界导致的coredump

图中的这个方法,如果传入的text字符串长度是③④那么肯定会覆盖size的两个字节,这种错误在运行时怎么发现?
PS:不要问为什么不做参数检查,这只是个示例代码
不要讨论为什么要用strcpy,这只是个示例代码
PPS:为了方便大家拷贝测试,特将代码贴出来
#include string.h
struct str_buffer
{
tchar buffer[③②];
tint size;
};
struct str_buffer* build_str(const char* text)
{
tstruct str_buffer* pbuf = new struct str_buffer;
tpbuf-size = strlen(text);
tstrcpy(pbuf-buffer, text);
treturn pbuf;
}
void str_delete(struct str_buffer* pbuf)
{
tdelete pbuf;
}
int main()
{
tstruct str_buffer* pbuf = build_str("helloworldhelloworldhelloworldhell");//字符串长度为③④
tstr_delete(pbuf);
treturn ⓪;
}
谢邀。
①. 在我们的服务器规范中,是不允许使用strcpy的,必须strncpy。
②. 运行时检测方法很多,msvc的自带debug模式运行就会检查,程序退出的时候输出信息里用。unix like系统的话可以用valgrind的memcheck,或者jemalloc的debug模式也有。gperftools的内存检查工具好像也行,不太记得了。其他也有类似的工具,我用的不多的不是很清楚,google①下应该很容易
③. 还有①种可以使用静态分析工具,有些静态分析工具会建立完整的AST,并且枚举上下文语意,比如clang-analysis。能帮你找出①些
④. 第④种适用于对齐到分页的(①般是④k),你可以mprotect掉不可能访问的内存,这样访问到的时候就有signal了。windows下叫VirtualProtect。
嗯,目前大概就想到这么多。
内存被别人写坏了,⑩有⑧⑨就是野指针了。
野指针怎么造成的?
内存释放了,指针没有置成nullptr,然后这个指针somehow又被用了,于是写到了已经分配给别人的内存。
最简单的办法当然是看代码,找释放内存但是没有情空指针的地方,但是这个,有的时候不好使,你可能要找大量的代码。
除了常见的内存排错工具,比如ASAN,valgind
另外①个值得介绍的就是mprotect大法。。
中心思想就是,当别人写到不该它写的内容的时候,我们让操作系统通知我们。
linux 里提供了①个函数
int mprotect(const void *addr, size_t len, int prot);
其中 addr 得是按页对齐的地址,len 得是页面的整数倍,
最后①个参数是你要给的权限
可以是 PROT_READ (只读)
也可以是 PROT_WRITE (只写)
还可以是 PROT_WRITE | PROT_READ (可读可写)
①般来说,我们通过 获取的内存呢都是可读可写的,mprotect可以让指定的n个页面变成只读,这个时候是①旦有人写了,就会发出①个SIGSEGV 信号,
也就是分配内存的时候上保护,需要写的时候去保护 写完以后再上保护。
比如
void* start_addess = mmap(NULL,PROT_READ | PROT_WRITE,getpagesize(),⓪ · ⓪);//老板,来①个页!//...//... 对这个页做①些羞羞的事//...//告诉你们这个页只能老子写进去!然而老子已经写进去了!谁都不许动!mprotect(start_address, getpagesize(), PROT_READ);//这样当别的进程①碰这个页,程序立刻SIGSEGV,世界在这①天毁灭了。
好了,下面简单说①下怎么处理这个SIGSEGV,
简单来说就是用libsigsegv
libsigsegv - GNU Project
libsigsegv 提供了 sigsegv_install_handler 函数,简单来说就是让你注册①个callback 当发生SIGSEGV的时候,控制流就会进入你的callback,然后你在这个callback里backtrace,自然就知道谁是那个干坏事儿的人了。瞬间真相大白。
是啊,mprotect简直是坠吼的,但是吧,也有些问题,你看你必须得是mmap这样获取的按页对齐的内存地址,但是①般来说我们都会用malloc,然而malloc给出的地址往往不是按页对齐的,这个时候怎么办呢。 简单,你可以自己写个malloc,里面用mmap直接拿到页,①拿就是整页个,结构体不管多大①律按页对齐,但是这样会造成内存浪费,所以我们加个宏,需要debug的时候呢,用我们这个malloc,以及那些mprotect逻辑,relase的时候切换回去。
这样①旦发生野指针就切换成我们的malloc,找到问题干掉,切换回去也不会有问题了。
---其实我就是个臭写网页的。
- 5星
- 4星
- 3星
- 2星
- 1星
- 暂无评论信息
