Use .ocommand for automatic debugging

A debugger is not just for debugging an application. It’s also useful for monitoring the application execution. For example, you may want to get the stack trace whenever certain function returns error.

    HANDLE hFile = ::CreateFile("foo.txt",
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hFile == INVALID_HANDLE_VALUE){
OutputDebugString("OCOMMAND: kb;gcn");
}

The code above calls OutputDebugString() whenever CreateFile() failes. The output text of OutputDebugString() is interesting – it’s a sequence of WinDbg command: kb and gc.

The WinDbg (and CDB/NTSC as well) has an extension command called ".ocommand". The command takes of any text and run the text as WinDbg command. In the case above, you want to call: ".ocommand OCOMMAND:" before starting the application.

 

Microsoft (R) Windows Debugger Version 6.8.0004.0 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: big_mem.exe
Symbol search path is: SRV*c:symbols*http://msdl.microsoft.com/download/symbols Executable search path is:
ModLoad: 00400000 00406000 big_mem.exe
ModLoad: 7c900000 7c9af000 ntdll.dll
ModLoad: 7c800000 7c8f6000 C:WINDOWSsystem32kernel32.dll
ModLoad: 78130000 781cb000 C:WINDOWSWinSxSx86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.3053_x-ww_b80fa8caMSVCR80.dll
ModLoad: 77c10000 77c68000 C:WINDOWSsystem32msvcrt.dll
(9e8.d28): Break instruction exception - code 80000003 (first chance)
eax=00251eb4 ebx=7ffde000 ecx=00000004 edx=00000010 esi=00251f48 edi=00251eb4
eip=7c90120e esp=0012fb20 ebp=0012fc94 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ntdll!DbgBreakPoint:
7c90120e cc int 3
0:000> .ocommand OCOMMAND:
Treat output prefixed with 'OCOMMAND:' as a command
0:000> gc
 

Then whenever OutputDebugString() outputs a line starting with "OCOMMAND:", the debugger automatically runs the command following the "OCOMMAND:". In this particular case, it shows stack trace.

ChildEBP RetAddr  Args to Child
0012fd0c 7c85acd0 40010006 00000000 00000002 kernel32!RaiseException+0x53
0012ff74 0040102d 004020fc 0040118d 00000001 kernel32!OutputDebugStringA+0x54
0012ff7c 0040118d 00000001 003b59d0 003b3b00 big_mem!main+0x2d
0012ffc0 7c817067 7c911440 0006f4cc 7ffde000 big_mem!__tmainCRTStartup+0x10f
0012fff0 00000000 004012d6 00000000 78746341 kernel32!BaseProcessStart+0x23
eax=0012fcbc ebx=00000000 ecx=00000000 edx=00000000 esi=0012fd38 edi=0040338c
eip=7c812aeb esp=0012fcb8 ebp=0012fd0c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202

It’s very useful feature especially for long term process status monitoring such as memory usage, exception, and so on.

Advertisements

About Moto

Engineer who likes coding
This entry was posted in Advanced Debugging. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s