Skip to content
Wireshark Wiki 中文翻译整理专题首页原始页面

优化 Packet List

当前的 packet list 实现在处理大型捕获文件时有一些严重缺陷。

它使用 GTKCList,后者有些不灵活,例如即使是当前未显示的内容,也需要将所有内容文本保存在内存中。

缺陷:

  • 巨大的内存消耗:我们必须在内存中保存(至少)info 列文本(这大约占一个 packet 内存消耗的一半!)

  • 所有 packet 的着色规则:会为所有 packet 处理着色规则,但实际上只有显示出来的 packet 才需要

  • 列无法更改:GTKCList 不允许在不退出并重启 Wireshark(或至少销毁该 widget)的情况下添加、删除或移动列

  • 并非所有 packet 都显示 ADNS 名称解析:当名称解析仍在进行时,已显示 packet 中不会显示名称解析(之后也不会更新)

  • 更改时间戳格式很慢:这需要重新生成 GTKCList(列?)

  • 垂直滚动条的已知 bug:参见 http://bugs.wireshark.org/bugzilla/show_bug.cgi?id=220

在处理大型捕获文件(>10MB)时,前两点对性能影响非常严重。分配大量内存需要时间,而为未显示的 packet 处理着色规则完全没有用。

优化这些内容将大幅提升处理大型捕获文件时的整体性能。

新设计

GTKCList 无法提供我们修复上述问题所需的功能。因此很明显,我们必须使用另一个 GTK widget,或者自己编写一个新的。

除了当前功能之外,它还应该:

  • 通过 callback 生成列内容,而不是在添加行时保存列文本
  • 允许动态更改列

第 1 个原型:GTKTreeView

根据 GTK+ API 参考,GTKClist(以及 GTKCTree)已被弃用,推荐使用 GTKTreeView,后者支持上述所有内容。遗憾的是,GTKTreeView 在 GTK+ 1.2 中不存在。

用 GTKTreeView 替换 GTKCList 似乎很直接,因为完整功能都封装在文件 gtk/packet_list.c 中 😃

我使用 GTKTreeView 做了一个原型实现,做起来并不困难,但之后遇到了一些严重问题:

  • 行使用更多显示空间:GTKTreeView 每行多使用 1-2px,最终屏幕上少显示几行。我甚至尝试实现自己的 GTKTreeCellRenderer,但无法限制空间使用
  • 与 GTKCList 相比,追加行明显更慢(耗时翻倍/翻三倍!)。我查看过 append 函数,但没有看到提升速度的方法

这个原型实现的文件已附上(注意,前方是丑陋的原型代码),以防以后可能需要……

结论:这不会兼容 GTK1.x,并且面临一些我无法解决的重大问题。由于 packet list 对性能非常关键,在这里不使用标准 widget 甚至可能是个好主意,这样我们可以精细调整行为…… - UlfLamping

完成原型

“新的” packet list 现在是默认实现!

通过使用我们自己的自定义 TreeView,大多数问题都已得到解决。使用新的 packet list 时,行确实会占用更多显示空间,但这可能是我们必须付出的代价。向列表添加行很快,因为只复制了很少的数据。

改进:

  • 加载一个 19Mb 文件(203950 个 packet)的时间从约 14s 降低到 < 4s。

  • 内存使用从约 170 Mb 降到约 113 Mb。

  • 应用着色很快,从 22s 降到不到 1s。

  • 更改时间格式很快,从 >4min 30s 降到不到 1s。

  • 更改时间参考很快,从 22s 降到不到 1s。

缺陷

  • 使用更多显示空间。
  • 排序也许更慢(做一次测量)。

尚未实现的功能:

  • 添加/删除列时重新创建 packet list。实现草图/想法:
  • 对 col_text 使用 GpointerArray,这样应该可以即时插入新的 index(column)。g_ptr_array_sort 可用于对列表排序(?)。将 packet 标记为 undissected 并调用 gtk_widget_queue_draw 应该会使用新列重新绘制 packet list。我们目前有 new_packet_list_recreate(),它会销毁 packet list 并创建一个新的。这必须重写。

未解决的问题:

  • 在 packet list 中通过 DnD 移动列时,更新内部结构(cfile.cinfo.*)。
  • 根据标题和内容长度正确调整列大小。
  • 启动时在 No. 列中添加缺失的排序指示器。
  • 从不匹配显示过滤器的 packet 中移除 Time Reference 时,选择下一个 packet。

已注意到的问题

  • [WMeier] SVN #29971 summary pane 和

details pane 之间先按 <Tab> 再按 <Shift Tab> 的行为并不完全一样……

从 summary 到 details 按 <Tab>,再按 <Shift Tab> 回到 summary 后,需要额外按一次下箭头才能下移 1 行。

代码中哪里处理 <Tab>?

jyoung 根据一些 Google 搜索,看起来 <Tab> 处理是由核心 GTK widget 原生处理的:

jyoung SVN #30025;理解 <Tab> 和 <Shift><Tab> 的问题。

  • <Tab> 和 <Shift><Tab> 会将焦点移动到 summary pane 中所选列的标签。

连续按六(6)次 <Tab> 会依次将焦点从 packet list(summary pane)中的所选 frame,移动到 details pane 中的所选元素,再到 hex pane,再到 toolbar 1 中最左侧的项目(list capture interfaces 按钮),再到 toolbar 2 中最左侧的项目(Filter: 标签),再到 summary pane 中所选列的标签,然后回到最初选中的 frame。因此,通过向前 Tab,我们可以回到起点(多按一次 <tab>)。

但在向后 TAB(<shift><tab>)时,焦点最初会从 packet list(summary pane)中所选 frame 移动到 summary pane 中所选列的标签;再到 toolbar 2 最右侧的项目("Apply");再到 toolbar 1 最右侧的项目("Show some help...");再到 hex pane;再到 details pane 中选中的项目;然后回到 summary pane 中所选列的标签。向后 TAB 时,焦点总是跳过 summary pane 中最初选中的项目。

我怀疑在适当的 callback 中插入 focus = gtk_window_get_focus(GTK_WINDOW(top_level)); 和 gtk_window_set_focus(GTK_WINDOW(top_level), focus); 会解决 <Tab> 和 <Shift><Tab> 问题。诀窍是弄清楚应将它们添加到哪个 callback(或哪些 callback)中。

  • jyoung SVN #30083;尝试复现 bug 4035 中报告的问题:"Application crash when changing real-time option"。我无法复现这个 bug。但我确实发现,在进行繁忙的活动捕获(线路上有大量 packet)时,summary portal 中的光标放置/移动存在一些问题。使用旧 packet list 时,我可以通过点击 summary portal 并按一次上箭头来停止 auto-scroll 功能。但在新的 packet list 中不会发生这种情况;列表会继续滚动。另外,当我禁用 "Auto Scroll in Live Capture"(通过菜单选项或点击 "Go back in packet history" 按钮)时,在向列表添加新 packet 的同时,我无法真正滚动浏览 packet list。光标会暂时出现在 frame 1 或也许 frame 2 上,然后消失,直到我再次按下箭头,光标才会瞬间重新出现在 frame 1 或 frame 2 上,随后又消失。

  • ABroman 最好能掌握剩余问题的情况;查看 bug 后,我发现以下仍然存在的 bug:见下面列表。其中一些可能已经在最近的提交中修复。也最好知道本页提到的其他问题还剩哪些。

Bugs

  • Bug 4056 - new_packet_list:启动后 Hex pane 显示问题。(部分修复)

  • Bug 4357 - new_packet_list:GtkTreeView::expander-size 决定 new packet list 记录的最小行高。

  • Bug 4445 - new_packet_list:summary pane 所选 frame 高亮未保持。GTK bug 618325

导入自 https://wiki.wireshark.org/Development/OptimizePacketList,时间为 2020-08-11 23:12:56 UTC

相关 Wireshark Wiki 页面

网络分析技术档案