What is the purpose of the Call Stack window in Visual Studio?
When your code breaks (i.e., when an exception is thrown) the Stack Trace Window will show you all methods that have been called prior to the method that raised the exception, including the parameters for each method and the state of these parameters. This makes debugging easier, especially in more complex call graphs (that is, when you cannot determine by looking at your code who called what other method/property/function).
Just try it, place a breakpoint somewhere in your code (F9), run your code, wait for the breakpoint to be hit and then open the stack window. You'll see all calls up to the current line. You can double click each entry in the stack trace window and the cursor will jump right at it.
In case you wondered: gray lines are method calls of which no source code, or symbols are loaded. You can rightclick these lines and select Load Symbols to load the symbols.
Each time you call a method, an entry is place on the "stack" for that thread describing the method and the parameters used to call the method. When the method returns, the method and it's parameters are removed from the stack. That's how the operating environment knows where to return when a method finishes. It just removes the top entry from the stack, cleans up any local variables that were created during that stack frame, and returns to the previous method. (That's over simplified, but generally the idea.)
You can think of it literally as a "stack" of the instructions that got you here.
That's what it means to the operating environment.
To the developer, the practical purpose is to help you understand why your program is in the state it is in. Whenever execution of the program stops in the debugger, either by breakpoint or by an exception being thrown (depending on your Visual Studio settings), you will have access to the current stack. Remember that this stack doesn't show ALL methods that have been called up to this point. Any method that completed was removed from the stack. It's not a log.
You can double click on any of the entries in the stack to go to that source code (if it's available on your machine). While you're there, you can inspect local variables, etc. It's a kind of detective tool to help you figure out what has happened in your program up to this point.
The purpose in the call stack is to allow you to see exactly what call caused an issue to happen.
When you look at the stack trace in an Exception, you can see the original call that caused the error to happen.
When debugging in Visual Studio, you can navigate up and down the call stack to see what values your application is storing at different levels. It's useful in debugging how your application got to the state it is in.
The purpose of the call stack window is to provide you access to the full code path which got you to the current instruction. You can use it to navigate to previous function calls within the program, inspect local variables, parameters, etc ... It's an invaluable tool for determining why your code is doing what it's doing.
Related
windows release windbg preview with TTD(time trave debugging).
It's very brilliant. But I meet a problem.
When I set TTD, I can not edit register or memory data, like this
How can I edit register value, then save status and continue. So there are two status, one status is that register is changed, another is not changed.
I'm not familiar with TTD, so TTD can do this or has a function like this?
No it's not possible.
TTD is basically a trace record of a program execution. Put simply it goes like this: for each instruction executed by the program, record (in a database) the state of all the registers, which memory address is accessed (if any) what is its value (and if a write happens what is the new value).
What you have at the end is the execution database, a trace of what your program did; you can interrogate the database, go wherever you want in it, even backward (which is why it is possible to "execute" something backward in TTD) but remember: the execution has already happened when you are using TTD, you are just 'browsing' through the execution database.
You are not allowed to change anything in the database, because doing so would impact the remaining of the program execution and, as the program execution has already been made, the debugger would have not mean to execute the new changes.
side note: there are some "debuggers" (more exactly proof of concept tools) that allows this kind of execution (record a trace, and then change the trace), in this case the execution is a mix between symbolic and what is called concolic execution. It is still an open problem in computer science as it leads quickly to combinatoric "explosion" due to all the cascading effects instructions generates.
Currently, I see a recurring error:
2013-04-18 02:35:51.583 aaah[1713:1110f] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x1fc00dc0> was mutated while being enumerated.'
In the failing background queue (I see my queues state upon the moment of a crash by pressing Command + 5) I see:
0 _pthread_kill
1 pthread_kill
And I see assembly output which I completely don't understand.
I know how to resolve this kind of array enumeration errors - I just can't understand where/how I should seek for the piece of code causing my app to crash.
I have much multi-threaded code using AFNetworking and Core Data, so I can't just remember where the crucial section might be.
Also, this error occurs not always, but from time to time, so it is difficult just to use "isolation approach", isolating smaller and smaller pieces of code, to finally identify the buggy piece of code.
So the question is:
How can I extract some more useful information from this output, or Xcode can provide me with some more verbosity level, so I could know how to resolve this annoying piece of code.
Have you tried setting an exception breakpoint? Sometimes the debugger struggles with exception handling inside blocks but it might help.
In the breakpoints navigator (one of the tabs on the left side of the window) click the plus button at the bottom of the window and select add an exception breakpoint. Then hit done.
Now when you crash, the debugger should hopefully put you right before the instant the exception was raised.
See http://developer.apple.com/library/mac/#recipes/xcode_help-breakpoint_navigator/articles/adding_an_exception_breakpoint.html for more info.
Edit:
Based on the feedback provided in the comments, here's some more analysis:
The exception your application is raising means that you attempted to change a collection type (in this case, an NSMutableOrderedSet) inside of an enumeration block (in your case, most likely a for-loop). It looks like you're trying to remove objects in a set that you are looping over: [NSMutableOrderedSet removeObjectsInRange:inOrderedSet:]
To resolve this you should store the ranges you wish to remove and then do the actual removing once you're no longer iterating over the set. It's still going to be difficult since, as I understand it, you're not breaking inside of Objective-C code. You should look at the running threads in the panel on the left and look at what method they're currently in. That might give you a hint as to where your code is wrong.
I read a description of how intellitrace in VS2010 Ultimate is like going back in time, in the execution of your application.
However, this sounds just like moving the line marker to a previous line (that yellow arrow in the breakpoints margin to the left of the code, when you are stepping through code).
Thanks
From Wikipedia:
Unlike the current debugger, that records only the currently-active stack, IntelliTrace records all events like prior function calls, method parameters, events, exceptions etc. This allows the code execution to be rewound in case a breakpoint wasn't set where the error occurred.
When you move the execution point back you run the same code again, but the variables might have different values. This is because running the code the first time may have changed some variables.
With Intellitrace you should be able to run the same code again with the same values as the first time. I have not tested it though.
The difference is that intellitrace keeps the history of each of those moments that it recorded. So unlike moving the line marker it is showing you the value of all the variables at that point in time. Similar to how a memory dump but for debugging.
It relies heavily on Tracing hence the name. Here is a good explanation of how it works. It's actually pretty cool.
I have a process that handles exceptions great. It calls:
_set_se_translator(exception_trans_func);
SetUnhandledExceptionFilter(UnhandledExceptionFilterHandler);
_set_purecall_handler(purecallHandler);
set_terminate(terminateHandler);
set_unexpected(unexpectedHandler);
_set_invalid_parameter_handler(InvalidParameterHandler);
atexit(exitHandler); //ignored during an expected exit
_onexit(onexitHandler); //ignored during an expected exit
Anytime an exception happens, one of the handlers is called which creates a crash dump for me. Life is good.
Except at one customer site. When they shutdown the process, there is an exception that isn't routed through these calls for some reason and they get the error:
The instruction at "0x101ba9df" referenced memory at "0x00000004". The memory could not be "read". Click OK to terminate...."
The memory reference of x000000004 looks like it's probably a null pointer. And looking at that address appears to be a global STL object's destructor (probably in the CRT's initterm call where globals are cleaned up).
Right now I'm kind of stuck though since I can't get a diagnostic dump and call stack and see exactly what is going on. So....
Why isn't the exception being routed through the above handlers, and instead being shown to the user?
Is there any way to hide that dialog (since no harm is being done at that point)?
And is there a way to track down the root error?
Thanks for any ideas.
What operating system are they running?
I assume you're setting the error mode using something like
::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
to make sure that windows isn't jumping in with its own error handling?
This sounds like the CRT has put an SEH try/catch block (can't write it properly, Markdown kicks in) around some piece of code, and is catching the exception to display the message, so you never end up calling the unhandled exception code path. You might have to do some CRT hacking to figure out what's happening.
It could be that STL code is being executed during the destruction of global variables at program shutdown time and perhaps (depending on the version of STL that you're using) some global variables that it requires have already been destroyed.
I've seen this with VS2008's STL. There are some STL lock objects that are created via a file level static during start up.
Are you using STL in your error handler functions? It could be that one of these is going off late in program shutdown and causing the problem.
I want to access the call stack at runtime in a Native C++ application. I am not using the IDE. How do I display the call stack?
Update: I have a function which is called from many points all over the application. It crashes on rare occasions. I was looking for a way to get name of the caller and log it.
Have a look at StackWalk64.
If you're used to doing this on .NET, then you're in for a nasty surprise.
I believe that this page has the answer you are looking for. You said Visual C so I assume you mean windows.
You should consider setting your unhandled exception filter and writing a minidump file from within it. It is not all that complicated and is well documented.
Just stick to the minimum of things you do once in your unhandled exception filter (read what can all go wrong if you get creative).
But to be on the safe side (your unhandled exception filter might get inadvertently overwritten), you could put your code inside __try/__except block and write the minidump from within the filter function (note, you cannot have objects that require automatic unwinding in a function with __try/__except block, if you do have them, consider putting them into a separate function):
long __stdcall myfilter(EXCEPTION_POINTERS *pexcept_info)
{
mycreateminidump(pexcept_info);
return EXCEPTION_EXECUTE_HANDLER;
}
void myfunc()
{
__try{
//your logic here
} __except(myfilter(GetExceptionInformation())) {
// exception handled
}
}
You can then inspect the dump file with a debugger of your choice. Both Visual Studio and debuggers from Windows Debugging Tools package can handle minidumps.
If you want to get a callstack of the crash, what you really want to do is post mortem debugging. If you want to check a callstack of application while it is running, this is one of many functions SysInternals Process Explorer can offer.
If you're not actively debugging, you can "crash" the app to produce a minidump (this can be done non-invasively and lets the app continue running). IIRC DrWatson will let you do this, if not userdump from MS support will.
You can then load the dump into windbg and see the callstack + variables etc there. You will need your app's symbols to make sense of the trace.
If you're looking for a simpler run-time code style traces, I recommend a simple class that you instantiate on every method, the constructor writes the method name using OutputDebugString. Use WinDebug to view the trace as the program runs. (put some form of control in your class, even if its just a global variable or registry value, or global Atom so you can turn the tracing on or off at will).
It crashes on rare occasions. I was looking for a way to get name of the caller and log it.
What do you mean by it crashes? Access Violation? Divide by zero? what exactly? Does it interact with kernel mode components?
Turn on appverifier. that should eliminate a lot of things.
create this:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\FileName.exe
under that key, create a new string
name : debugger
value: c:\pathtowindbg\windbg.exe -gG -xe av
If you're running 32bit code with WOW, you need to do this under the wow3264node.