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.
Related
Ok, it may be a bit difficult to explain:
Suppose someone creates a Windows application (using C# or any other language) that uses the GetDesktopWindow() function on the user32.dll to capture a Screenshot and then sends this image to any online service.
Since it's custom made application, no anti-virus software will be able to determine that it's a virus because it's still an unknown application for it. Also, there are legitimate uses for such API, so it's not necessarily a virus, it can be a harmless window capture tool or some kind of espionage tool.
What I want to know is: Is there any way to see what a specific EXE file does regarding the Windows functions? Can I know if "myapp.exe" uses GetDesktopWindow() of user32.dll?
This is only one example. There are plenty other Windows endpoints that I would like to know when they're used by any application.
Is there a way to do that?
It depends to what lengths you want to go doing that. It's essentially a game of cat and mouse - bad actors will attempt to find new ways to circumvent your detection by jumping through some obscure hoops, you will add more sophisticated detection methods for those tricks, they will think of new tricks, and so on.
Also, it depends on whether you want to statically or dynamically determine that, and whether you actually want to know if GetDesktopWindow is called or if "the program gets a handle to the desktop window" (which can be achieved in other ways as well).
Here is a non-exhaustive list of ideas:
You could statically determine whether the function is imported by looking at the import directory. Research the PE file structure to find out more. This article may help.
This method of detection can be easily circumvented by dynamically importing the function using LoadLibrary and GetProcAddress.
You could scan the file for the string GetDesktopWindow to detect possible usage for dynamic import.
This method of detection can be easily circumvented by packing, encrypting or otherwise obfuscating the name of the dynamically imported function.
You could dynamically observe whether the GetDesktopWindow function gets called by registering an AppInit_DLL or a global hook which is injected into every new process and hook the GetDesktopWindow function from inside the process by overwriting its first bytes with a jump to your own code, notifying your detection component somehow, executing the original bytes and jumping back. (Microsoft Detours can help there.)
This method of detection can be circumvented if the target notices the hook and removes it before calling, since its in its own process space. (You could also do some tricks with acting like a debugger and setting a hardware breakpoint on the first instruction of GetDesktopWindow, but yet again there would be ways to detect or circumvent that since the target could also modify the debug registers.)
You could build a driver that does this from kernel-mode instead, but now we are getting really deep.
Note that until now we focused on the actual GetDesktopWindow function from user32.dll. But what if the target will just use a different way to achieve its goal of getting a desktop window handle?
The desktop window handle for the current thread is stored in the TIB (thread information block) which is accessible via fs:[18] from user mode. You can see this in the GetDesktopWindow source code of ReactOS which is pretty accurate compared to Microsoft's actual implementation (which you can verify by looking at it in a debugger). The target could therefore just access the TIB and extract this value, without even calling GetDesktopWindow at all.
The target could just take a known top-level window such as the shell's hidden compatibility window which you'll get via GetShellWindow() or - to avoid detection of GetShellWindow too - for example FindWindow(NULL, "Program Manager") (or even a newly created window!) and call GetAncestor(hWnd, GA_PARENT) on it to get the desktop window handle.
I'm sure, with some creativity, your adversaries will come up with more clever ideas than these.
Also, if we take this one step further and take a look at the ultimate goal of taking a screenshot, there as well exist other ways to achieve that. First example coming to mind: They could use keybd_event to emulate pressing the PrnSc key and then read the screenshot out of the clipboard data.
So it's all a matter of how far you want to take this.
By the way, you may find the drltrace project interesting - it is a library call tracer.
When I use an enum in a switch statement in C#, I am used to add a debug break statement to the Default case to prevent adding items to the enum which are not covered by the switch. During debugging, the code will then break if it hits the Default case.
Now I am programming a beckhoff PLC and want to do the same in a CASE .. OF ELSE ...END CASE in STL. Is this possible and/or normal in PLC programming?
I don’t think you can. Also it wouldn’t be desirable to stop a PLC program and prevent it from executing machine relevant code.
Instead you could use the ADSLOGSTR function to log to the event logger. Or show a message box. This will work in both TC2 and TC3.
You can set breakpoints when you are in online-mode, but as pboedker pointed out as soon as the breakpoint is reached (unless you have a special configuration, but this is another subject) your ethercat master will timeout, your safety module will produce a com error and your drives will need a reset aswell.
If you don't have real hardware and an ethercat master attached in your project you can use breakpoints without any worries.
I personally take another approach.
I always build a separate Debug-Visualization in the plc together with a special Debug FunctionBlock which helps me to track bugs in the project.
In your case for example I would simply call a special method of the Debug-FunctionBlock with an errror code and a string when the program flow reaches the default-case.
The error code and the string would then be visualized in the Debug-Visualization.
Even if it's a little more effort than simply calling adslogstr I would rather implement a separate Debug-FunctionBlock for 3 reasons:
You need more logic than simply calling adslogstr anyway because if by any chance adslogstr is called cyclically, you end up spamming the event logger.
Reuse in other projects
You can expand the Debug-Visualization to a Test-Suite if needed, which can come in handy
You can find more info about the beckhoff visualization here:
https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_plc_intro/3523377803.html&id=
Breakpoints are possible like Filippo said. You can prevent outputs from being reset during breakpoint by setting KeepOutputsOnBP (see this: https://stackoverflow.com/a/52158801/8140625).
You could also set error/warning/note message to your Visual Studio when that happens by using ADSLOGSTR(see this: https://stackoverflow.com/a/51700613/8140625). So add a ADSLOGSTR call to your CASE ELSE with appropriate message and you will see it in error list / TwinCAT console.
Edit: Somehow missed pboedkers answer, he already answered the ADSLOGSTR.
I like the solution of Filippo. Is could be easy to change the behavior of the debug function in the future without touching the code to much.
I was thinking to much in the C# solutions :)
Thank!
Is this possible in Visual Studio to generate a text list of the methods that are being called, and possibly execution time [of returned methods]? I know about a lot of approaches to profile an application, but I think that having a clear - even if long - callstack would be helpful in improving launch performances.
Here's a code project article about this
It basically boils down to using the GetThreadContext() to capture the context of the current thread and then using StackWalk64() to walk the stack. Alternatively you can also use CaptureStackBackTrace().
These functions will only get you the list of addresses that make the stack. To get the names of the functions and line numbers you'll need to use functions from dbghelp.dll like
SymGetModuleInfo64()
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.
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.