Improvement to Debugging C++ Access Violations in Visual Studio 2015 Update 1
October 29, 2015
In this blog post I will introduce a small but useful Visual Studio 2015 Update 1 improvement for debugging C/C++ code.
When writing C/C++ code it is common to deal with complex lines that utilize multiple pointers, for example dereferencing multiple pointers on a single line. However, it can be difficult to decipher which part of that line of code is the problem when an access violation occurs. You may have previously broken up the line of code into multiple lines in order to debug this problem, but no longer. When this happens while using Visual Studio 2015 Update 1, you can easily see which pointer caused this exception. We now show a message directly in the Exception Dialog that informs you which variable was the nullptr.
Currently this capability is only available while debugging C/C++ code, but we are working toward applying the experience to .NET debugging in the future. If you’d like to see this feature for managed code, please continue to add votes and comments to this UserVoice item detailing the request.
Example
Let’s take a look at the small C++ code sample below (the full source is attached). In this example we have a series of classes, each of which contains a pointer to another class, and one function named GetHelloWorld(). In the main()method we dereference all of the pointers in order to print “Hello World”.
int main()
{
ClassA* A = new ClassA();
printf(A-> B-> C-> D-> GetHelloWorld());
return 0;
}
When I run this simple demo I get an exception for an access violation on the line printf(A-> B-> C-> D-> GetHelloWorld()); I know that something on this line must be causing the access violation. But what? With prior versions of Visual Studio, I would have to investigate further into the code to figure that out. Now with VS 2015 Update 1, all I have to do is look at the message in the Exception Dialog that pops up. The debugger tells me that a read access violation occurred and that A->B was nullptr.
Now I can break into my code knowing exactly what part of the chained line caused the access violation and can fix the issue.
Wrap up
Install Visual Studio 2015 Update 1 RC today, and try out this new feature. We are aware this functionality is highly desirable for .NET debugging as well. We’re working on it, but can’t promise when it will be available. Please vote for and comment on this UserVoice item and provide your feedback. As always, we welcome feedback with open ears so please let me know what you think in the comments section below, through Visual Studio’s Send a Smile tool, or via Twitter.
What about printf(A-> A-> A-> A-> GetHelloWorld()); How do you identify which one caused the exception?
@Vincent Ripoll — For the example you gave above, in the Exception Dialog the message should say
"A was nullptr" if the first "A" is the issue.
"A->A was nullptr" if the second "A" was the offender.
"A->A->A was nullptr" if the third "A" and so on.
What happened to "GetProcessUserModeExceptionPolicy"?
How do we use SetUnhandledExceptionFilter and not have it ignored?
Alternatively, how can we use SignalHandlerPointer and have it be the thread which seg faulted (access violation)?
@Philip Deegan — Thanks for your questions, most of these items are related to the Windows team, but I will try to answer them to the best of my ability.
GetProcessUserModeExceptionPolicy: This seems to be an undocumented export from kernel32, and the Windows team decided to remove it. It isn't uncommon for undocumented functions to come and go, but I do not know the 'why' behind this particular instance.
SetUnhandledExceptionFilter: From what I found in this documentation for SetUnhandledExceptionFilter (msdn.microsoft.com/…/ms680634(v=vs.85).aspx) It appears that it only applies when a process is not being debugged.
Additionally, I talked to a co-worker and they suggested a few possible reasons why an unhandled exception filter wouldn't be called which I have listed below:
1. Some dll that you loaded replaced your unhandled exception filter with its own and didn’t chain back to yours. You can set a function breakpoint on SetUnhandledExceptionFilter to confirm/deny this theory.
2. The exception in question is in a class of exceptions that seem like ‘corruption is detected’, and so fail fasts instead of raising an exception. Some examples where this might happen include some exceptions from the CRT, Access Violations in parts of the .NET Framework, and detected heap corruptions.
3. We are not certain, but it is possible that some frameworks decided to have their own exception back stop on the stack (__except), and to directly report exceptions that reach it.
If you are running into case of #3, and possibly in the case of #2 you may be able to fix this with some combination of a vectored exception handler and a stack-based (__except) SEH exception handler around entry points into your code.
SignalHandlerPointer: You will have to explain more of your question here. Win32 isn’t signal based. So you aren’t going to get any additional functionality by consuming some sort of SEH exception -> signal translation layer.