请随时将文档补丁发送到 vbox-dev 邮件列表。
VirtualBox/IPRT 日志记录功能
IPRT 日志记录功能的通用描述可在 Runtime/VBox/log-vbox.cpp 中找到。
IPRT 日志组名称(如 RT_LDR)和日志标志可在 include/iprt/log.h 中找到。
VirtualBox 日志组名称(如 DEV_VMM)和标志可在 include/VBox/log.h 中找到。在需要添加日志的文件中,也可以查找类似 "#define LOG_GROUP LOG_GROUP_DEV_VMM" 的行。
VirtualBox 使用环境变量 VBOX_LOG
、VBOX_LOG_DEST
和 VBOX_LOG_FLAGS
来控制调试日志输出,使用 VBOX_RELEASE_LOG
、VBOX_RELEASE_LOG_DEST
和 VBOX_RELEASE_LOG_FLAGS
来控制发布日志输出。日志设置也可以在运行时通过调试器更改,从 4.1.8 版本开始,还可以通过 VBoxManage debugvm
进行更改。
注意: 如果您想从 ring-0 组件或 客户端增强功能中获取日志,请参阅关于这些内容的特定章节(如果您需要 ring-0 增强功能日志,则两者都请参阅)。
注意: 要启用 VBoxSVC 发布日志记录,请参阅此处的专用页面。
示例
set VBOX_LOG=em=~0 rem* -rem_mmio # Enable all EM group logging and all level 1 REM* # groups logging except REM_MMIO. set VBOX_LOG_FLAGS=buffered thread tsc # Buffer log output, print thread IDs in the log # statements, print TSC values
export VBOX_RELEASE_LOG="rem*.e.l.f main gui" export VBOX_RELEASE_LOG_FLAGS="buffered thread msprog" # Do not limit the number of log entries a guest can send to the release log export VBOX_RELEASE_LOG=-dev_vmm_backdoor.restrict
export VBOX_LOG="dev_vmm.e" export VBOX_LOG="rt_ldr.e.f" export VBOX_LOG_FLAGS="msprog" export VBOX_LOG_DEST="nofile stderr"
发布日志记录即使在运行组件/程序的发布版本时,也会将信息打印到目标位置。默认情况下,此目标是用户 VirtualBox 主目录中的发布日志文件,该文件在创建时会进行轮换。要设置目标,调试日志记录使用环境变量 "VBOX_LOG_DEST",发布日志记录使用 "VBOX_RELEASE_LOG_DEST",并添加前缀 "file="(如果记录到文件)或 "dir="(目录)以及文件名/目录。请参阅 Runtime/common/log/log.cpp 的第 265 行附近。示例:
export VBOX_LOG_DEST="dir=/tmp"
默认情况下,所有 1 级发布日志语句("LogRel()")都会导致日志记录到发布日志中。对于 2 级("!LogRel2()")、流日志("LogRelFlow()")等要输出的内容,您需要为您感兴趣的日志组启用日志类型 - 例如:
VBOX_RELEASE_LOG="+dev_vmm.e.l.f+main.e.l.f"
将为 2 级和流日志记录启用 "dev_vmm" 和 "main" 发布日志组。发布日志记录对于调试远程问题可能很方便,但当然应在性能关键型代码中谨慎使用。
Ring-0 日志记录
默认情况下,来自 ring-0 上下文的日志记录使用 Runtime/VBox/log-vbox.cpp 中找到的硬编码配置。由于在主机上调试 VMM 问题时,将 ring-0 上下文日志输出与 ring-3 和原始模式上下文日志语句放在同一日志文件中通常会更有用,因此我们创建了一个小技巧(用于 *主机* ring-0 日志记录!):将 VBOX_WITH_R0_LOGGING=1 添加到 LocalConfig.kmk 或通过命令行将其传递给 kmk。使用此技巧时,ring-0 日志记录器将主要使用与 ring-3 日志记录器相同的设置。
当在 Linux 客户端上使用自建增强功能设置 ring-0 日志记录时,请确保您对 log-vbox.cpp 的更改确实进入了客户端内核模块源代码中的 log-vbox.c。如果您希望在 Linux 客户端上使用官方增强功能构建启用 ring-0 日志记录,可以修改客户端模块源代码中的 VBox/log-vbox.c 并强制重建和重新加载模块。如果您希望将客户端 ring-3 日志记录传递给主机,请更改 makefile 以构建模块的调试版本。
关于组后缀的一些说明
.eo (.enabledonly) - 仅启用;
.e (.enabled) - 启用 + 1 级;
.lX (.levelX) - X 级,X 为 1-6;
.l = .l2;
.f (.flow);
命名后缀
有时核心开发人员会使用看起来像 Log<Nick>(...) 的私有日志语句,其中 <Nick> 是开发人员的昵称。要启用这些日志语句,您必须为该开发人员设置日志标志。例如,对于昵称为 "NoName" 的开发人员(代码中的 LogNoName(...) 语句),使用后缀
.n = .noname;
要完全禁用日志记录,请使用以下之一:
export VBOX_LOG_DEST=nofile export VBOX_LOG_FLAGS=disabled export VBOX_LOG=-all
客户端增强功能日志记录
要启用客户端 R3 应用程序的 发布日志记录(和调试日志记录)到 VMM 后门:
- Windows 客户端:创建一个
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VBoxGuest\LoggingEnabled
注册表项,值为 0xFF (DWORD 32位)。
- Linux 客户端:将 /sys/module/vboxguest/r3_log_to_host 设置为 1。对于基于 Debian 和 RPM 的客户端,安装 sysfsutils 软件包并添加
module/vboxguest/parameters/r3_log_to_host = 1
到 /etc/sysfs.conf。在运行时更改此值也是可行的。
要启用客户端增强功能日志记录,请将以下内容添加到主机环境变量中:
set VBOX_LOG="-all+dev_vmm_backdoor.e.l.f+dev_vmm.e.l.f" set VBOX_LOG_FLAGS="thread tsc"
……然后在客户端(关于在 ring-0 位中执行此操作,请参阅上面关于 ring-0 的部分),使用以下方式重启您希望记录日志的组件:
set VBOX_LOG="all"
注意: 您需要在客户端虚拟机上安装 调试版 客户端增强功能(即 VBoxGuest.<ext> 的调试版本),才能使其他客户端组件的日志记录输出到主机日志文件。但是,您仍然可以从发布组件中获取一些日志记录——输出到客户端上的文件。请参阅 X11 客户端共享剪贴板组件 的示例。
旧版警告: 如果定义了 "LOG_TO_BACKDOOR",并且您在调试语句中使用了格式说明符(例如 "%s"),您的日志文件可能会变得混乱。取消定义/删除此宏以使用 IPRT 常规方式进行日志记录。
对于共享文件夹(Windows: VBoxSF.sys / VBOXMRXNP.dll)
VBOX_LOG_FLAGS=thread VBOX_LOG=+hgcm.e.f,+shared_folders.e.f
使用 VBoxManage 更改设置
VBoxManage 命令行工具可用于更改运行中虚拟机的日志设置。示例:
$ VBoxManage debugvm <name> log --release +dev_vga.e.l.f $ VBoxManage debugvm <name> log --release -dev_vmm_backdoor.restrict $ VBoxManage debugvm <name> logdest --debug stdout $ VBoxManage debugvm <name> logflags --release buffered $ VBoxManage debugvm <name> show logdbg-settings
在调试器内部更改设置
日志设置可以在运行时使用调试器更改。这主要对 VBoxSVC 有用。以下是 gdb 的两个示例:
(gdb) call RTLogGroupSettings(0, "+drv_nat.e.l.f.l2.l3") $1 = 0
等同于传递环境变量
VBOX_LOG=+drv_nat.e.l.f.l2.l3
以及
(gdb) call RTLogRelDefaultInstance() $1 = (RTLOGGER *) 0x2be2c30 (gdb) call RTLogFlags(0x2be2c30, "thread") $2 = 0
等同于
VBOX_RELEASE_LOG_FLAGS=thread