Category Archives: Debug
- 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.
- Clicking [Help] goes to an non-existent webpage.
- 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.
- If you call UpdateData in OnTimer, you may cause a debug assertion failed:
Microsoft Visual C++ Debug Library
Debug Assertion Failed!
(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.
- 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:
- 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.
- 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).
- 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.
- 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.
- 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
- 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
- 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
DEBUG_BREAK( expresssion );
- 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.
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.
Good luck finding any official documentation on this.