0024977: There are compilation errors in products csharp sample
[occt.git] / dox / dev_guides / debug / debug.md
CommitLineData
ba06f8bb 1Debugging tools and hints {#occt_dev_guides__debug}
d4faf9e9 2=========================
3
4@tableofcontents
5
6@section occt_debug_intro Introduction
7
8This manual describes facilities included in OCCT to support debugging, and provides some hints for more efficient debug.
9
10@section occt_debug_bop Self-diagnostics in Boolean operations algorithm
11
12In real-world applications modeling operations are often performed in a long sequence, while the user sees only the final result of the whole sequence. If the final result is wrong, the first debug step is to identify the offending operation to be debugged further. Boolean operation algorithm in OCCT provides a self-diagnostic feature which can help to do that step.
13
14This feature can be activated by defining environment variable *CSF_DEBUG_BOP*, which should specify an existing writeable directory.
15
16The diagnostic code checks validity of the input arguments and the result of each Boolean operation. When an invalid situation is detected, the report consisting of argument shapes and a DRAW script to reproduce the problematic operation is saved to the directory pointed by *CSF_DEBUG_BOP*.
17
18@section occt_debug_exceptions Calling JIT debugger on exception
19
20On Windows platform when using Visual Studio compiler there is a possibility to start the debugger automatically if an exception is caught in a program running OCCT. For this, set environment variable *CSF_DEBUG* to any value. Note that this feature works only if you enable OCCT exception handler in your application by calling *OSD::SetSignal()*.
21
22@section occt_debug_call Functions for calling from debugger
23
24Modern interactive debuggers provide the possibility to execute application code at a program break point. This feature can be used to analyse the temporary objects available only in the context of the debugged code. OCCT provides several global functions that can be used in this way.
25
26Note that all these functions accept pointer to variable as <i>void*</i> to allow calling the function even when debugger does not recognize type equivalence or can not perform necessary type cast automatically. It is responsibility of the developer to provide the correct pointer. In general these functions are not guaranteed to work, thus use them with caution and at your own risk.
27
28@subsection occt_debug_call_draw Interacting with DRAW
29
ba06f8bb 30Open CASCADE Test Harness or @ref occt_user_guides__test_harness "DRAW" provides an extensive set of tools for inspection and analysis of OCCT shapes and geometric objects and is mostly used as environment for prototyping and debugging OCCT-based algorithms.
d4faf9e9 31
32In some cases the objects to be inspected are available in DRAW as results of DRAW commands. In other cases, however, it is necessary to inspect intermediate objects created by the debugged algorithm. To support this, DRAW provides a set of commands allowing the developer to store intermediate objects directly from the debugger stopped at some point during the program execution (usually at a breakpoint).
33
34~~~~~
35const char* Draw_Eval (const char *theCommandStr)
36~~~~~
37
38Evaluates a DRAW command or script.
39A command is passed as a string parameter.
40
41~~~~~
42const char* DBRep_Set (const char* theNameStr, void* theShapePtr)
43~~~~~
44
45Sets the specified shape as a value of DRAW interpreter variable with the given name.
938bb740 46- *theNameStr* - the DRAW interpreter variable name to set.
47- *theShapePtr* - a pointer to *TopoDS_Shape* variable.
d4faf9e9 48
49~~~~~
50const char* DrawTrSurf_Set (const char* theNameStr, void* theHandlePtr)
51const char* DrawTrSurf_SetPnt (const char* theNameStr, void* thePntPtr)
52const char* DrawTrSurf_SetPnt2d (const char* theNameStr, void* thePnt2dPtr)
53~~~~~
54
55Sets the specified geometric object as a value of DRAW interpreter variable with the given name.
938bb740 56- *theNameStr* - the DRAW interpreter variable name to set.
57- *theHandlePtr* - a pointer to the geometric variable (Handle to *Geom_Geometry* or *Geom2d_Curve* or descendant) to be set.
58- *thePntPtr* - a pointer to the variable of type *gp_Pnt* to be set.
59- *thePnt2dPtr* - a pointer to the variable of type *gp_Pnt2d* to be set.
d4faf9e9 60
61All these functions are defined in *TKDraw* toolkit and return a string indicating the result of execution.
62
63@subsection occt_debug_call_brep Saving and dumping shapes and geometric objects
64
65The following functions are provided by *TKBRep* toolkit and can be used from debugger prompt:
66
67~~~~~
68const char* BRepTools_Write (const char* theFileNameStr, void* theShapePtr)
69~~~~~
70
71Saves the specified shape to a file with the given name.
938bb740 72- *theFileNameStr* - the DRAW interpreter variable name to set.
73- *theShapePtr* - a pointer to *TopoDS_Shape* variable.
d4faf9e9 74
75~~~~~
76const char* BRepTools_Dump (void* theShapePtr)
77const char* BRepTools_DumpLoc (void* theShapePtr)
78~~~~~
79
80Dumps shape or its location to cout.
938bb740 81- *theShapePtr* - a pointer to *TopoDS_Shape* variable.
d4faf9e9 82
fc9b36d6 83The following function is provided by *TKMesh* toolkit:
84
85~~~~~
86const char* BRepMesh_Dump (void* theMeshHandlePtr, const char* theFileNameStr)
87~~~~~
88
89Stores mesh produced in parametric space to BREP file.
90- *theMeshHandlePtr* - a pointer to *Handle(BRepMesh_DataStructureOfDelaun)* variable.
91- *theFileNameStr* - name of file the mesh sould be stored to.
92
d4faf9e9 93The following additional function is provided by *TKGeomBase* toolkit:
94
95~~~~~
96const char* GeomTools_Dump (void* theHandlePtr)
97~~~~~
98
99Dump geometric object to cout.
938bb740 100- *theHandlePtr* - a pointer to the geometric variable (<i>Handle</i> to *Geom_Geometry* or *Geom2d_Curve* or descendant) to be set.
d4faf9e9 101
102@section occt_debug_vstudio Using Visual Studio debugger
103
104@subsection occt_debug_vstudio_command Command window
105
106Visual Studio debugger provides the Command Window (can be activated from menu <b>View / Other Windows / Command Window</b>), which can be used to evaluate variables and expressions interactively in a debug session (see http://msdn.microsoft.com/en-us/library/c785s0kz.aspx). Note that the Immediate Window can also be used but it has some limitations, e.g. does not support aliases.
107
108When the execution is interrupted by a breakpoint, you can use this window to call the above described functions in context of the currently debugged function. Note that in most cases you will need to specify explicitly context of the function by indicating the name of the DLL where it is defined.
109
110For example, assume that you are debugging a function, where local variable *TopoDS_Edge* *anEdge1* is of interest.
111The following set of commands in the Command window will save this edge to file *edge1.brep*, then put it to DRAW variable *e1* and show it maximized in the axonometric DRAW view:
112
113~~~~~
114>? ({,,TKBRep.dll}BRepTools_Write)("d:/edge1.brep",(void*)&anEdge1)
1150x04a2f234 "d:/edge1.brep"
116>? ({,,TKDraw.dll}DBRep_Set)("e1",(void*)&anEdge1)
1170x0369eba8 "e1"
118>? ({,,TKDraw.dll}Draw_Eval)("donly e1; axo; fit")
1190x029a48f0 ""
120~~~~~
121
122For convenience it is possible to define aliases to commands in this window, for instance (here ">" is prompt provided by the command window; in the Immediate window this symbol should be entered manually):
123
124~~~~~
125>alias deval ? ({,,TKDraw}Draw_Eval)
126>alias dsetshape ? ({,,TKDraw}DBRep_Set)
e3e895af 127>alias dsetgeom ? ({,,TKDraw}DrawTrSurf_Set)
128>alias dsetpnt ? ({,,TKDraw}DrawTrSurf_SetPnt)
d4faf9e9 129>alias dsetpnt2d ? ({,,TKDraw}DrawTrSurf_SetPnt2d)
130>alias saveshape ? ({,,TKBRep}BRepTools_Write)
131>alias dumpshape ? ({,,TKBRep}BRepTools_Dump)
132>alias dumploc ? ({,,TKBRep}BRepTools_DumpLoc)
fc9b36d6 133>alias dumpmesh ? ({,,TKMesh}BRepMesh_Dump)
d4faf9e9 134>alias dumpgeom ? ({,,TKGeomBase}GeomTools_Dump)
135~~~~~
136
137Note that aliases are stored in the Visual Studio user's preferences and it is sufficient to define them once on a workstation. With these aliases, the above example can be reproduced easier (note the space symbol after alias name!):
138
139~~~~~
140>saveshape ("d:/edge1.brep",(void*)&anEdge1)
1410x04a2f234 "d:/edge1.brep"
142>dsetshape ("e1",(void*)&anEdge1)
1430x0369eba8 "e1"
144>deval ("donly e1; axo; fit")
1450x029a48f0 ""
146~~~~~
147
148Note that there is no guarantee that the call will succeed and will not affect the program execution, thus use this feature at your own risk. In particular, the commands interacting with window system (such as *axo*, *vinit*, etc.) are known to cause application crash when the program is built in 64-bit mode. To avoid this, it is recommended to prepare all necessary view windows in advance, and arrange these windows to avoid overlapping with the Visual Studio window, to ensure that they are visible during debug.
149
150@subsection occt_debug_vstudio_watch Customized display of variables content
151
152Visual Studio provides a way to customize display of variables of different types in debugger windows (Watch, Autos, Locals, etc.).
153
154In Visual Studio 2005-2010 the rules for this display are defined in file *autoexp.dat* located in subfolder *Common7\\Packages\\Debugger* of the Visual Studio installation folder (hint: the path to that folder is given in the corresponding environment variable, e.g. *VS100COMNTOOLS* for vc10). This file contains two sections: *AutoExpand* and *Visualizer*. The following rules can be added to these sections to provide more convenient display of some OCCT data types.
155
156### \[AutoExpand\] section
157
158~~~~~
159; Open CASCADE classes
160Standard_Transient=<,t> count=<count,d>
161Handle_Standard_Transient=<entity,x> count=<entity->count,d> <,t>
162TCollection_AsciiString=<mylength,d> <mystring,s>
163TCollection_HAsciiString=<myString.mylength,d> <myString.mystring,s>
164TCollection_ExtendedString=<mylength,d> <mystring,su>
165TCollection_HExtendedString=<myString.mylength,d> <myString.mystring,su>
166TCollection_BaseSequence=size=<Size,d> curr=<CurrentIndex,d>
167TCollection_BasicMap=size=<mySize,d>
168NCollection_BaseSequence=size=<mySize,d> curr=<myCurrentIndex,d>
169NCollection_BaseList=length=<myLength,d>
170NCollection_BaseMap=size=<mySize,d> buckets=<myNbBuckets>
171NCollection_BaseVector=length=<myLength,d>
172TDF_Label=<myLabelNode,x> tag=<myLabelNode->myTag>
173TDF_LabelNode=tag=<myTag,d>
174TDocStd_Document=format=<myStorageFormat.mystring,su> count=<count,d> <,t>
175TopoDS_Shape=<myTShape.entity,x> <myOrient>
176gp_XYZ=<x,g>, <y,g>, <z,g>
177gp_Pnt=<coord.x,g>, <coord.y,g>, <coord.z,g>
178gp_Vec=<coord.x,g>, <coord.y,g>, <coord.z,g>
179gp_Dir=<coord.x,g>, <coord.y,g>, <coord.z,g>
180gp_XY=<x,g>, <y,g>
181gp_Pnt2d=<coord.x,g>, <coord.y,g>
182gp_Dir2d=<coord.x,g>, <coord.y,g>
183gp_Vec2d=<coord.x,g>, <coord.y,g>
184gp_Mat2d={<matrix[0][0],g>,<matrix[0][1],g>}, {<matrix[1][0],g>,<matrix[1][1],g>}
185gp_Ax1=loc={<loc.coord.x,g>, <loc.coord.y,g>, <loc.coord.z,g>} vdir={<vdir.coord.x,g>, <vdir.coord.y,g>, <vdir.coord.z,g>}
186~~~~~
187
188### \[Visualizer\] section
189
190~~~~~
191; Open CASCADE classes
192
193NCollection_Handle<*> {
194 preview ( *((($T0::Ptr*)$e.entity)->myPtr) )
195 children ( (($T0::Ptr*)$e.entity)->myPtr )
196}
197
198NCollection_List<*> {
199 preview ( #( "NCollection_List [", $e.myLength, "]" ) )
200 children ( #list( head: $c.myFirst, next: myNext ) : #(*($T1*)(&$e+1)) )
201}
202
203NCollection_Array1<*> {
204 preview ( #( "NCollection_Array1 [", $e.myLowerBound, "..", $e.myUpperBound, "]" ) )
205 children ( #array( expr: $c.myData[$i], size: 1+$c.myUpperBound ) )
206}
207
208math_Vector {
209 preview ( #( "math_Vector [", $e.LowerIndex, "..", $e.UpperIndex, "]" ) )
210 children ( #array ( expr: ((double*)($c.Array.Addr))[$i], size: 1+$c.UpperIndex ) )
211}
212
213TColStd_Array1OfReal {
214 preview ( #( "Array1OfReal [", $e.myLowerBound, "..", $e.myUpperBound, "]" ) )
215 children ( #array ( expr: ((double*)($c.myStart))[$i], size: 1+$c.myUpperBound ) )
216}
217
218Handle_TColStd_HArray1OfReal {
219 preview ( #( "HArray1OfReal [",
220 ((TColStd_HArray1OfReal*)$e.entity)->myArray.myLowerBound, "..",
221 ((TColStd_HArray1OfReal*)$e.entity)->myArray.myUpperBound, "] ",
222 [$e.entity,x], " count=", $e.entity->count ) )
223 children ( #array ( expr: ((double*)(((TColStd_HArray1OfReal*)$e.entity)->myArray.myStart))[$i],
224 size: 1+((TColStd_HArray1OfReal*)$e.entity)->myArray.myUpperBound ) )
225}
226
227TColStd_Array1OfInteger {
228 preview ( #( "Array1OfInteger [", $e.myLowerBound, "..", $e.myUpperBound, "]" ) )
229 children ( #array ( expr: ((int*)($c.myStart))[$i], size: 1+$c.myUpperBound ) )
230}
231
232Handle_TColStd_HArray1OfInteger {
233 preview ( #( "HArray1OfInteger [",
234 ((TColStd_HArray1OfInteger*)$e.entity)->myArray.myLowerBound, "..",
235 ((TColStd_HArray1OfInteger*)$e.entity)->myArray.myUpperBound, "] ",
236 [$e.entity,x], " count=", $e.entity->count ) )
237 children ( #array ( expr: ((int*)(((TColStd_HArray1OfInteger*)$e.entity)->myArray.myStart))[$i],
238 size: 1+((TColStd_HArray1OfInteger*)$e.entity)->myArray.myUpperBound ) )
239}
240
241Handle_TCollection_HExtendedString {
242 preview ( #( "HExtendedString ", [$e.entity,x], " count=", $e.entity->count,
243 " ", ((TCollection_HExtendedString*)$e.entity)->myString ) )
244 children ( #([actual members]: [$e,!] ) )
245}
246
247Handle_TCollection_HAsciiString {
248 preview ( #( "HAsciiString ", [$e.entity,x], " count=", $e.entity->count,
249 " ", ((TCollection_HAsciiString*)$e.entity)->myString ) )
250 children ( #([actual members]: [$e,!],
251 #array( expr: ((TCollection_HAsciiString*)$e.entity)->myString.mystring[$i],
252 size: ((TCollection_HAsciiString*)$e.entity)->myString.mylength) ) )
253}
254~~~~~
255
256In Visual Studio 2012 and later, visualizers can be put in a separate file in subdirectory *Visualizers*. See file *occt.natvis* for example.