【问题标题】:libpcap - pcap_findalldevs() causing memory leak?libpcap - pcap_findalldevs() 导致内存泄漏?
【发布时间】:2021-06-08 02:17:03
【问题描述】:

我一直在学习使用 libpcap 库。按照手册,我编写了以下代码。它只是打印出本地操作系统上的所有网络接口。

#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char errbuf[PCAP_ERRBUF_SIZE] = {0};
    pcap_if_t *it = NULL;

    if(pcap_findalldevs(&it, errbuf) == 0) {
        while (it) {
            printf("%s - %s\n", it->name, it->description);
            it = it->next;
        }
        pcap_freealldevs(it);
    }
    else {
        printf("error: %s\n", errbuf);
        exit(-1);
    }

    return 0;
}

编译和运行的代码没有问题。但是,valgrind 报告说这个简单的代码确实存在内存泄漏:

$ valgrind --leak-check=yes ./hello_pcap 
==1824== Memcheck, a memory error detector
==1824== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1824== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==1824== Command: ./hello_pcap
==1824== 
ens18 - (null)
any - Pseudo-device that captures on all interfaces
lo - (null)
nflog - Linux netfilter log (NFLOG) interface
nfqueue - Linux netfilter queue (NFQUEUE) interface
==1824== 
==1824== HEAP SUMMARY:
==1824==     in use at exit: 845 bytes in 31 blocks
==1824==   total heap usage: 45 allocs, 14 frees, 44,033 bytes allocated
==1824== 
==1824== 845 (40 direct, 805 indirect) bytes in 1 blocks are definitely lost in loss record 16 of 16
==1824==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==1824==    by 0x48669A6: add_dev (pcap.c:1314)
==1824==    by 0x4866B77: find_or_add_dev (pcap.c:1266)
==1824==    by 0x4866C13: add_addr_to_if (pcap.c:1085)
==1824==    by 0x486345E: pcap_findalldevs_interfaces (fad-getad.c:266)
==1824==    by 0x48632CE: pcap_platform_finddevs (pcap-linux.c:1691)
==1824==    by 0x4866D65: pcap_findalldevs (pcap.c:721)
==1824==    by 0x1091AA: main (hello_pcap.c:10)
==1824== 
==1824== LEAK SUMMARY:
==1824==    definitely lost: 40 bytes in 1 blocks
==1824==    indirectly lost: 805 bytes in 30 blocks
==1824==      possibly lost: 0 bytes in 0 blocks
==1824==    still reachable: 0 bytes in 0 blocks
==1824==         suppressed: 0 bytes in 0 blocks
==1824== 
==1824== For counts of detected and suppressed errors, rerun with: -v
==1824== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

令我惊讶的是,我打电话给pcap_freealldevs() 试图释放内存,然后是manual

必须使用 pcap_freealldevs(3PCAP) 释放设备列表,这会释放 alldevs 指向的列表。

我似乎 pcap_freealldevs() 在这里不起作用?我想知道我可能做错了什么?

我在本地编译了最新的libpcap 1.10版本:

$ ls -l /usr/local/lib/
total 3412
-rw-r--r-- 1 root root  2344310 Jun  4 04:25 libpcap.a
lrwxrwxrwx 1 root root       12 Jun  4 04:25 libpcap.so -> libpcap.so.1
lrwxrwxrwx 1 root root       17 Jun  4 04:25 libpcap.so.1 -> libpcap.so.1.10.0
-rwxr-xr-x 1 root root  1131592 Jun  4 04:25 libpcap.so.1.10.0

并将代码编译为:

gcc -g -Wall -o hello_pcap hello_pcap.c -lpcap

使用 gcc:

$ gcc --version
gcc (Debian 8.3.0-6) 8.3.0

操作系统是 debian10 x64。

感谢您的帮助!

【问题讨论】:

  • it = it-&gt;nextit 更改为下一个元素。当你的循环结束时,it 变成了 NULL ,并且没有任何东西被释放。您应该保存指向 head 元素的指针并释放它。
  • @KagurazakaKotori 是的,我后来在答案中想通了。谢谢!

标签: c memory-leaks libpcap


【解决方案1】:

我发现原因是我在代码中犯了一个错误:

int main()
{
...
    if(pcap_findalldevs(&it, errbuf) == 0) {
        while (it) {
            printf("%s - %s\n", it->name, it->description);
            it = it->next;
        }
        pcap_freealldevs(it);
    }
...
}

while 循环结束后,it 最终变为 NULL。因此难怪 pcap_freealldevs() 如果给定一个 NULL 指针在这里不起作用。

添加 pcap_if_t 指针的附加副本以执行 while 循环:

int main()
{
    char errbuf[PCAP_ERRBUF_SIZE] = {0};
    pcap_if_t *ift = NULL;

    if(pcap_findalldevs(&ift, errbuf) == 0) {
        pcap_if_t *it = ift;
        while (it) {
            printf("%s - %s\n", it->name, it->description);
            it = it->next;
        }
        pcap_freealldevs(ift);
    }
    else {
        printf("error: %s\n", errbuf);
        exit(-1);
    }

    return 0;
}

正确释放内存并修复内存泄漏问题。谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-06
    • 2014-06-07
    • 2013-11-20
    • 2011-10-28
    • 2016-01-18
    • 2012-12-13
    • 1970-01-01
    • 2011-01-08
    相关资源
    最近更新 更多