Debugging Synergy .NET Code

This topic includes the following sections:


The Visual Studio .NET debugger is used for debugging applications for .NET Framework on Windows (including Universal Windows Platform), and the Xamarin debugger in Visual Studio is used for debugging applications for Android and iOS. (Debugging for Linux is not currently supported.) See Visual Studio and Xamarin documentation for assistance with these debuggers, and note the following:

.define g_select  Synergex.SynergyDE.UIToolkit.GlobalState.t_selection

So, to examine g_select you would enter the following in the Watch or QuickWatch window: Synergex.SynergyDE.UIToolkit.GlobalState.t_selection.

For information on the Synergy.SynergyDE.tklib.dll library, see Using UI Toolkit with the .NET Framework.

Synergy DBL Integration includes several Synergy-specific commands for use in the Visual Studio Watch and QuickWatch windows:


Information displayed


The address for a descriptor type variable specified by expression. This works only for .NET types in Synergy records and i, d, and a Synergy types. It is used in a procedure that determines what changed a variable. See SET WATCH functionality in Visual Studio below.

^M([struct_field,] handle)

(not supported for Mono, Visual Studio 2015, or Visual Studio 2017)

The value of the specified location in the memory handle. If the field is typed as a, d, i, or id, it is displayed as that type. If it’s an array, it is displayed as an array of appropriate types.

Show channels

Channel information

Show handles

Handle information

Synergy types in the Visual Studio Memory Usage Tool

The Visual Studio Memory Usage Tool displays information on Synergy types, but it uses different names for these types:




For example, a decimal will appear as either Synergex.SynergyDE.DecimalDesc, Synergex.SynergyDE.PinDecimalDesc, or Synergex.SynergyDE.RefDecimalDesc.

Synergex.SynergyDE.Gen_Box<ns1.$$_struct1, ns1.$$_wrap_struct1>

The next example is for a boxed structure named struct2 in namespace ns1:

Synergex.SynergyDE.Gen_Couple<ns1.$$_struct2, ns1.$$_wrap_struct2>

SET WATCH functionality in Visual Studio

In traditional Synergy, if a variable’s value changes, you can find out what changed it by using WATCH variable or SET WATCH variable. But for Synergy .NET, this functionality is not available as the default in the Visual Studio debugger. Instead you must use the SOS debugging extension (which is installed with Visual Studio) as outlined in the following procedure. The SOS command !CLRStack dumps current stack traces for all threads at the point the variable changes. By examining these stack traces, you can find out which routine is writing to the variable.

1. Open your Synergy .NET project in Visual Studio, and locate or create a programmatic break or pause in execution (e.g., a point where the program waits for user input) that happens before the variable’s value is changed. You’ll need a programmatic break or pause to give you time to select Break All in step 7.
2. Set a Visual Studio breakpoint at or before the programmatic break.
3. Start debugging the program (Debug > Start Debugging).
4. When the program breaks, use the ^ADDR( ) command in a Watch or QuickWatch window to get the address of the variable. For example, if the name of your variable is my_alpha, enter the following in a Watch or QuickWatch window:

Note (or copy) the address in the Value column of the Watch or QuickWatch window. You will use the hexadecimal form of this address to set a data breakpoint in step 8. (If a decimal value is displayed in the Value column, you can right-click on the value and select Hexadecimal Display from the context menu.)

5. Detach from the process (Debug > Detach All).
6. Reattach to the process in native mode: Select Debug > Attach to Process, select the process for your program in the Available Processes area of the Attach to Process window, and then click Select. In the Select Code Type window, select Native and clear all other options. Then click OK to close the Select Code Type window, and click Attach in the Attach to Process window.

Detaching and reattaching is necessary because the debugger runs in managed mode by default but must run in native mode for the data breakpoint set in step 8 to work correctly.

7. Select Debug > Break All. You may get an error (e.g., “The process appears to be deadlocked...”) and a “No Source Available” window. Ignore these; just click OK in the error message and close the “No Source Available” window.
8. Set a data breakpoint (Debug > New Breakpoint > New Data Breakpoint) using the hexadecimal address you got in step 4. For example, if the hexadecimal address from that step is 0x0288F0C0, enter this in the Address field of the New Breakpoint window.

1. Set a breakpoint using the hexadecimal address for the variable.

Set a breakpoint using the hexadecimal address for the variable

9. When the breakpoint is set, continue program execution (Debug > Continue).
10. When the debugger breaks at the breakpoint, you’ll see the message “The following breakpoint was hit....” Click OK in this message box.
11. Select Debug > Save Dump As, and then use the Save Dump As window to save a .dmp file.
12. Stop the debugging session (Debug > Stop Debugging).
13. In Visual Studio, select File > Open > File, and then in the Open File window, select the file you saved in the previous step and click Open.
14. A window opens with the title of the .dmp file. In the Actions section of this window, select Debug with Mixed.
15. Enter the following in the Immediate Window:
.load sos

This loads the SOS debugger extension.

16. Enter the following case-sensitive SOS command in the Immediate Window:

This writes the stack traces to the Immediate Window.

Note that the program’s debugging session is over, so you won’t be able to continue debugging it.