Archive for the ‘Debug’ Category

How to not step into functions using the Visual Studio 2013 debugger   Leave a comment

  • If you are using Visual Studio versions prior to 2012, this information is already documented here: How to Not Step Into Functions using the Visual C++ Debugger
  • Visual Studio 2012/2013 no longer use the “/NativeDE/StepOver” registry key, they use “natstepfilter” files.
  • As of 4/1/2014, there is no official documentation about using the natstepfilter files that I can find.
  • The default natstepfilter file is located here:
  • C:\Program Files[ (x86)]\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\default.natstepfilter
  • If you want to not step into a specific function, operator, etc, while debugging, you can add specific information to this file.
  • This feature only works for native code. It works with “debugger type” set to “auto”, as long a the code your are debugging is native C++.
  • Here is an example of how to not step into any CString functions (add this inside the <StepFilter> block):

<Function><Name>ATL::CStringT.*</Name><Action>NoStepInto</Action></Function>

  • More examples coming soon!

Debugging with UIAccess=true   Leave a comment

  • If you attempt to debug an application which an app manifest with UIAccess=true, you may receive the following error:

Unable to start program [Application].

The application manifest has the uiAccess attribute set to ‘true’.
Running an Accessibility application requires following the steps
described in Help.

[OK] [Help]

  • Clicking [Help] goes to an non-existent webpage.

Solution:

  • Set Visual Studio to run as administrator (right-click the VS shortcut, select properties, compatibility tab, and check run as administrator).
  • If you are using remote debugging, also set the Visual Studio Remote Debugger to run as administrator.

Calling UpdateData in OnTimer may cause debug assertion failed or crash   Leave a comment

  • If you call UpdateData in OnTimer, you may cause a debug assertion failed:

Microsoft Visual C++ Debug Library
Debug Assertion Failed!
File: f:\spl\vctools\vc7libce\ship\atlmfc\src\mfc\dlgdata.cpp
Line: 296
(Press Retry to debug the application)

  • The last line of execution will likely be:

ASSERT(hWndOldLockout != m_hWnd);   // must not recurse

  • In Windows CE, it also seems to throw a first-chance exception/access violation.
  • Clicking continue/retry/ignore all do the same thing: it re-throws the same exception, it is non-recoverable.
  • The simple solution is to avoid calling UpdateData in OnTimer.
  • Call UpdateData somewhere else, perhaps in OnIdle.

Get the name of an object during runtime   Leave a comment

  • If you want to get the name of an object during runtime, it is very easy using a macro.
  • This method gets the name during compile and embeds it as a string literal into the code in place of the macro.
  • This works because the name of your object cannot change between compile and runtime.
  • I call this getting the name during runtime, because this method makes the name of the object available to you during runtime, even though the work of getting the name occurs during compile.
  • For example, if you have an object ‘x’ of type int, and you want to output the name of the object as a string ( “x” ), you can use the following macro:

#define GET_NAME(name) #name

  • Here is an example usage:

int x = 0;
TRACE( "%d\n", x );
TRACE( "%s\n", GET_NAME(x) );

  • The above code will output:

0
x

Posted June 21, 2013 by Ed Nafziger in C/C++, Debug

Tagged with , , , ,

CFileDialog::DoModal() causes Access Violation 0xC0000005   14 comments

  • There seems to be an issue with CFileDialog causing an unhandled exception/access violation after the CFileDialog::DoModal window is closed.
  • According to Microsoft this is a known issue, caused by a race condition, within NetworkItemFactory.dll.
  • I can easily reproduce the crash on demand at least 60% of the time.
  • Crash occurs exactly 60 seconds after closing the CFileDialog when dynamically linking MFC.
  • Crash occurs immediately after closing the CFileDialog when statically linking MFC.
  • Crash occurs also when using ::GetOpenFileName.
  • In my experience, this crash only occurs while debugging.
  • This seems completely unrelated to other reported issues of CFileDialog causing access violations with VC6/VS2003, which seem related to the structure size of OPENFILENAME.
  • I’m using Win7 SP1 64-bit with Visual Studio 2010 SP1, Platform SDK 7.1.
  • Some 3rd party software, such as having Adobe Acrobat Reader installed, seems to make the crash occur more often.

Unhandled exception at MEMORYLOCATION (ntdll.dll) in FILENAME.exe: 0xC0000005: Access violation reading location 0xfeeefeee

Steps to replicate:

  • There are many ways to replicate this crash, here is what I believe to be the absolute minimum necessary:
  • Create a new “MFC Application” project.
  • Add the following code snippet to theApp::InitInstance.
  • Put a breakpoint on the line Sleep( 1 ).
  • Start debugging.
  • Browse and select a file.
  • Wait (60 seconds) for the debugger to stop on your breakpoint.
  • Clicking Continue or pressing F5 should immediately trigger an Access Violation.
CFileDialog fileDialog( TRUE );
fileDialog.DoModal();
Sleep( 60000 );
Sleep( 1 ); // put a breakpoint here

Suggestion # 1: uninstall Acrobat Reader/Disable RPC Debugging:

  • I recommend trying this first, only because it is more convenient to try.
  • Uninstall Adobe Acrobat Reader.
  • -AND-
  • Disable RPC Debugging:
    • Tools-> Options-> Debugging-> Native-> Enable RPC debugging, uncheck it (disable it).
  • This is what fixed it for me. Seems to be 100% resolved. Tested about 300 times, zero crashes.
  • Afterwards I also installed the Hot-fix listed below, but the issue seems to have already been fixed by these steps.
  • If you’re still getting the error, try the hotfix.

Suggestion # 2: install experimental Hotfix from Microsoft:

  • Try installing this experimental Hot-fix from Microsoft (install at your own risk).
  • http://support.microsoft.com/kb/2718841/en-us
  • Thanks Kelly.
  • The Hot-fix is packaged in an self-extracting-exe. It prompts for an unzip path, which defaults to C:\, however it does not seem to accept this as a valid path. Change the path to something besides the root path.
  • The installer does not seem to automatically create a system restore point, so I suggest manually creating one prior to installing (thanks TD-er).
  • This step (or the first one listed above) should resolve the issue. If you’re still getting the error it maybe another unrelated scenario which requires some other fix.

One or both of either the above 2 items should resolve the issue. While I was still researching this issue, I found the following items to cause the crash to occur less often. I no longer consider the following items part of the solution. I still list them for educational use, in case you are interested in doing further research on this issue.

Disable 3rd party shell extensions:

  • This is not really a solution, but for some reason these seem to cause the crash to occur less often.
  • Disable buggy 3rd party shell extensions.
  • Any software which adds special icons in Windows Explorer, or which adds menu items to the desktop or Windows Explorer right-click context menu is suspect.
  • These applications should be uninstalled, or disabled using ShellExView, and then *REBOOT*.
  • I recommend using Nirsoft’s ShellExView, and disable *ALL* non-Microsoft shell extensions.

Use CoInitializeEx:

  • This is not really a solution, but for some reason these seem to cause the crash to occur less often.
  • Use CoInitialize Ex, instead of AfxOleInit or CoInitialize.
  • If you replace use of AfxOleInit, you must also add CoUninitialize in your YourApp::ExitInstance.

Debug Output:

  • The last 3 lines appear exactly 60 seconds after closing the CFileDialog.
First-chance exception at 0x7652b9bc (KernelBase.dll) in maint32.exe: 0x000006BA: The RPC server is unavailable.
First-chance exception at 0x7652b9bc (KernelBase.dll) in maint32.exe: 0x000006BA: The RPC server is unavailable.
First-chance exception at 0x7652b9bc (KernelBase.dll) in maint32.exe: 0x80010108: Server Disconnected from clients.
First-chance exception at 0x7652b9bc (KernelBase.dll) in maint32.exe: 0x80010108: Server Disconnected from clients.
First-chance exception at 0x7652b9bc (KernelBase.dll) in maint32.exe: 0x80010108: Server Disconnected from clients.
First-chance exception at 0x7677c99e (ole32.dll) in maint32.exe: 0xC0000005: Access violation reading location 0xfeeefeee.
First-chance exception at 0x7652b9bc (KernelBase.dll) in maint32.exe: 0x80010108: Server Disconnected from clients.
Unhandled exception at 0x77bb15de (ntdll.dll) in maint32.exe: 0xC0000005: Access violation reading location 0xfeeefeee.

Call Stack, main thread:

  • I enabled load all symbols in Tools-> Options-> Debug-> Symbols to get complete call stack.
ntdll.dll!_ZwRaiseException@12() + 0x12 bytes
 ntdll.dll!_ZwRaiseException@12() + 0x12 bytes
 ole32.dll!SilentlyReportExceptions(_EXCEPTION_POINTERS * lpep) Line 133 C++
 ole32.dll!ServerExceptionFilter(_EXCEPTION_POINTERS * lpep) Line 190 C++
 ole32.dll!AppInvokeExceptionFilterWithMethodAddress(_EXCEPTION_POINTERS * lpep, void * pvObject, const _GUID & riid, unsigned long dwMethod, void * pvVtableAddress, const char * szPossibleCause) Line 379 C++
 ole32.dll!AppInvokeExceptionFilter(_EXCEPTION_POINTERS * lpep, void * pvObject, const _GUID & riid, unsigned long dwMethod) Line 485 C++
 ole32.dll!FinishShutdown() Line 1037 + 0x19 bytes C++
 msvcrt.dll!@_EH4_CallFilterFunc@8() + 0x12 bytes
 msvcrt.dll!__except_handler4_common() + 0x87 bytes
 ole32.dll!_except_handler4(_EXCEPTION_RECORD * ExceptionRecord, _EXCEPTION_REGISTRATION_RECORD * EstablisherFrame, _CONTEXT * ContextRecord, void * DispatcherContext) Line 90 + 0x1b bytes C
 ntdll.dll!ExecuteHandler2@20() + 0x26 bytes
 ntdll.dll!ExecuteHandler@20() + 0x24 bytes
 ntdll.dll!_RtlDispatchException@8() + 0xd3 bytes
 ntdll.dll!_KiUserExceptionDispatcher@8() + 0xf bytes
 ole32.dll!CStdMarshal::Disconnect(unsigned long dwType) Line 3420 C++
 ole32.dll!DisconnectSwitch(void * pv) Line 3119 C++
 ole32.dll!CStdMarshal::DisconnectAndRelease(unsigned long dwType) Line 3167 C++
 ole32.dll!COIDTable::ThreadCleanup() Line 1760 + 0xa bytes C++
 ole32.dll!FinishShutdown() Line 1035 C++
 ole32.dll!ApartmentUninitialize(int fHostThread) Line 1291 C++
 ole32.dll!wCoUninitialize(COleTls & Tls, int fHostThread) Line 2766 + 0x8 bytes C++
 ole32.dll!CoUninitialize() Line 2620 C++
 networkitemfactory.dll!FDBackgroundThreadHandler() + 0x21 bytes
 shlwapi.dll!WrapperThreadProc() + 0xd3 bytes
 kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes
 ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes
 ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes

DebugBreak vs AfxDebugBreak vs _CrtDebugBreak vs __debugbreak   Leave a comment

  • You can use DebugBreak or one of its variants to trigger a breakpoint in your code at runtime.
  • Some functions will trigger a breakpoint in Release builds, which means if you have Visual Studio installed it will prompt to you to select a debugger, otherwise it will crash.
  • It is ridiculous to surround every call to a debug break function with preprocessor #ifdef _DEBUG blocks, or comment out every call for Release builds.
  • In my opinion, there needs to be a 100% reliable guaranteed way to call DebugBreak only in Debug builds, without resorting to surrounding every DebugBreak call with preprocessor #ifdef _DEBUG blocks, or commenting out every call to DebugBreak for release builds. Keep reading. I offer the solution.
  • There are multiple variants of the DebugBreak function and each behave differently:

DebugBreak (not recommended):

  • DebugBreak() will trigger a breakpoint in both Debug and Release builds.
  • System debugging symbols must be installed in order to use DebugBreak properly, otherwise the call stack information may be inaccurate or unavailable.
  • Not recommended, because it will trigger a breakpoint in Release builds (causing your application to crash unless you have Visual Studio installed) and call stack information is usually inaccurate or not available.

AfxDebugBreak (not recommended):

  • AfxDebugBreak() is complicated:
  • Behavior is different between 32-bit and 64-bit builds (depending if _M_IX86 is defined or undefined).
  • Behavior is different depending if _AFX_NO_DEBUG_CRT is defined or undefined.
  • Behavior is different depending if _AFX_PORTABLE is defined or undefined.
  • It may be the same as asm int 3, or calls _CrtDdgBreak, or calls DebugBreak, depending on conditions described above.
  • Not recommended, for obvious reasons.

_CrtDbgBreak (not recommended):

  • _CrtDbgBreak() will only trigger a breakpoint in Debug builds, it will do nothing in Release builds.
  • It is dependent on the _DEBUG define, which Visual Studio defines for you automatically for Debug builds.
  • It may be the same __debugbreak, or its own function with undocumented and unknown behavior, depending if _CRT_PORTABLE is defined or undefined.
  • Not recommended, but better than DebugBreak because it wont trigger a breakpoint in Release builds.

__debugbreak (not recommended):

  • __debugbreak() will trigger a breakpoint in both Debug and Release builds.
  • It is an intrinsic function (built-in to the compiler), it does not require system debugging symbols.
  • In my experience call stack information is always available and accurate.
  • Not recommended, but create a macro to call __debugbreak only in Debug builds. Keep reading!

Use custom macro (highly recommended):

  • I prefer using my own macro to call __debugbreak() in Debug builds and do nothing in Release builds, that way I have complete control over its behavior.
  • Highly recommended!
  • Add the following code to your stdafx.h:
#if !defined( MyDebugBreak )
#ifdef _DEBUG
#define MyDebugBreak() __debugbreak()
#else
#define MyDebugBreak() __noop
#endif
#endif

Conditional DebugBreak   Leave a comment

Conditional DebugBreak:

  • It would be useful to use DebugBreak with a condition, so that you can use it in a single line of code like the ASSERT macro.
  • I created my own DEBUG_BREAK macro which evaluates a condition like the ASSERT macro, and calls DebugBreak if the condition evaluates to false.
  • It only works in Debug builds without relying on NDEBUG being defined. This is a big deal for me because most of my projects do not have NDEBUG defined in every source file.
  • The result is a conditional breakpoint in a single like of code.

Add this to your stdafx.h file:

#ifdef _DEBUG
#define DEBUG_BREAK( exp ) if( !exp ) __debugbreak()
#else
#define DEBUG_BREAK( exp ) __noop
#endif

Usage:

DEBUG_BREAK( expresssion );

Posted April 10, 2012 by Ed Nafziger in C/C++, Debug, MFC, Visual Studio

Tagged with , , , ,

Data breakpoints do not work under these conditions   Leave a comment

  • There are some conditions that will prevent a data breakpoint from working even though the specified memory location changes values:

Data breakpoints do not work under these conditions: if a process that is not being debugged writes to the memory location, or if the memory location is shared between two or more processes.

Data breakpoints do not work if the memory location is updated within the kernel. For example, if memory is passed to the 32-bit Windows ReadFile function, the memory will be updated from kernel mode and the debugger does not break on the memory write.

  • The first scenario probably isn’t such a problem, because the developer should know if the memory is shared between two or more processes, so the use of data breakpoints could just be avoided in that scenario.
  • The second scenario is a big problem, because unless you are familiar with the code being debugged, there is no way you can know exactly what functions are being called unless you single step into every line of code.
  • For example, if you are using a 3rd party DLL that does not supply the source code, it may not be possible to know if the DLL functions you are using internally call kernel API functions or not.
  • ReadFile is a good example, memory changed by calling ReadFile will not trigger a data breakpoint.

REF:
How to: Set a Data Breakpoint (Native Only)

Posted January 30, 2012 by Ed Nafziger in C/C++, Debug, Visual Studio

Tagged with , , , , , , ,

memcpy in Debug mode behaves like memmove   1 comment

excerpt from Debug vs. Release by Joseph M. Newcomer (see link below):
Its definately worth reading in its entirety, not just the memcpy section.

It has been reported to me that memcpy might be implemented differently between the Debug mode and the Release mode such that a memcpy which had no problem in Debug mode will fail completely in the Release mode.

I agree!

Good luck finding any official documentation on this.

REF:
Debug vs. Release by Joseph M. Newcomer

Posted October 1, 2011 by Ed Nafziger in C/C++, Debug

Tagged with , , ,

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: