src: http://www.olegsych.com/2008/09/t4-tutorial-debugging-code-generation-files/
Posted by Oleg SychSeptember 13, 2008
This post is a part of the series that introduces code generation with Text Templates (also known as T4Templates) in Visual Studio using C# and Visual Basic; explains how to create reusable templates and combine them in complex code generators. In order to follow examples in this article, you need to have Visual Studio 2008 Standard Edition or higher, SQL Server 2005 or later, T4 Toolbox and T4 Editorinstalled on your computer.
Overview
As you remember from the previous article in this series, Runtime Errors are caused by exceptions thrown by code in the GeneratedTextTransformation class, which is compiled and executed by the code generation Engine.
Although the Engine reports detailed stack dump for every exception thrown, troubleshooting non-trivial runtime errors may require using a debugger to step through the template code as it executes. Because template code is running inside of Visual Studio process itself, a second instance of Visual Studio is required to serve as a debugger for the first instance, which is running the template code.
Current support for debugging of code generation templates in Visual Studio is somewhat limited. It requires you to either use a manual breakpoint in the template code to trigger the just-in-time debugger or starting a debugging instance of Visual Studio in advance and attaching it to the instance that’s running the template.
Setup
Use Visual Studio to open CrudStoredProcedures.tt created in the first article of this series (you can download the source code using links at the end of this article). As you remember, it’s a code generation file that produces a DELETE stored procedure using table schema information retrieved from SQL server using SMO.
- Simulate a runtime error by assigning null or Nothing to the server variable. This should trigger a run-time exception in the call to Database constructor.
- Save the template file or select Run Custom Tool item from context menu in Solution Explorer to trigger template transformation.
Troubleshooting Runtime Errors
C#
Visual Basic
- Just-In-Time Debugging
The quickest way to start debugging is by placing a breakpoint in the code of the template and triggering the just-in-time debugger. Note, if you are using Windows Vista or 2008 Server, this technique can hang Visual Studio. Please read the Just In Time Debugging on Windows Vista and 2008 Server section below first.
- Make sure that debug parameter of the template directive is set to True.
- Modify the template to call Debugger.Break method in the beginning of the code block.
C#
Visual Basic
- Save the template file or select Run Custom Tool item from context menu in Solution Explorer to trigger template transformation.
Debugger.Break method attempts to launch the Just-In-Time Debugger configured on your system.You should see a Visual Studio Just-In-Time Debugger dialog (shown above).
- In Visual Studio Just-In-Time Debugger dialog, select New instance of Visual Studio 2008 in the list and click Yes.
C#
Visual Basic
This will launch a new instance of Visual Studio and attach it as a debugger to the first instance which is running your template. You should see the source code of your template automatically loaded in debugger and a green line pointing where the execution point currently is.
While in debugger, you can use all standard features, like stepping through code, and windows, like Watch, Call Stack, Immediate, etc.
- Select Exceptions item from Debug menu in Visual Studio; turn on the option to break when exception is thrown and click OK.
- Select Continue item from Debug menu in Visual Studio.
The template will continue to run until it encounters the exception. At that point, the Visual Studio debugger will pause it and display the dialog shown above. You can inspect the exception object by clicking View Detail link.
- Select Continue item from Debug menu.
- Close the debugging instance of Visual Studio.
- Back in the original instance of Visual Studio, remove the call to Debugger.Break method from the template code.
Just-In-Time Debugging on Windows Vista and 2008 Server
By default on Windows Vista, the just-in-time debugger is configured to display a user-friendly dialog shown below. Although you can click the Debug the program button and start the debugger successfully, your original Visual Studio instance will hang in the end of the debugging session.
In order to avoid having to constantly kill the Visual Studio process after debugging, you will want to change Just-In-Time debugger configuration to work the same way it does on Windows XP and Windows Server 2003. This configuration is stored in registry as DbgJITDebugLaunchSetting value in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework key. It’s default value on Windows Vista is 0×10. Change it to 0×2, which is the default value on Windows XP. After making this change, you should no longer see the User-Defined Breakpoint dialog and will be able to continue using Visual Studio after debugging.
Attaching Debugger Manually
Just-in-time debugging, described above, is the fastest and most precise way to set a breakpoint in template code and hit it in the debugger. However, it may not be appropriate if the code generation file you want to debug is read-only (such as when it is stored in source control repository or received from a third-party). In this situation, you can attach the debugger manually, which takes longer but doesn’t require you to modify the template code.
- Start a second instance of Visual Studio and open the code generation file you need to debug –CrudStoredProcedures.tt in this example.
- Select Attach to Process from the Debug menu in Visual Studio.
- In the list of Available Processes, select devenv.exe and click the Attach button. This will attach the current instance of Visual Studio as a debugger for the first instance of Visual Studio running the template. Let’s call the first instance as simply Visual Studio and the second instance as Debugger.
- Back in text editor of the Debugger, where you have the CrudStoredProcedures.tt file open, click on the left side of line 8 to sent a breakpoint.
C#
Visual Basic
Normally, the red breakpoint icon would appear next to the line you clicked. However, due to limitations in the current support for template debugging, Visual Studio displays the breakpoint icon in line 2 instead.
- In the original Visual Studio instance, trigger template transformation by either saving the template or selecting Run Custom Tool from the context menu in Solution Explorer. This will trigger the breakpoint and you will see something like this in the Debugger.
C#
Visual Basic
You can use all debugging features as you would expect in regular .NET code with the exception of breakpoints. I have not found a way to place breakpoints in the template code precisely using the debugger and have to resort to manual breakpoints using Debugger.Break as described above.
- Select Continue item from Debug menu.
- Close the debugging instance of Visual Studio.
- Back in the original instance of Visual Studio, restore the original initialization code for server variable.
Conclusion
Debugging is the most powerful technique in troubleshooting runtime errors that occur during code generation. Although current support for debugging of template code in Visual Studio is somewhat limited, you can debug templates effectively by either triggering Just-In-Time debugger with Debugger.Break from template code or by attaching a separate instance of Visual Studio as a debugger in advance.
In the next article of this series, we will talk about creating reusable code generation templates.