Alter.Org.UA
 << Back Home EN en   Donate Donate

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


См. также


Предложения и замечания слать на FB or mail alterX@alter.org.ua (remove X)   Share
Автор: Alter (Александр А. Телятников) Сервер: Apache+PHP под FBSD © 2002-2021