Scapy使用奇怪的Python内存

时间:2015-06-29 13:27:29

标签: python mysql sqlalchemy

我编写了一个脚本,通过SQLAlchemy将pcapy中的mac地址记录到mysql中,我最初使用的是直接的sqlite3,但很快意识到需要更好的东西,所以这个周末过去我重写了所有的数据库谈话以符合SQLAlchemy。一切正常,数据进入并再次出现。我虽然sessionmaker()对我来说管理DB的所有会话非常有用。

我发现有关内存消耗的奇怪事件。我启动脚本...它收集并写入所有数据库...但是每隔2-4秒我的内存消耗量会增加兆字节。目前我正在谈论的记录很少,不到100行。

脚本序列:

  1. 脚本开始
  2. SQLAlchemy将mac_addr列读入maclist []。
  3. scapy获取数据包>如果new_mac在maclist []?
  4. 如果为真?只将时间戳写入时间戳列,其中mac = newmac。回到第2步。

    如果为false?然后将新的mac写入DB。清除maclist []并再次调用第2步。

    在1h30m后,我的内存占用量为1027MB(RES)和1198MB(VIRT),在1表数据库(MySQL)中有124行。

    问:这是否可以促成每次从DB清理和重新填充的maclist []?

    问:当它达到系统最大内存时会发生什么?

    任何想法或建议都会非常感谢。

    有问题的段的memory_profiler输出,其中list []从数据库mac_addr列填充。

    Line #    Mem usage    Increment   Line Contents
    ================================================
       123 1025.434 MiB    0.000 MiB   @profile
       124                             def sniffmgmt(p):
       125                              global __mac_reel
       126                              global _blacklist
       127 1025.434 MiB    0.000 MiB    stamgmtstypes = (0, 2, 4)
       128 1025.434 MiB    0.000 MiB    tmplist = []
       129 1025.434 MiB    0.000 MiB    matching = []
       130 1025.434 MiB    0.000 MiB    observedclients = []
       131 1025.434 MiB    0.000 MiB    tmplist = populate_observed_list()
       132 1025.477 MiB    0.043 MiB    for i in tmplist:
       133 1025.477 MiB    0.000 MiB          observedclients.append(i[0])
       134 1025.477 MiB    0.000 MiB    _mac_address = str(p.addr2)
       135 1025.477 MiB    0.000 MiB    if p.haslayer(Dot11):
       136 1025.477 MiB    0.000 MiB        if p.type == 0 and p.subtype in stamgmtstypes:
       137 1024.309 MiB   -1.168 MiB            _timestamp = atimer()
       138 1024.309 MiB    0.000 MiB            if p.info == "":
       139 1021.520 MiB   -2.789 MiB                        _SSID = "hidden"
       140                                          else:
       141 1024.309 MiB    2.789 MiB                        _SSID = p.info
       142                                      
       143 1024.309 MiB    0.000 MiB            if p.addr2 not in observedclients:
       144 1018.184 MiB   -6.125 MiB                    db_add(_mac_address, _timestamp, _SSID)
       145 1018.184 MiB    0.000 MiB                    greetings()
       146                                      else:
       147 1024.309 MiB    6.125 MiB                add_time(_mac_address, _timestamp)
       148 1024.309 MiB    0.000 MiB                observedclients = [] #clear the list
       149 1024.309 MiB    0.000 MiB                observedclients = populate_observed_list() #repopulate the list
       150 1024.309 MiB    0.000 MiB                greetings()
    

    您将看到observeclients是有问题的列表。

4 个答案:

答案 0 :(得分:7)

我设法找到了内存消耗的实际原因。它本身就是傻瓜。默认情况下,Scapy设置为存储它捕获的所有数据包。但你可以禁用它。

停用

sniff(iface=interface, prn=sniffmgmt, store=0)

启用:

sniff(iface=interface, prn=sniffmgmt, store=1)

感谢BitBucket Ticket

答案 1 :(得分:1)

正如您所看到的,分析器输出建议您最后使用较少的内存,因此这不能代表您的情况。

深入挖掘的一些方向: 1)add_time(为什么增加内存使用量?) 2)db_add(为什么它会减少内存使用量?缓存?关闭/打开数据库连接?发生故障时会发生什么?) 3)populate_observed_list(垃圾收集的返回值是否安全?可能是某些数据包发生了某些异常?)

此外,如果您嗅探的数据包超出您的代码能够处理的性能,会发生什么?

我会分析这3个函数并分析可能的异常/失败。

答案 2 :(得分:0)

如果没有代码,很难说什么,假设它不是SQLAlchemy或scapy中的泄漏而不是代码(似乎不太可能)。

您似乎知道泄漏可能发生的位置,请执行一些memory profiling以确定您是否正确。

一旦你的python进程占用了足够的内存,你可能会得到MemoryError例外。

答案 3 :(得分:0)

感谢大家的指导。我想我设法解决了不断增加的内存消耗。

答:正如我所了解的,代码逻辑在内存消耗中起着非常重要的作用。 如果你在我的初始问题中查看memory_profiler输出,我将第131-133行移到第136行的IF语句中。这似乎不会如此频繁地增加内存。我现在需要更多地改进populate_observedlist(),以免浪费太多内存。