You may some times feel crazy about some exceptions in your application. You have no idea where it is happening in the code and what you can do now is debugging the suspicious location in the issue happening scenario. Let me welcome you to a better approach with your VC++ debugger, so that you will get a better context of the issue causing exception. Follow the steps,
1. Debug your application (Either start with debugger or attach your process with the debugger).
2. In the VC 6 debugger choose Debug->Exceptions then you can see a dialog with various exception types.
3. Click and select all the Exceptions, now press OK.
4. Run your scenario.
5. When an exception happen a message box will be shown in the debugger and execution will break.
6. Now you can get the call stack where exception happens. For this check the Context combo box in the debugger IDE.
7. Now select each location in the call stack and interpret the cause (you can get the value of the variables).
Showing posts with label Debugging. Show all posts
Showing posts with label Debugging. Show all posts
Friday, September 11, 2009
Friday, September 4, 2009
[Utility][WinDbg] !htrace for debugging handle leak
Windbg Debugger’s !htrace extension is very good at debugging handle leaks. See the below steps how you can do it.
1. Install Debugging Tool for windows from here.
2. Run WinDbg installed with Debugging Tools in Step 1.
3. Take File->Attach to a process... menu and select your application in the process list
4. Application will break and change in to debug mode
5. Take File->Symbol File path and add the path where your application's pdb file is available
6. In the debug prompt enter !htrace -enable and press enter.
7. Now take Debug->Go menu, then you can operate on your application
8. Now run your scenario where your application is assumed to have handle leak.
9. Now take Debug->Break menu, for changing the application to debug mode.
10. Now enter !htrace -diff in the debug prompt and press enter. Here it list the handle leak logs.
Below is an example of the log generated for 4 opened handle in my test app. From the log you can see where exactly the handle is leaked in the code.
0:001>
1. Install Debugging Tool for windows from here.
2. Run WinDbg installed with Debugging Tools in Step 1.
3. Take File->Attach to a process... menu and select your application in the process list
4. Application will break and change in to debug mode
5. Take File->Symbol File path and add the path where your application's pdb file is available
6. In the debug prompt enter !htrace -enable and press enter.
7. Now take Debug->Go menu, then you can operate on your application
8. Now run your scenario where your application is assumed to have handle leak.
9. Now take Debug->Break menu, for changing the application to debug mode.
10. Now enter !htrace -diff in the debug prompt and press enter. Here it list the handle leak logs.
Below is an example of the log generated for 4 opened handle in my test app. From the log you can see where exactly the handle is leaked in the code.
0:001>
!htrace -diff
Handle tracing information snapshot successfully taken.
0x26 new stack traces since the previous snapshot.
Ignoring handles that were already closed...
Outstanding handles opened since the previous snapshot:
--------------------------------------
Handle = 0x0000070c - OPEN
Thread ID = 0x00001758, Process ID = 0x00001248
0x7c8308eb: kernel32!CreateEventA+0x00000068
*** WARNING: Unable to verify checksum for D:\TestFolder\MiscTest\Release\MiscTest.exe
0x0040172b: MiscTest!CMiscTestDlg::OnButtonHandle+0x0000001a
0x73dd24c0: MFC42!_AfxDispatchCmdMsg+0x00000082
0x73dd23bf: MFC42!CCmdTarget::OnCmdMsg+0x0000010a
0x73e3dead: MFC42!CPropertySheet::OnCmdMsg+0x0000001d
0x73dd3244: MFC42!CWnd::OnCommand+0x00000053
0x73dd1bf1: MFC42!CWnd::OnWndMsg+0x0000002f
0x73dd1b9b: MFC42!CWnd::WindowProc+0x00000024
0x73dd1b05: MFC42!AfxCallWndProc+0x00000091
0x73dd1a58: MFC42!AfxWndProc+0x00000036
0x73e6847d: MFC42!AfxWndProcBase+0x00000039
--------------------------------------
Handle = 0x00000710 - OPEN
Thread ID = 0x00001758, Process ID = 0x00001248
0x7c8308eb: kernel32!CreateEventA+0x00000068
0x0040172b: MiscTest!CMiscTestDlg::OnButtonHandle+0x0000001a
0x73dd24c0: MFC42!_AfxDispatchCmdMsg+0x00000082
0x73dd23bf: MFC42!CCmdTarget::OnCmdMsg+0x0000010a
0x73e3dead: MFC42!CPropertySheet::OnCmdMsg+0x0000001d
0x73dd3244: MFC42!CWnd::OnCommand+0x00000053
0x73dd1bf1: MFC42!CWnd::OnWndMsg+0x0000002f
0x73dd1b9b: MFC42!CWnd::WindowProc+0x00000024
0x73dd1b05: MFC42!AfxCallWndProc+0x00000091
0x73dd1a58: MFC42!AfxWndProc+0x00000036
0x73e6847d: MFC42!AfxWndProcBase+0x00000039
--------------------------------------
Handle = 0x00000714 - OPEN
Thread ID = 0x00001758, Process ID = 0x00001248
0x7c8308eb: kernel32!CreateEventA+0x00000068
0x0040172b: MiscTest!CMiscTestDlg::OnButtonHandle+0x0000001a
0x73dd24c0: MFC42!_AfxDispatchCmdMsg+0x00000082
0x73dd23bf: MFC42!CCmdTarget::OnCmdMsg+0x0000010a
0x73e3dead: MFC42!CPropertySheet::OnCmdMsg+0x0000001d
0x73dd3244: MFC42!CWnd::OnCommand+0x00000053
0x73dd1bf1: MFC42!CWnd::OnWndMsg+0x0000002f
0x73dd1b9b: MFC42!CWnd::WindowProc+0x00000024
0x73dd1b05: MFC42!AfxCallWndProc+0x00000091
0x73dd1a58: MFC42!AfxWndProc+0x00000036
0x73e6847d: MFC42!AfxWndProcBase+0x00000039
--------------------------------------
Handle = 0x00000718 - OPEN
Thread ID = 0x00001758, Process ID = 0x00001248
0x7c8308eb: kernel32!CreateEventA+0x00000068
0x0040172b: MiscTest!CMiscTestDlg::OnButtonHandle+0x0000001a
0x73dd24c0: MFC42!_AfxDispatchCmdMsg+0x00000082
0x73dd23bf: MFC42!CCmdTarget::OnCmdMsg+0x0000010a
0x73e3dead: MFC42!CPropertySheet::OnCmdMsg+0x0000001d
0x73dd3244: MFC42!CWnd::OnCommand+0x00000053
0x73dd1bf1: MFC42!CWnd::OnWndMsg+0x0000002f
0x73dd1b9b: MFC42!CWnd::WindowProc+0x00000024
0x73dd1b05: MFC42!AfxCallWndProc+0x00000091
0x73dd1a58: MFC42!AfxWndProc+0x00000036
0x73e6847d: MFC42!AfxWndProcBase+0x00000039
--------------------------------------
Displayed 0x4 stack traces for outstanding handles opened since the previous snapshot.
Sunday, February 8, 2009
[VC++] Visual Studio Debugger tips for viewing string pointers
If you add a string pointer to debug watch window what you can see is the memory location pointed and not the string itself. In order to view the string data we may need to place format specifier with the variable name in watch window.
Add following with variable name in watch window
,s for an simple null-terminated string
,s8 for a UTF-8 string
,su for a Unicode string
The memory operators can be used to display up to 64 bytes of memory in the preview line, as bytes, words, dwords, quads, or ascii characters
,mb bytes
,mw words
,md dwords
,mq quads
,ma ASCII
Also we can use ,wc ,wm and ,hr to view data as a window class, window message, and HRESULT respectively. See the below snapshot demonstrating how to use these operators in watch window.

Add following with variable name in watch window
,s for an simple null-terminated string
,s8 for a UTF-8 string
,su for a Unicode string
The memory operators can be used to display up to 64 bytes of memory in the preview line, as bytes, words, dwords, quads, or ascii characters
,mb bytes
,mw words
,md dwords
,mq quads
,ma ASCII
Also we can use ,wc ,wm and ,hr to view data as a window class, window message, and HRESULT respectively. See the below snapshot demonstrating how to use these operators in watch window.

For viewing UNICODE string in the watch/quick watch you can either ,su (I specified before) or can check the Display unicode strings check box in the Tools->Options->Debug tab
[VC++] Visual Studio Debugger tips for watch window
Displaying GetLastError's value and message in watch window
While debugging it is possible to get the GetLastError() returned after any line of execution and the message associated with it. For viewing the error code and error message in watch window what you need to do is add @err,hr to your watch window and see the value/message displayed on executing program statements.
Displaying pointer as an array in watch window
Suppose you have a pointer array and if you add the same to watch window, by default, you can view only the first value pointed. For viewing all the pointer array content, add the variable name to watch window and add the maximum index to be displayed separated by comma, for eg: watching pnValArr,100 will display all the value of pnValArr from 0 to 100th index. Similarly we can watch intermidate range of a pointer array, for eg: (pnValArr+90),10 will display content of pointer array from index 90 to 100.
See the below debug snapshot showing watch window demonstrating GetLastError() and displaying pointers as array

While debugging it is possible to get the GetLastError() returned after any line of execution and the message associated with it. For viewing the error code and error message in watch window what you need to do is add @err,hr to your watch window and see the value/message displayed on executing program statements.
Displaying pointer as an array in watch window
Suppose you have a pointer array and if you add the same to watch window, by default, you can view only the first value pointed. For viewing all the pointer array content, add the variable name to watch window and add the maximum index to be displayed separated by comma, for eg: watching pnValArr,100 will display all the value of pnValArr from 0 to 100th index. Similarly we can watch intermidate range of a pointer array, for eg: (pnValArr+90),10 will display content of pointer array from index 90 to 100.
See the below debug snapshot showing watch window demonstrating GetLastError() and displaying pointers as array

Thursday, February 5, 2009
[VC++] Visual Studio Debugger tips for viewing integer data
Visual Studio's C++ debugger has some undocumented yet powerful features ! Here is how to view an integer data type with its data in various ways. Suppose you break at the below statement in program,

int nVal = 0x12345678;
Use operators before variable name in watch window...
by To view contents of a variable as an unsigned byte
wo To view contents of a variable as an unsigned word
dw To view contents of a variable as a dword
Use format specifiers after variable name in watch window...
,o To view the conten in octal
,d To view the conten in decimal
,x To view the conten in hex
See the below debugging snapshot to visualize how to use the above said,

Wednesday, December 24, 2008
[VC++] Debugging application startup
1. Consider your application is being launched from some other applications and you want to debug the same then how you can do that ?
First of all your module should be made debuggable by building with proper project settings (making release build debuggable). Now start your application, since application is started by some other parent application you cannot get the debug mode.
So what you need to do is that,
a). Take taskmanager->Process tab & Right click the entry corresponding to your process
b). Choose the Debug menu item and press Yes for the warning message shown
c). Visual Studio Debugger will be launched, take File->Open & choose the file which you want to insert break point
d). Insert break point where ever needed and execute it will work fine !
2. Now the question is - How can you debug your application (if lanched by some other process) in the start up, say you want to debug App class constructor or InitInstance() ?
Some of you might have faced the same situation and you would have gone behind putting MessageBox() in some startup function, but there is a better option for the same.
What you need to do for debugging in the startup is
a). Set Auto flag to '1' under registery entry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
b). Add any of the below lines where you want to debug in start up,
_asm int 3;
or
DebugBreak();
Now try start your application, it will automatically launch msdev for debugging and break the execution where you put _asm int 3 or DebugBreak.
First of all your module should be made debuggable by building with proper project settings (making release build debuggable). Now start your application, since application is started by some other parent application you cannot get the debug mode.
So what you need to do is that,
a). Take taskmanager->Process tab & Right click the entry corresponding to your process
b). Choose the Debug menu item and press Yes for the warning message shown
c). Visual Studio Debugger will be launched, take File->Open & choose the file which you want to insert break point
d). Insert break point where ever needed and execute it will work fine !
2. Now the question is - How can you debug your application (if lanched by some other process) in the start up, say you want to debug App class constructor or InitInstance() ?
Some of you might have faced the same situation and you would have gone behind putting MessageBox() in some startup function, but there is a better option for the same.
What you need to do for debugging in the startup is
a). Set Auto flag to '1' under registery entry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
b). Add any of the below lines where you want to debug in start up,
_asm int 3;
or
DebugBreak();
Now try start your application, it will automatically launch msdev for debugging and break the execution where you put _asm int 3 or DebugBreak.
Tuesday, December 23, 2008
[VC++] Debugging Application in the release mode
When you create applications in VC++ using application wizards the default configuration will be debug configuration. So you can debug easily by pressing F5 key and setting break points(F9) where ever in code. Now what about debugging application in Release mode(For making the project release build configuration select Build->SetActiveConfiguration->Win32Release). Some of you might have find that its difficult to debug with release version(if you are new to VC++). That is you cannot put breakpoint when build with Release configuration. Now when tried with F5 key on a release build application what you can see only is a disassembly window or where ever you put break point, that has been disabled.
So below is what you have to do for making the project debuggable in release version
In Project->Settings->C\C++ tab,
- Set Optimizations to Disable(Debug)
- Set Debug info to Program Database
In Project->Settings->Link->Category General set
- Check Debuginfo
See the below snapshots of Project->Settings changes from default.

Now rebuild and try putting the break point again, now its debuggable!
So below is what you have to do for making the project debuggable in release version
In Project->Settings->C\C++ tab,
- Set Optimizations to Disable(Debug)
- Set Debug info to Program Database
In Project->Settings->Link->Category General set
- Check Debuginfo
See the below snapshots of Project->Settings changes from default.

Now rebuild and try putting the break point again, now its debuggable!
Tuesday, December 16, 2008
[VC++] Debugging with the help of AUTOEXP.DAT
Hope you might have debugged some application in VC++ debugger. Have you ever thought of how you are seeing the value of object as tool tip while debugging. For example, while debugging you point to the CString object you can see the value of member variable m_pchData of CString class.
You can give the same support for your custom defined data structures, suppose you have a complex object which holds many items and you want to know the values stored while debugging (sometimes you can expand the variable in watch/Quick watch window but that is difficult for a complex data structure).
In the below debug snapshot, you can see all the values (even other structure’s value) in the structure INFO_EX_t as tool tip while debugging,
In the below debug snapshot, you can see all the values (even other structure’s value) in the structure INFO_EX_t as tool tip while debugging,

For this all you have to do is modify the file MSDEV_INSTAL_DIR\Microsoft Visual Studio\Common\MSDev98\Bin\AUTOEXP.DAT, add an entry for your data structure also. For showing the above variable expansion I have added the below line,
where ‘st’ in the above line is a format specifier for the string to choose UNICODE or ANSI depending on the current setting.
Another usage of AUTOEXP.DAT is you can prevent the stepping to some specific functions (for eg: CString::operator) while debugging with F11. For that what you have to do is add an entry like what I shown below,
[ExecutionControl]
CString::operator==NoStepInto
[ExecutionControl]
CString::operator==NoStepInto
Just try it you will find it useful some day !
Subscribe to:
Posts (Atom)