Yukang's Page

valgrind

2011-05-06


纪念一下跑测试跑了几天才找出的一个内存泄漏,这个函数源于UNP,还以为UNP有bug呢,找到原书当getaddreinfo失败或者res==NULL的时候直接退出了。但是写这个代码的同学当然不想连接不上直接退出,于是忘记了freeaddrinfo调用直接返回,那个struct addrinfo就没释放。很多错误都是这种,涉及到库函数的时候更加难查。


int tcp_connect(const char host, const char serv)
{
int sockfd, n;
struct addrinfo hints, res, ressave;

bzero(&hints, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;

if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0)
{
log_sprintf(“tcp_connect error for %s, %s: %s”, host, serv, gai_strerror(n));
freeaddrinfo(res); //oops: memory leak

return -1;
}
ressave = res;

do {
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sockfd < 0)
continue; / ignore this one /
if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
break; / success /
close(sockfd); / ignore this one /

} while ( (res = res->ai_next) != NULL);

if (res == NULL) / errno set from final connect() /
{
log_sprintf(“tcp_connect error for %s, %s”, host, serv);
freeaddrinfo(ressave); //oops: memory leak
return -1;
}
freeaddrinfo(ressave);
return(sockfd);
}


上一篇博文中说到自己包装的内存检测方法,这还有个问题当时没发现,就是那个包装malloc之类的方法对于库函数中的内存申请调用没法记录,所以是不会发现上面这个bug的。这个Memwatch倒是把原生的malloc都重定义了,但是最好的Linux下检测内存泄漏的工具还是valgrind,这真是个神器,在代码上不用做一点修改,这东西甚至能测试程序的cache命中率。看了一下valgrind的相关论文,对于检测方法都是一种称之为shadow value的方法,也就是用信息来记录每一个byte内存的使用情况。这种方式的一个缺点都是会拖慢速度,前面提到的那种稍微包装了一下的方式可能还好(因为使用的是静态数组), Memwatch里面使用了不少链表也会拖慢速度。再看看valgrind的实现,以后工作可能会碰上类似的。

更多valgrind

更多Memwatch

Tags: Tools
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章