DbgPrint logger for NT3.51/NT4/NT4-TS/w2k/XP/2k3/2k3-r2/Vista and WinPE/BartPE/MobileOS
DbgPrint logger home
DbgDumpLog manual
Overview
Утилита для перехвата и сохранения вывода от DbgPrint() (также известного под
именем KdPrint()) и OutputDebugString() в файл.
Поддерживает ротацию логов. Размер одного log-файла ограничен 128Mb.
При достижении предельного размера происходит автоматический переход к следующему
файлу. Например если лог начат с файла dbgprint.log, то следующими будут
dbgprint1.log, dbgprint2.log и т.д. Поддерживается управление с клавиатуры.
Можно приостановить сбор сообщений, принудительно перейти к новому log-файлу.
В отличие от SysInternals DbgView данная утилита не имеет ограничений на
суммарный объем логов. (DbgView падает при достаточно больших объемах - ~4Gb).
Имеет целую кучу настроек и может перенастраиваться с клавиатуры в процессе работы.
Работает так: драйвер находит точку, где DbpPrint() передает управление во
внутреннюю ф-цию ядра и заменяет адрес вызова на собственный обработчик.
(Кстати, точно так же поступает и SoftIce). Перехваченные строки складируются в
буфер (1Mb). User-mode приложение забирает из драйвера собранные сообщения через
IOCTL. Сообщения, поступившие через OutputDebugString() собираются в
user-mode в отдельном thread'е.
Последние версии умеют также сохранять boot-time логи, а так же работать
как сервис - без необходимости логиниться в систему. Для этого предназначены
ключи -svc и -drv (см. ниже).
Note: код установки драйвера и сервиса
ищет DbgPrintLog.exe и DbgPrnHk.sys в той директории, где
расположен DbgPrintLog.exe. Поэтому я рекомендую указывать
полный путь к DbgPrintLog.exe или запускать его из того же каталога где он находится.
Это позволит избежать запуска ранее установленного exe'шника из %SystemRoot%\System32
или другого места, указаного в переменной окружения %PATH%.
Для удобства написания скриптов для тестирования софта и последующей интерпретации
полученых логов сделана утилита EchoDbg. Позволяет отправлять текстовые сообщения
не только в StdOut (как это делает обычная команда echo), но и в DebugConsole через
OutputDebugString(). Кроме того, EchoDbg умеет перенаправлять свой StdIn все в ту же
DebugConsole. При использованиия EchoDbg в тестирующих скриптах очень легко
сопоставлять вызовы верхнего уровня (например команды работы с файлами) с логами,
произведенными самой тестируемой программой (например драйвером файловой системы).
Есть подобие SDK - .H и .LIB, позволяющие отлаживаемой программе отправлять
debug-сообщения прямо во внутренний буфер драйвера. API такое же как у printf().
Еще если интересно, можно почитать про устройство
KdPrint()/OutputDebugString().
Compatibility
Утилита DbgPrintLog проверена в следующих OS при включенном и при выключеном SoftIce:
NT 3.51
NT 4.0 build 1381 Service Pack 4
NT 4.0 build 1381 Service Pack 6
NT 4.0 build 1381 Service Pack 6a
NT 4.0 (TS) build 1381 Service Pack 6
NT 5.0 (Win 2000) build 2195
NT 5.0 (Win 2000) build 2195 Service Pack 2
NT 5.0 (Win 2000) build 2195 Service Pack 4
NT 5.1 (Win XP) build 2600 Service Pack 1, v.1081
NT 5.1 (Win XP) build 2600 Service Pack 2, v.2055
NT 5.1 (Win XP) build 2600 Service Pack 2
NT 5.2 (Win 2003) build 3790
NT 5.2 (Win 2003-R2) Service Pack 1
NT 6.0 (Vista)
Command line reference
Debugger extension
Параметры командной строки для DbgPrintLog (ключи для предыдущих версий можно посмотреть
здесь):
Usage:
DbgPrintLog.exe [<switches>] [<log-file name>]
Switches:
Log-file format:
-m, --caller_mode
write initiator mode (K - kernel, U - user) to log
-p, --pid, --process_id
write ProcessId to log
-P, --pname, --process_name (since v0.8a)
write Process Name to log
-t, --tid, --thread_id
write ThreadId to log (for kernel-mode only)
-i, --irql
write IRQL to log (for kernel-mode only)
--cpu write CPU num to log (for kernel-mode only)
--full same as -m -p -t -i
--raw (since v0.8b)
write messages in raw format (doesn't affect syslog stream)
-T FMT, --timestamp_fields FMT
specify absolute time format FMT. FMT string can contain
the following switches: D - date, T - time, N - high precision time
R - relative time (tick count), U - UTC time
-fm M do not log messages from <M> mode
<M> can be K - kernel or U - user
--filter:<action> <condition>
perform <action> for all messages matching <condition>
prior to putting them to log. For now the only possible action
is DENY (or BLOCK, SKIP, DROP). Available <conditions> are:
origin=kernel (origin=ring0 or K) - messages from kernel mode
origin=user (origin=ring3 or U) - messages from user mode
-sfp, --stack_frame_ptr (since v0.7)
write Stack Frame Pointer information to log (for kernel-mode only)
Log-file control:
-s NUM, --max_log_size NUM
set max log-file size to NUM Mbytes (0 < NUM < 2048)
128Mb is used by default
-S NUM, --prealloc_log_size NUM
does like -s, but sets initial file size to specified value.
Is intended mainly for use by GUI tool.
-x NUM, --build_index NUM
create index file for each log file.
Is intended mainly for use by GUI tool.
-l NUM, --max_log_count NUM, --log_rotate_count NUM
keep NUM latest log files
-n NUM, --initial_log_number NUM
set start log number to NUM
-ovw, --overwrite_old_log (since v0.7f)
overwrite existing log files
-ft NUM, --flush_timeout NUM
flush messages buffer after NUM seconds of inactivity
-sm, --sync_mode
synchronous mode. all messages are flushed immediately
-wd DIR, --working_directory DIR
specify working directory
Output data stream control:
--out:<output> [<parameters>]
since v0.8b multiple --out: options ara allowed
available values for <output> are:
stdout write log to STDOUT instead of file
file write log file (default)
syslog HOST[:PORT] (since v0.8a)
send messages via UDP syslog protocol to
speciified PORT of HOST. PORT is defaulted to 514
none do not write logs anyware
just forward OutputDebugString to driver
-o, --stdout
same as --out:stdout
-cf same as --out:file --out:stdout
--no_out same as --out:none
--syslog:mtu MTU (since v0.8c)
set maximum syslog packet size to MTU bytes (1024 by default)
Input data stream control:
--in:<input> [<parameters>]
available values for <input> are:
drv read message stream from the driver (default)
stdin read message stream from STDIN
file FILENAME
read message stream from FILENAME
comdbg read serial port (COM) over WinDbg protocol (since v0.8g)
syslog [HOST][:PORT] (since v0.9)
get messages via UDP syslog protocol at
speciified PORT of HOST. PORT is defaulted to 514
HOST is defaulted to ANY interface of local host
--stdin same as --in:stdin
--in_file FILENAME
same as --in:file FILENAME
--in_drv same as --in:drv
--comdbg:port NUM (since v0.8g)
use serial port NUM
by default used COM1 if _NT_DEBUG_PORT env. variable
not defined
--comdbg:baud NUM (since v0.8g)
use baudrate NUM (e.g. 9600, 19200, 57600, 115200)
by default used 115200 if _NTKD_BAUD_RATE env. variable
not defined
--comdbg:int3 NUM (since v0.9a)
INT3 handling: 0 - do not handle, 1 - skip, 2 - prompt
Service control:
--svc:install MOD
install or uninstall as service. MOD specify startup mode:
A - automatic, M - manual, U - uninstall. 'A' is used by default
if MOD is omited.
--run:MOD (since v0.7e)
Specify DbgPrintLog.exe run mode:
U, user - run as plain user even under SYSTEM account
S, svc - run as service regardless of user account
by default Service mode is assumed if runnyng under SYSTEM account
Driver run mode:
--drv:install MOD
Specify driver startup mode:
1 - very first (boot), B - boot, S - system,
A - automatic, M - manual, U - uninstall
'M' is used by default if MOD is omited.
--drv:noload, --no_drv
do not use driver for message routing
--drv:reload, -rd
restart and reinstall driver before start
--drv:reconfig, -rc (since v0.7)
make driver to read config changes from Registry
--drv:opt OPTION_NAME VALUE
or --drv_opt OPTION_NAME VALUE
Specify driver startup option. Valid OPTION_NAMEs and VALUEs are
CheckIrql 0|1
BufferSize NUM (in KBytes, integral multiple of 2)
DoNotPassMessagesDown 0|1
StopOnBufferOverflow 0|1|2 (2 invokes Kernel Debugger on overflow)
TimeStampType 0|1|2
AggregateMessages 0|1
DumpStackFramePtr 0|1
Read documentation for each option description
Misc options:
--status display information about installed and active components
--nowait do not wait for new messages, just dump already stored in driver and exit
-h, -?, /?, /h, --help
display this help message
Console commands reference
Если DbgPrintLog запущен как консольное приложение,
доступны следующие клавиши управления:
Commands:
'Esc' - exit
'N' - start new log
'F' - flush log buffer
'H' - display this help message
Mode switchers (toggle on/off):
'Space' - pause
'S' - synchronous mode
'C' - copy log to stdout
'K' - capture kernel messages
'U' - capture user-mode messages
'I' - CheckIrql
'P' - DoNotPassMessagesDown
'O' - StopOnBufferOverflow
'A' - AggregateMessages
'?' - query current options
Examples
Logging Boot-driver
Для получения логов начальной загрузки, например - инициализации драйверов SCSI/IDE контроллеров,
имеет смысл установить DbgPrintLog с такими параметрами:
DbgPrintLog.exe --full -T DTN -wd X:\dir_for_logs --drv:inst 1 --svc:inst A --drv:opt DoNotPassMessagesDown 1
--drv:opt StopOnBufferOverflow 1 --drv:opt BufferSize 16384 BootInit.log
В этом случае драйвер перехватит все обращения к DbgPrint() и сохранит сообщения во внутреннем буфере размером 16Mb.
Когда буфер заполнится, поступающие сообщения будут выбрасываться. Это продолжится до тех пор, пока
не запустится сервис. В этот момент сохраненные сообщения будут записаны в файл и сбор логов продолжится в
нормальном режиме. Поскольку сообщения не будут передвваться в настоящую ф-цию DbgPrint(),
можно безопасно генерировать логи даже на высоких IRQL.
Собраные логи можно забрать следующими способами:
-
Из каталога X:\dir_for_logs (который вы указали в командной строке), если система успешно загрузилась
-
Из CRASHDUMP'а, если система успешно свалилась :)
При помощи
Kernel Debugger extension'а.
-
При отладке по шнурку (COM, IEE1394, USB2.0) логи можно в любой момент забрать с отлаживаемой машины при помощи
Kernel Debugger extension'а.
-
Начиная с v0.8g при отладке по шнурку (пока только COM) логи можно забрать самим DbgPrintLog'ом
без привлечения WinDbg. Причем, в отличие от варианта с WinDbg, не играет роли, какие версии NT
установлены на машинах. В этом случае установка вспомогательного драйвера на отлаживаемой машине не нужна.
Remote debugging
При больших объемах логов при удаленной отладке (COM, IEEE1394, USB2.0)
для получения предсмертных логов устанавливается DbgPrintLog с такими параметрами:
DbgPrintLog.exe --out:none --drv:inst 1 --svc:inst A --drv:opt DoNotPassMessagesDown 1
--drv:opt StopOnBufferOverflow 0 --drv:opt BufferSize 16384
В этом случае драйвер в паре с сервисом перехватят все обращения к KdPrint()/DbgPrint() и
OutputDebugString() и сохранят сообщения во внутреннем буфере размером 16Mb.
Когда буфер заполнится, самые старые сообщения будут выбрасываться.
Поскольку сообщения не будут передвваться в настоящую ф-цию DbgPrint(),
торможений за счет передачи отладочных сообщений в удаленный отладчик не будет.
Логи можно в любой момент забрать с отлаживаемой машины при помощи
Kernel Debugger extension'а.
Remote debugging without WinDbg
При удаленной отладке (COM, IEEE1394, USB2.0) часто возникают проблемы совместимости
версий ОС на машинах. Это глюк WinDbg - он нормально работает только если версии совпадают.
Для получения логов на отлаживаемой машине можно ничего не устанавливать,
достаточно настроить ее для удаленной отладки через COM-порт, как это описано в
WinDbg HOWTO для тестировщиков (остальное пока не поддерживается).
А на мониторящей машине запускается DbgPrintLog с такими параметрами:
DbgPrintLog.exe --full --in:comdbg --comdbg:port 1 --comdbg:baud 115200 DbgLog.log
В этом случае DbgPrintLog сделает вид, что он - WinDbg, получит логи и сохранит их в файл.
Запускать нужно до перезагрузки отлаживаемой машины, чтобы в тот момент, когда она начнет искать отладчик,
DbgPrintLog уже слушал COM-порт.
Logging System-driver
Для получения логов во время загрузки system драйверов, например CDROM,
имеет смысл установить DbgPrintLog с такими параметрами:
DbgPrintLog.exe --full -T DTN -wd X:\dir_for_logs --drv:inst B --svc:inst A
--drv:opt StopOnBufferOverflow 1 --drv:opt BufferSize 16384 SystemDrivers.log
Драйвер перехватит все обращения к DbgPrint() и сохранит сообщения во внутреннем буфере размером 16Mb.
Когда буфер заполнится, поступающие сообщения будут выбрасываться. Это продолжится до тех пор, пока
не запустится сервис. В этот момент сохраненные сообщения будут записаны в файл и сбор логов продолжится в
нормальном режиме. Поскольку сообщения будут передвваться в настоящую ф-цию DbgPrint(),
не стоит генерировать логи на высоких IRQL.
Logging Logon process
Для получения логов во время входа пользователя в систему, например из gina.dll,
имеет смысл использовать функции вывода логов из
DbgPrint logger SDK
вместо стандартной ф-ций
OutputDebugString(). Это связвно с тем, что для перехвата OutputDebugString()
требуется наличие сервиса DbgPrintLog.exe, который может быть еще не запущен.
Установить DbgPrintLog нужно с такими параметрами:
DbgPrintLog.exe -p -t -T DT -wd X:\dir_for_logs --drv:inst S --svc:inst A Logon.log
Драйвер сохранит сообщения во внутреннем буфере размером 1Mb (по умолчанию).
Когда буфер заполнится, наиболее старые сообщения будут выбрасываться. Это продолжится до тех пор, пока
не запустится сервис. В этот момент сохраненные сообщения будут записаны в файл и сбор логов продолжится в
нормальном режиме.
Logging on demand
Если требуется собрать во время исполнения тестируемого приложения,
имеет смысл запускать DbgPrintLog с такими параметрами:
DbgPrintLog.exe -p -fm K -T DT -wd X:\dir_for_logs MyApp.log
User-mode часть утилиты перехватит сообщения идущие через OutputDebugString()
и сохранит в файл. Сообщения от DbgPrint() сохранены не будут.
Сбором логов в этом случае можно управлять в консольном окне с помощью клавиатуры.
Deinstall
Для отключения автозапуска утилиты стоит воспользоваться следующей строчкой:
DbgPrintLog.exe -drv U -svc U
DbgPrintLog main page
Предложения и замечания слать на
alterX@alter.org.ua (remove X)
|