Debugging
See Also: Profiling Plug-In Performance.
This section presents information on Debugging. This include an introduction to using the VC++ debugger, a useful API for printing debug messages, and information about the Sparks Developer Program.
Using the Visual C++ IDE to Debug MAX Plug-Ins
Overview
Developers may use the VC++ IDE to debug 3ds max plug-ins. This provides source code level debugging capabilities while execution is taking place inside the context of the plug-in. One can do things such as set breakpoints (specific lines in the source code where execution stops temporarily so the developer can examine variables, review the call stack, etc.) and establish variables to 'watch'. These variables appear in a separate window and display their current contents as they change.
Setting Up for Debugging
Developer must use the plug-in project's Hybrid configuration for debugging. The Release build does not contain any source level information and thus cannot be used. For registered developers using the special Debug SDK the Debug configuration should be used (in the description below Hybrid is always referred to however).
To begin, make sure you've compiled the Hybrid configuration so you have the debug information available. You can set the Hybrid configuration as the current one by choosing Build…/Set Active Configuration…. Then choose Build/Rebuild All. This will be create a DLL and associated files appropriate for use while debugging.
Next, VC++ needs to know where the 3ds max executable is. You can set this through the IDE by choosing Settings… from the Project pulldown menu. Then go to the Debug Tab, and with the Hybrid configuration selected (highlighted in the 'Settings for:' list), enter the full pathname to 3DSMAX.EXE. For example, under the 'Executable for debug session:' edit field enter 'd:\3dsmax\3dsmax.exe'. In the 'Working directory' field enter 'd:\3dsmax'.
Executing 3ds max and Your Plug-In
There are several ways to cause execution to halt at a specific spot in your code. One is to set a breakpoint at the spot. This is done by placing the cursor on the line where you want execution to stop and pressing F9. Then, to run the debugger simply press F5. This will launch 3ds max and get things going. 3ds max will run and load your plug-in as usual upon startup. Begin execution of your plug-in as you normally would inside 3ds max (for example, if your plug-in is a modifier apply it to an object). When execution of your plug-in's code reaches the breakpoint, control will return to VC++ and you may use its tool to examine the state of things (see the section below for more details).
A second way to reach a certain line in your code is to use 'Run to Cursor' option. This is chosen by placing the cursor on the desired line of your source file and selecting 'Build/Start Debug/Run to Cursor' (or by pressing Ctrl+F10). This will begin execution and stop when the point in your source code where the cursor sits.
Once execution is stopped, you can begin again by pressing F5, or pressing F11 to step to the next line of source or into the next function or method. Note that if you attempt to step into MAX's code (not your own) you'll wind up with a window showing the disassembly of the source (since no debugging information is available for MAX's internal code.) If this happens you can simply close this window and set another breakpoint inside your own code.
Note: Before you begin debugging it is often helpful to maximize your (main) source code window. This prevents other tiled windows from overlapping it so you won't have to scroll to see the currently executing line.
Examining Variables and the Call Stack
A Variables Windows is available to examine variables within the program's current context. This window also has a dropdown list for the call stack that shows the hierarchy of functions that are pending completion. This is handy in the case of a program crash since it can often be used to show the sequence of calls made up to the point of the crash.
Also available is a Watch Window. This will display the contents of any variable and updates automatically as the variable changes.
For additional details on these and other debugging tools see the VC++ IDE online help.
Summary
Developers may use the VC++ debugger to help develop 3ds max plug-ins. This section has presented an overview of getting started. Of particular importance is the use of the plug-in project's Hybrid configuration so source code information is available. See the section Creating a New Plug-In Project for details on setting up such a configuration.
The DebugPrint() Function
The function DebugPrint() may be used to send information to the Debug window in the Developer Studio IDE. This is handy for outputting debug information, as it only appears while debugging. This window is scrollable so a developer can print a lot of information to it, then go back to look it over. The format string works like the standard C printf() function.
void DebugPrint(const TCHAR *format, ...);
Additional Debugging Tools Available to Sparks Developers
A Debug SDK is available to registered developers. This special version of the SDK provides additional internal source code to 3ds max and is useful to help developers debug their applications deep inside MAX. Also, registered developers are provided with a special build of 3ds max compiled in Debug mode. Using this debug build, registered developers can step into parts of the core of 3ds max as they are debugging.
This special version of 3ds max has a purple animate button to distinguish it from the regular Release build of MAX. There is also a Debug menu available on the toolbar. This menu provides options to review the 3ds max command stack to see what is the current command mode and what modes have been previously pushed.
Also provided is a menu item 'Pipeline...' Each line in the dialog displayed by this command represents the state of the pipeline cache after a particular modifier or derived object.
TM refers to the Transform Matrix channel: the number in parenthesis is a zero(0) or one(1) indicating the channel is invalid (0) or valid (1).
MT refers to the Material channel, followed by its validity in parenthesis.
OB refers to the Object, and is followed by a list in parenthesis of all the object channels. If the channel is listed, it is valid, otherwise only "--" will appear for that channel.
TO is the topology channel.
GE is the geometry channel.
TX is the texture coordinate channel.
MT is the sub-object material channel.
SE is the sub-object selection channel.
SU is the sub-object selection state.
DI is the display attributes channel.
An asterisk (*) following any of these channels indicates that the channel is "locked", meaning that is a shallow copy of a channel that is owned by a cache "upstream" in the pipeline.
The numbers following "t=" and "g=" are the memory addresses of the topology and geometry channel data, respectively, which are useful for debugging problems related to the shallow copying.