Appearance
Appearance
有时你只是想查看一些变量,看看代码中发生了什么,而不需要进行一次重量级的调试器会话。在这些情况下,printf 可能是你最好的朋友。要让它工作,你需要:
启动 Wireshark,并进入 Edit->Preferences...->Advanced。在 Search: 框中输入 "console",然后在搜索结果中选择 gui.console_open。将 Value 改为 'ALWAYS',然后点击 Ok 按钮。
$ tshark --log-level=noisy --log-domain=main,capture --log-file=/tmp/wsdebug -r some.pcap如果你关注某个条件,可以将以下内容添加到代码中:
if (condition) { g_print("Kilroy was here\n");}请注意,printf/g_print 不适用于 dumpcap(例如 capture_loop.c),因为 stdio 被用于与 Wireshark 的捕获引擎通信。请改用 g_log 或 g_printerr。
在找到 bug 之后,不要忘记稍后移除这些语句。这些类似 printf 的语句不应在生产代码中保持启用,因为它们经常会打扰不关心这些信息的用户。
通常你知道自己的 dissector 中有一个 bug/问题,而且只能在某个特定数据包中找到。
假设你知道编号为 1234 的数据包有 bug,那么可以将以下内容添加到代码中:
if (pinfo->fd->num == 1234) { g_print("Here is my bug\n");}然后只需在 g_print 调用处设置断点。
当然,你需要能够访问 pinfo,但在任何 dissector 中通常都应如此。
在找到 bug 之后,不要忘记稍后移除它 😃
某些调试器(例如 gdb 和 MSVC)也允许你设置条件断点;你可以在某个例程中的某个位置设置断点,并将断点条件设为 pinfo->fd->num == 1234。
摘自 http://www.gnu.org/software/libtool/manual/libtool.html#Debugging-executables
如果你想在安装应用程序之前,在 UNIX 上调试自己构建的 Wireshark,就必须通过 libtool 运行 GDB,如下所示:
user@host:~/src/wireshark$ libtool --mode=execute gdb wiresharkDDD 是 GNU 为 GDB 命令行调试器(以及其他调试器)提供的图形化前端。http://www.gnu.org/software/ddd/
为了帮助 DDD 在调试时定位源文件,可以先 "cd" 到这些源文件所在的目录,然后通过 libtool 启动 DDD(和 GDB 一样),或者在 DDD 菜单中查看 "Edit" -> "GDB Settings..." -> "Search path for source files",并在那里显式添加路径。
如果你正在调试,而优化造成了问题(例如,单步执行代码时显示的行号似乎与实际执行内容不一致),请将 CMAKE_BUILD_TYPE 设置为 Debug,以便在构建时禁用优化,步骤类似如下:
mkdir buildcd buildcmake -DCMAKE_BUILD_TYPE=Debug ..makegdb run/tshark反复输入 libtool --mode=execute 很快会让人厌烦。在大多数 shell 中,你可以创建一个快捷方式来减少输入量。
Bourne 风格的 shell:
function lx{ glibtool --mode=execute $*}C 风格的 shell:
alias lx 'glibtool --mode=execute'使用此快捷方式,上面的 GDB 示例可以缩短为:
user@host:~/src/wireshark$ lx gdb wiresharkValgrind 会动态分析程序,并且非常擅长捕捉与内存相关的错误。不过,在使用默认块内存分配器时,它无法捕捉 Wireshark 内存管理框架(wmem,在 wsutil/wmem/ 中实现)中的 bug。幸运的是,你可以在运行时告诉 Wireshark 改用 wmem 的 "simple" 分配器,该分配器使用 malloc 和哈希表,对 Valgrind 友好:
export WIRESHARK_DEBUG_WMEM_OVERRIDE=simple类似地,GLib 的 GSlice 内存分配器(某些未使用 wmem 的 Wireshark 代码会用到它)也可以通过另一个环境变量改为使用 malloc:
export G_SLICE=always-malloc假设你已经定义了 lx 快捷方式(见上文),你可以像这样检查内存问题:
lx valgrind --tool=memcheck tshark -nVxr /path/to/capture.pcap > /dev/nullAddressSanitizer(ASAN)可以在运行时捕捉内存安全问题,包括 use-after-free、double-free、buffer overflow 和 memory leaks。它需要 GCC 或 Clang,并可在 Linux 和 macOS 上运行。不支持 Windows 上的 MSVC。
要开始使用,请用 cmake -DENABLE_ASAN=1 构建 Wireshark。
注意:ASAN 会使速度降低 2 倍(或更多),因此为 ASAN 构建单独准备一个构建目录会很有用。
使用 ASAN 调试时,多种环境变量会很有帮助。
wmem 使用的块分配器可能会阻止 ASAN 捕捉某些错误。要检测错误,可以像使用 Valgrind 时那样使用基于 malloc 的分配器,或者将 wmem 和 GSlice 的内存分配器设置为会通过 canaries 跟踪内存使用并检查已释放内存的分配器(ASAN 比 Valgrind 更擅长处理这些情况):
export WIRESHARK_DEBUG_WMEM_OVERRIDE=strictexport G_SLICE=debug-blocks在调查内存泄漏时,以下选项可能很有用:
# This slows down a lot more but results in more precise backtraces,# especially when calling C++ standard library functions.export ASAN_OPTIONS=fast_unwind_on_malloc=0# This causes LeakSanitizer to print the addresses of leaked objects# for inspection in a debugger.export LSAN_OPTIONS=report_objects=1如果你只关注内存安全检查,而不进行内存泄漏调试,只需使用以下方式禁用后者:
export ASAN_OPTIONS=detect_leaks=0这些 ASAN 选项及其他选项记录在 https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
dumpcap 需要权限才能捕获数据包。要从构建目录测试它,相对安全的选项是:
添加文件系统 capabilities:sudo setcap cap_net_raw,cap_net_admin+eip run/dumpcap(缺点:如果构建目录位于以 nosuid 挂载的 tmpfs(/tmp)中,则无法工作;重新构建后更改会丢失)。
使用 ambient capabilities,参见 [Wireshark-dev] Capturing packets on Linux during development。
在任何情况下都不应以(setuid)root 身份运行它,除非你不在意该环境(例如虚拟机)。
无论哪种情况,添加 capabilities 都会阻止 gdb/strace 附加。要解决此问题,请在启动 GDB 之前使用带有 cap_sys_ptrace 的 ambient capabilities。请注意,这将允许调试任何进程,包括 root 拥有的进程。
Wireshark 等应用程序对 GLib 的调用可能会导致警告。要调试这些警告,可以设置环境变量来影响 GLib 对这些警告的反应。结合调试器,你可以查看导致该警告的调用栈。参见 Running GLib Applications
摘自 http://www.ethereal.com/lists/ethereal-dev/200503/msg00778.html[Ethereal-dev] How to trace Ethereal on WinXP using MSVC++?
如果你只是想调试 Wireshark,那么 Win32 二进制文件默认应已包含调试符号。你可以查看 config.nmake 文件,并确保调试开关已启用……
# Linker flags# /DEBUG generate debug infoLOCAL_LDFLAGS=/DEBUG一旦你有了带调试符号的有效二进制文件,就可以通过在 MSVC 中打开该二进制文件来轻松调试 Wireshark。
因此,在 Visual Studio 中只需点击 File ! Open ! Project/Solution 菜单,然后浏览到 Wireshark .exe 的安装位置。通常为:c:\program files\wireshark\wireshark-gtk2。打开之后,你应该会在 Visual Studio 最左侧窗口中看到 wireshark.exe。要执行 Wireshark,只需按 F5 键。如果你想在 Wireshark 中的某个位置中断,只需打开源文件并设置断点。Wireshark.exe 的执行会在指定位置暂停。然后你可以单步执行源代码,以定位/调试你的问题。
注意:对于 Visual Studio 6,请使用 File ! Open,将文件扩展名类型改为所有文件,然后按上述步骤继续。
有时,能够使用 MSVC6 的 "Tools/Source Browser" 功能查找 Wireshark 函数和变量的定义与引用会非常有用。
要构建并使用所需的 "Browse Information File"(.bsc)文件:
# Compiler flags# /W3 warning level 3 (0 less - 4 most, 1 default)# /Zi create .pdb file for debugging# /Fr create .sbr files used by BSCMAKE to create a "Browse Information File"LOCAL_CFLAGS=/Zi /W3 /Fr user@host:~/src/wireshark$ nmake -f Makefile.nmake wireshark.bsc通过使用与 source browser 关联的键盘快捷键,可以相当轻松地在源文件之间导航。(参见 MSVC Help 中的 "Browse Information Files")。
例如:如果光标位于某个标识符的开头,按 F12 会立即跳转到该标识符定义所在的源文件位置。按 <Ctrl Num *> 则会将光标移回上一个位置。
于 2020-08-11 23:13:12 UTC 从 https://wiki.wireshark.org/Development/Tips 导入