All about attaching debuggers
Most of us use the debugger by launching our application from an IDE. “Start Debugging” a common command.
This not only boots our project but attaches the debugger to it. This way, when something crashes, we’re already attached and ready to inspect.
Or if any breakpoints are encountered, execution will pause and the debugger will show us where we are.
You can launch without the debugger attached, which is how all your users use your software. You can also attach at a later point.
What do you do if you are debugging a crash that happens very early on, and you are in a situation where you can’t launch via the IDE so the debugger is attached right away? Often there are functions to detect if a debugger is present. Early in your program, you can spin until a debugger is detected, so it will wait for you to attach and then continue.
You can also attach to processes on other machines. If a colleague is running into something that needs debugging, you can attach and debug as if it were running locally.
In native code, you can attach to almost any running process on your computer. You are only limited by a few things:
- Security privileges
- Availability of debug symbols and source code (this won’t prevent you, it’s just easier to understand)
- Debugger-hostile implementations (common anti-cheat technology for games, early example is StarCraft)
With Visual Studio C++, you can attach to multiple processes at once! This is useful when you are debugging a multiplayer game and you have several clients to track at once.
Lastly, debuggers are able to produce a snapshot of a program. Most often this is used when a crash occurs - capture a minimum or maximum of application state to a file. This is usually called a crash dump. With this file, your debugger can do a partial replay of this after the fact. It’s almost like attaching to a past instance.
What is your most useful method of attaching a debugger?