Thursday, September 16, 2004

Multi-Process Debugging in Delphi

As many of you know, Borland's annual conference, aka “Borcon” was held this week in San Jose. I was fortunate enough to be a part of the Diamondback preview and Delphi Meet the Team event which was held Monday night. During the Diamondback preview, I showed several of the new debugger features that will be a part of Diamondback. I actually had wanted to show a bunch more than I did, but I had to compress my part of the presentation down to 5 minutes (with all the material I wanted to show, which was still not everything that's included in Diamondback, I originally had 14 minutes worth of material).

At any rate, one of the things I did show was the ability to debug both Win32 native processes and .NET managed processes from within the same IDE. The "cool thing" I wanted people to take away from seeing this was the fact that the IDE is now able to host two fairly different debugger subsystems. However, after talking to people during the Meet the Team portion of the event, most people were impressed by the fact that you could debug more than one process at a time. I received several questions from people who asked if it was possible to debug more than one Win32 native process at the same time. After the third such question, I realized that we obviously haven't done a good enough job publicizing this feature, which has been available in Delphi since version 4.

So, I 'd like to discuss a few IDE features that have been in Delphi for several years that allow you to debug more than one process at the same time. While more useful when you want to debug both a client and server at the same time, it can also be useful to debug several unrelated processes simultaneously.

Project Groups

Although not required, using project groups make multi-process debugging much more useful. If you have a project group with more than one project in it, you can start a debug session for each project in the project group. The key here is to make sure that all projects in the project group are up to date. To do this, use the “Compile all Projects” menu item in the Project menu. Once you do that, you are ready to go. Start a debug session on the active project the way you would normally start a debug session (Run, Step Over, Step Into, etc...). Now, go back to the project manager and make a different project active (the easiest way to do this is to double click the project target). The next debugger command you issue will initiate a second debug session -- if you click the green Run arrow toolbar button, the second process will be run. You will now be debugging two processes simultaneously.

Changing the Active Process

When you are debugging more than one process, only one of the processes can be active at a time. All debugger commands (things like Step Over, Pause, Reset, Show Execution Point) operate on the active process. There are several ways to change the active process. One is to use the Project Manager, as described earlier. When you activate a project in the Project Manager, if it is being debugged, it's process will become the active process. Another way is to use the drop down menu connected to the Run toolbar button (the green arrow). When you click the little down arrow next to the button to drop down the menu, it will show a list of processes currently being debugged, as well as any additional projects from the project group that can be debugged. The active process will be shown in a bold font. Choose any other item in the menu to set a new active process.

You can also change the active process using the debugger's Thread Status View. Use the local menu item “Make Current” (or double click) any non-current process to make that process active.

One additional note with regards to the active process. If any non-active process hits a breakpoint, gets notified of an exception or encounters any similar debug event, it will become the active process.

“Multi-Process” vs. “Active-Process” Debugger Views

Several of the debugger views only operate on the active process. The Call Stack view, Watch List view, Local Variables View, CPU view, and FPU view are the views that only operate on the current process. Actually to be precise, they all only operate on the current thread within the current process.

The Breakpoint List view, Thread Status view, Event Log view and the Modules view, on the other hand, are multi-process views. They will show information pertaining to all processes loaded in the debugger, rather than just the active process. For instance, if you have more than one process loaded in the debugger, the Thread Status view will show all threads in all processes. The Modules view will show all the modules that are loaded in each process. The Event Log view will show all debug events generated by all loaded processes.

“Load Process” and “Attach to Process“

In addition to using a Project Group to manage multi-process debugging, you can also use the Run Parameters dialog (or Load Process dialog if you're fortunate enough to be using the Diamondback preview) to load additional processes into the debugger. Simply bring up the dialog and specify a process that you want to debug and click the Load button. Do this more than once and you are debugging multiple processes!

You can also initiate a multi-process debugging session using the Attach to Process dialog. You can use this dialog to attach to as many processes as you like.

Additional Note

One other question I received was “Is there a limit to the number of processes I can debug?“. You'll only be limited by your available system resources. The IDE does nothing to limit the number of processes you can debug, but keep in mind that symbol tables tend to be memory-hogs, so if you have a large project group or lots of processes loaded in the debugger at the same time, you're likely to run into some limitations. FWIW, this is one of the performance issues we hope to improve on before we unleash Diamonback into the wild.

Happy Multi-Process Debugging!

No comments: