aboutsummaryrefslogtreecommitdiffstats
path: root/lib/runtime_tools/doc/src/dbg.xml
blob: 74ce8ccf3f933e51c9a87648e433ee56fc7800d4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">

<erlref>
  <header>
    <copyright>
      <year>1996</year><year>2013</year>
      <holder>Ericsson AB. All Rights Reserved.</holder>
    </copyright>
    <legalnotice>
      The contents of this file are subject to the Erlang Public License,
      Version 1.1, (the "License"); you may not use this file except in
      compliance with the License. You should have received a copy of the
      Erlang Public License along with this software. If not, it can be
      retrieved online at http://www.erlang.org/.
    
      Software distributed under the License is distributed on an "AS IS"
      basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
      the License for the specific language governing rights and limitations
      under the License.
    
    </legalnotice>

    <title>dbg</title>
    <prepared>Patrik Nyblom (Claes Wikstrom)</prepared>
    <responsible></responsible>
    <docno>1</docno>
    <approved>ETX/B/SFP (Kenneth Lundin)</approved>
    <checked></checked>
    <date>96-11-07</date>
    <rev>A</rev>
    <file>dbg.sgml</file>
  </header>
  <module>dbg</module>
  <modulesummary>The Text Based Trace Facility</modulesummary>
  <description>
    <p>This module implements a text based interface to the
      <c>trace/3</c> and the <c>trace_pattern/2</c> BIFs.  It makes it
      possible to trace functions, processes and messages on text based
      terminals. It can be used instead of, or as complement to, the
      <c>pman</c> module.
      </p>
    <p>For some examples of how to use <c>dbg</c> from the Erlang
      shell, see the <seealso marker="#simple_example">simple example</seealso> section.
      </p>
    <p>The utilities are also suitable to use in system testing on
      large systems, where other tools have too much impact on the
      system performance.  Some primitive support for sequential tracing
      is also included, see the <seealso marker="#advanced">advanced topics</seealso> section.
      </p>
  </description>
  <funcs>
    <func>
      <name>fun2ms(LiteralFun) -> MatchSpec</name>
      <fsummary>Pseudo function that transforms fun syntax to match_spec.</fsummary>
      <type>
        <v>LiteralFun = fun() literal</v>
        <v>MatchSpec = term()</v>
      </type>
      <desc>
        <p>Pseudo function that by means of a <c>parse_transform</c>
          translates the <em>literal</em><c>fun()</c> typed as parameter in
          the function call to a match specification as described in
          the <c>match_spec</c> manual of <c>ERTS</c> users guide.
          (with literal I mean that the <c>fun()</c> needs to
          textually be written as the parameter of the function, it
          cannot be held in a variable which in turn is passed to the 
          function). </p>
        <p>The parse transform is implemented in the module
          <c>ms_transform</c> and the source <em>must</em> include the
          file <c>ms_transform.hrl</c> in STDLIB for this
          pseudo function to work. Failing to include the hrl file in
          the source will result in a runtime error, not a compile
          time ditto. The include file is easiest included by adding
          the line
          <c>-include_lib("stdlib/include/ms_transform.hrl").</c> to
          the source file.</p>
        <p>The <c>fun()</c> is very restricted, it can take only a
          single parameter (the parameter list to match), a sole variable or a
          list. It needs to use the <c>is_</c>XXX guard tests and one
          cannot use language constructs that have no representation
          in a match_spec (like <c>if</c>, <c>case</c>,
          <c>receive</c> etc). The return value from the fun will be
          the return value of the resulting match_spec.</p>
        <p>Example:</p>
        <pre>
1> <input>dbg:fun2ms(fun([M,N]) when N > 3 -> return_trace() end).</input>
[{['$1','$2'],[{'>','$2',3}],[{return_trace}]}]</pre>
        <p>Variables from the environment can be imported, so that this
          works:</p>
        <pre>
2> <input>X=3.</input>
3
3> <input>dbg:fun2ms(fun([M,N]) when N > X  -> return_trace() end).</input>
[{['$1','$2'],[{'>','$2',{const,3}}],[{return_trace}]}]</pre>
        <p>The imported variables will be replaced by match_spec
          <c>const</c> expressions, which is consistent with the
          static scoping for Erlang <c>fun()</c>s. Local or global
          function calls can not be in the guard or body of the fun
          however. Calls to builtin match_spec functions of course is
          allowed:</p>
        <pre>
4> <input>dbg:fun2ms(fun([M,N]) when N > X, is_atomm(M)  -> return_trace() end).</input>
Error: fun containing local erlang function calls ('is_atomm' called in guard)\
 cannot be translated into match_spec
{error,transform_error}
5> <input>dbg:fun2ms(fun([M,N]) when N > X, is_atom(M)  -> return_trace() end).</input>
[{['$1','$2'],[{'>','$2',{const,3}},{is_atom,'$1'}],[{return_trace}]}]</pre>
        <p>As you can see by the example, the function can be called from
          the shell too. The <c>fun()</c> needs to be literally in the
          call when used from the shell as well. Other means than the 
          parse_transform are used in the shell case, but more or less
          the same restrictions apply (the exception being records,
          as they are not handled by the shell).</p>
        <warning>
          <p>If the parse_transform is not applied to a module which calls this
            pseudo function, the call will fail in runtime (with a 
            <c>badarg</c>). The module <c>dbg</c> actually exports a
            function with this name, but it should never really be called
            except for when using the function in the shell. If the
            <c>parse_transform</c> is properly applied by including
            the <c>ms_transform.hrl</c> header file, compiled code
            will never call the function, but the function call is
            replaced by a literal match_spec.</p>
        </warning>
        <p>More information is provided by the <c>ms_transform</c>
          manual page in STDLIB.</p>
      </desc>
    </func>
    <func>
      <name>h() -> ok </name>
      <fsummary>Give a list of available help items on standard output.</fsummary>
      <desc>
        <p>Gives a list of items for brief online help.</p>
      </desc>
    </func>
    <func>
      <name>h(Item) -> ok </name>
      <fsummary>Give brief help for an item.</fsummary>
      <type>
        <v>Item = atom()</v>
      </type>
      <desc>
        <p>Gives a brief help text for functions in the dbg module. The
          available items can be listed with <c>dbg:h/0</c></p>
      </desc>
    </func>
    <func>
      <name>p(Item) -> {ok, MatchDesc} | {error, term()} </name>
      <fsummary>Trace messages to and from Item.</fsummary>
      <desc>
        <p>Equivalent to <c>p(Item, [m])</c>.</p>
      </desc>
    </func>
    <func>
      <name>p(Item, Flags) -> {ok, MatchDesc} | {error, term()}</name>
      <fsummary>Trace Item according to Flags.</fsummary>
      <type>
        <v>MatchDesc = [MatchNum]</v>
        <v>MatchNum = {matched, node(), integer()} | {matched, node(), 0, RPCError}</v>
        <v>RPCError = term()</v>
      </type>
      <desc>
        <p>Traces <c>Item</c> in accordance to the value specified
          by <c>Flags</c>. The variation of <c>Item</c> is listed below:</p>
        <list type="bulleted">
          <item>If the <c>Item</c> is a <c>pid()</c>, the corresponding
           process is traced.  The process may be a remote process
           (on another Erlang node). The node must be in the list of
           traced nodes (<seealso marker="#n">see</seealso><c>n/1</c> and <c>tracer/0/2/3</c>).</item>
          <item>If the <c>Item</c> is the atom <c>all</c>, all processes in the
           system as well as all processes created hereafter are
           to be traced. This also affects all nodes added with the
          <c>n/1</c> or <c>tracer/0/2/3</c> function.</item>
          <item>If the <c>Item</c> is the atom <c>new</c>, no currently existing
           processes are affected, but every process created after the
           call is.This also affects all nodes added with the
          <c>n/1</c> or <c>tracer/0/2/3</c> function.</item>
          <item>If the <c>Item</c> is the atom <c>existing</c>, all
           existing processes are traced, but new processes will not
           be affected.This also affects all nodes added with the
          <c>n/1</c> or <c>tracer/0/2/3</c> function.</item>
          <item>If the <c>Item</c> is an atom other than <c>all</c>,
          <c>new</c> or <c>existing</c>, the process with the
           corresponding registered name is traced.The process may be a 
           remote process (on another Erlang node). The node must be added 
           with the <c>n/1</c> or <c>tracer/0/2/3</c> function.</item>
          <item>If the <c>Item</c> is an integer, the process <c><![CDATA[<0.Item.0>]]></c> is
           traced.</item>
          <item>If the <c>Item</c> is a tuple <c>{X, Y, Z}</c>, the
           process <c><![CDATA[<X.Y.Z>]]></c> is
           traced. </item>
	  <item>If the <c>Item</c> is a string <![CDATA["<X.Y.Z>"]]>
	    as returned from <c>pid_to_list/1</c>, the process
	   <c><![CDATA[<X.Y.Z>]]></c> is traced. </item>
        </list>
        <p><c>Flags</c> can be a single atom,
          or a list of flags. The available flags are:
          </p>
        <taglist>
          <tag><c>s (send)</c></tag>
          <item>
            <p>Traces the messages the process sends.</p>
          </item>
          <tag><c>r (receive)</c></tag>
          <item>
            <p>Traces the messages the process receives.</p>
          </item>
          <tag><c>m (messages)</c></tag>
          <item>
            <p>Traces the messages the process receives and sends.</p>
          </item>
          <tag><c>c (call)</c></tag>
          <item>
            <p>Traces global function calls for the process
              according to the trace patterns set in the system (see tp/2).</p>
          </item>
          <tag><c>p (procs)</c></tag>
          <item>
            <p>Traces process related events to the process.</p>
          </item>
          <tag><c>sos (set on spawn)</c></tag>
          <item>
            <p>Lets all processes created by the traced
              process inherit the trace flags 
              of the traced process.</p>
          </item>
          <tag><c>sol (set on link)</c></tag>
          <item>
            <p>Lets another process, <c>P2</c>, inherit the
              trace flags of the traced 
              process whenever the traced process links to <c>P2</c>.</p>
          </item>
          <tag><c>sofs (set on first spawn)</c></tag>
          <item>
            <p>This is the same as <c>sos</c>, but only 
              for the first process spawned by the traced process.</p>
          </item>
          <tag><c>sofl (set on first link)</c></tag>
          <item>
            <p>This is the same as <c>sol</c>, but only for
              the first call to 
              <c>link/1</c> by the traced process.</p>
          </item>
          <tag><c>all</c></tag>
          <item>
            <p>Sets all flags.</p>
          </item>
          <tag><c>clear</c></tag>
          <item>
            <p>Clears all flags.
              </p>
          </item>
        </taglist>
        <p>The list can also include any of the flags allowed in 
          <c>erlang:trace/3</c></p>
        <p>The function returns either an error tuple or a tuple
          <c>{ok, List}</c>. The <c>List</c> consists of
          specifications of how many processes that matched (in the
          case of a pure pid() exactly 1). The specification of
          matched processes is <c>{matched, Node, N}</c>. If the
          remote processor call,<c>rpc</c>, to a remote node fails,
          the <c>rpc</c> error message is delivered as a fourth
          argument and the number of matched processes are 0. Note
          that the result {ok, List} may contain a list where
          <c>rpc</c> calls to one, several or even all nodes failed.</p>
      </desc>
    </func>
    <func>
      <name>c(Mod, Fun, Args)</name>
      <fsummary>Evaluate <c>apply(M,F,Args)</c>with <c>all</c>trace flags set.</fsummary>
      <desc>
        <p>Equivalent to <c>c(Mod, Fun, Args, all)</c>.</p>
      </desc>
    </func>
    <func>
      <name>c(Mod, Fun, Args, Flags)</name>
      <fsummary>Evaluate <c>apply(M,F,Args)</c>with <c>Flags</c>trace flags set.</fsummary>
      <desc>
        <p>Evaluates the expression <c>apply(Mod, Fun, Args)</c> with the trace
          flags in <c>Flags</c> set. This is a convenient way to trace processes 
          from the Erlang shell.</p>
      </desc>
    </func>
    <func>
      <name>i() -> ok</name>
      <fsummary>Display information about all traced processes.</fsummary>
      <desc>
        <p>Displays information about all traced processes.</p>
      </desc>
    </func>
    <func>
      <name>tp(Module,MatchSpec)</name>
      <fsummary>Set pattern for traced global function calls</fsummary>
      <desc>
        <p>Same as tp({Module, '_', '_'}, MatchSpec)</p>
      </desc>
    </func>
    <func>
      <name>tp(Module,Function,MatchSpec)</name>
      <fsummary>Set pattern for traced global function calls</fsummary>
      <desc>
        <p>Same as tp({Module, Function, '_'}, MatchSpec)</p>
      </desc>
    </func>
    <func>
      <name>tp(Module, Function, Arity, MatchSpec)</name>
      <fsummary>Set pattern for traced global function calls</fsummary>
      <desc>
        <p>Same as tp({Module, Function, Arity}, MatchSpec)</p>
      </desc>
    </func>
    <func>
      <name>tp({Module, Function, Arity}, MatchSpec) -> {ok, MatchDesc} | {error, term()}</name>
      <fsummary>Set pattern for traced global function calls</fsummary>
      <type>
        <v>Module = atom() | '_'</v>
        <v>Function = atom() | '_'</v>
        <v>Arity = integer() |'_'</v>
        <v>MatchSpec = integer() | Built-inAlias | [] | match_spec()</v>
	<v>Built-inAlias = x | c | cx</v>
        <v>MatchDesc = [MatchInfo]</v>
        <v>MatchInfo = {saved, integer()} | MatchNum</v>
        <v>MatchNum = {matched, node(), integer()} | {matched, node(), 0, RPCError}</v>
      </type>
      <desc>
        <p>This function enables call trace for one or more
          functions. All exported functions matching the <c>{Module, Function, Arity}</c> argument will be concerned, but the
          <c>match_spec()</c> may further narrow down the set of function
          calls generating trace messages.</p>
        <p>For a description of the <c>match_spec()</c> syntax,
          please turn to the
          <em>User's guide</em> part of the online
          documentation for the runtime system (<em>erts</em>). The
          chapter <em>Match Specification in Erlang</em> explains the 
          general match specification "language".</p>
        <p>The Module, Function and/or Arity parts of the tuple may
          be specified as the atom <c>'_'</c> which is a "wild-card"
          matching all modules/functions/arities. Note, if the
          Module is specified as <c>'_'</c>, the Function and Arity
          parts have to be specified as '_' too. The same holds for the
          Functions relation to the Arity.</p>
        <p>All nodes added with <c>n/1</c> or <c>tracer/0/2/3</c> will
          be affected by this call, and if Module is not <c>'_'</c>
          the module will be loaded on all nodes.</p>
        <p>The function returns either an error tuple or a tuple
          <c>{ok, List}</c>. The <c>List</c> consists of specifications of how
          many functions that matched, in the same way as the processes
          are presented in the return value of <c>p/2</c>. </p>
        <p>There may be a tuple <c>{saved, N}</c> in the return value,
          if the MatchSpec is other
          than []. The integer <c>N</c> may then be used in
          subsequent calls to this function and will stand as an
          "alias" for the given expression. There are also a couple of
	  built-in aliases for common expressions, see <c>ltp/0</c> below 
	  for details.</p>
        <p>If an error is returned, it can be due to errors in
          compilation of the match specification. Such errors are
          presented as a list of tuples <c>{error, string()}</c> where
          the string is a textual explanation of the compilation
          error. An example:</p>
        <pre>
(x@y)4> <input>dbg:tp({dbg,ltp,0},[{[],[],[{message, two, arguments}, {noexist}]}]).</input>
{error,
 [{error,"Special form 'message' called with wrong number of
          arguments in {message,two,arguments}."},
  {error,"Function noexist/1 does_not_exist."}]}</pre>
      </desc>
    </func>
    <func>
      <name>tpl(Module,MatchSpec)</name>
      <fsummary>Set pattern for traced local (as well as global) function calls</fsummary>
      <desc>
        <p>Same as tpl({Module, '_', '_'}, MatchSpec)</p>
      </desc>
    </func>
    <func>
      <name>tpl(Module,Function,MatchSpec)</name>
      <fsummary>Set pattern for traced local (as well as global) function calls</fsummary>
      <desc>
        <p>Same as tpl({Module, Function, '_'}, MatchSpec)</p>
      </desc>
    </func>
    <func>
      <name>tpl(Module, Function, Arity, MatchSpec)</name>
      <fsummary>Set pattern for traced local (as well as global) function calls</fsummary>
      <desc>
        <p>Same as tpl({Module, Function, Arity}, MatchSpec)</p>
      </desc>
    </func>
    <func>
      <name>tpl({Module, Function, Arity}, MatchSpec) -> {ok, MatchDesc} | {error, term()}</name>
      <fsummary>Set pattern for traced local (as well as global) function calls</fsummary>
      <desc>
        <p>This function works as <c>tp/2</c>, but enables
          tracing for local calls (and local functions) as well as for
          global calls (and functions).</p>
      </desc>
    </func>
    <func>
      <name>ctp()</name>
      <fsummary>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>Same as ctp({'_', '_', '_'})</p>
      </desc>
    </func>
    <func>
      <name>ctp(Module)</name>
      <fsummary>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>Same as ctp({Module, '_', '_'})</p>
      </desc>
    </func>
    <func>
      <name>ctp(Module, Function)</name>
      <fsummary>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>Same as ctp({Module, Function, '_'})</p>
      </desc>
    </func>
    <func>
      <name>ctp(Module, Function, Arity)</name>
      <fsummary>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>Same as ctp({Module, Function, Arity})</p>
      </desc>
    </func>
    <func>
      <name>ctp({Module, Function, Arity}) -> {ok, MatchDesc} | {error, term()}</name>
      <fsummary>Clear call trace pattern for the specified functions</fsummary>
      <type>
        <v>Module = atom() | '_'</v>
        <v>Function = atom() | '_'</v>
        <v>Arity = integer() | '_'</v>
        <v>MatchDesc = [MatchNum]</v>
        <v>MatchNum = {matched, node(), integer()} | {matched, node(), 0, RPCError}</v>
      </type>
      <desc>
        <p>This function disables call tracing on the specified
          functions. The semantics of the parameter is the same
          as for the corresponding function specification in
          <c>tp/2</c> or <c>tpl/2</c>. Both local and global call trace
          is disabled. </p>
        <p>The return value reflects how many functions that matched,
          and is constructed as described in <c>tp/2</c>. No tuple
          <c>{saved, N}</c> is however ever returned (for obvious reasons).</p>
      </desc>
    </func>
    <func>
      <name>ctpl()</name>
      <fsummary>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>Same as ctpl({'_', '_', '_'})</p>
      </desc>
    </func>
    <func>
      <name>ctpl(Module)</name>
      <fsummary>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>Same as ctpl({Module, '_', '_'})</p>
      </desc>
    </func>
    <func>
      <name>ctpl(Module, Function)</name>
      <fsummary>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>Same as ctpl({Module, Function, '_'})</p>
      </desc>
    </func>
    <func>
      <name>ctpl(Module, Function, Arity)</name>
      <fsummary>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>Same as ctpl({Module, Function, Arity})</p>
      </desc>
    </func>
    <func>
      <name>ctpl({Module, Function, Arity}) -> {ok, MatchDesc} | {error, term()}</name>
      <fsummary>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>This function works as <c>ctp/1</c>, but only disables
          tracing set up with <c>tpl/2</c> (not with <c>tp/2</c>).</p>
      </desc>
    </func>
    <func>
      <name>ctpg()</name>
      <fsummary>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>Same as ctpg({'_', '_', '_'})</p>
      </desc>
    </func>
    <func>
      <name>ctpg(Module)</name>
      <fsummary>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>Same as ctpg({Module, '_', '_'})</p>
      </desc>
    </func>
    <func>
      <name>ctpg(Module, Function)</name>
      <fsummary>>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>Same as ctpg({Module, Function, '_'})</p>
      </desc>
    </func>
    <func>
      <name>ctpg(Module, Function, Arity)</name>
      <fsummary>>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>Same as ctpg({Module, Function, Arity})</p>
      </desc>
    </func>
    <func>
      <name>ctpg({Module, Function, Arity}) -> {ok, MatchDesc} | {error, term()}</name>
      <fsummary>Clear call trace pattern for the specified functions</fsummary>
      <desc>
        <p>This function works as <c>ctp/1</c>, but only disables
          tracing set up with <c>tp/2</c> (not with <c>tpl/2</c>).</p>
      </desc>
    </func>
    <func>
      <name>ltp() -> ok</name>
      <fsummary>List saved and built-in match specifications on the console.</fsummary>
      <desc>
        <p>Use this function to recall all match specifications previously
          used in the session (i. e. previously saved during calls
          to <c>tp/2</c>, and built-in match specifications.
          This is very useful, as a complicated
          match_spec can be quite awkward to write. Note that the
          match specifications are lost if <c>stop/0</c> is called.</p>
        <p>Match specifications used can be saved in a file (if a
          read-write file system is present) for use in later
          debugging sessions, see <c>wtp/1</c> and <c>rtp/1</c></p>
	<p>There are three built-in trace patterns:
	  <c>exception_trace</c>, <c>caller_trace</c> 
	  and <c>caller_exception_trace</c> (or <c>x</c>, <c>c</c> and 
	  <c>cx</c> respectively). 
	  Exception trace sets a trace which will show function names, 
	  parameters, return values and exceptions thrown from functions. 
	  Caller traces display function names, parameters and information 
	  about which function called it. An example using a built-in alias:</p>
	  <pre>
(x@y)4> <input>dbg:tp(lists,sort,cx).</input>
{ok,[{matched,nonode@nohost,2},{saved,cx}]}
(x@y)4> <input>lists:sort([2,1]).</input>
(&lt;0.32.0&gt;) call lists:sort([2,1]) ({erl_eval,do_apply,5})
(&lt;0.32.0&gt;) returned from lists:sort/1 -> [1,2]
[1,2]</pre>
      </desc>
    </func>
    <func>
      <name>dtp() -> ok</name>
      <fsummary>Delete all saved match specifications.</fsummary>
      <desc>
        <p>Use this function to "forget" all match specifications
          saved during calls to <c>tp/2</c>.
          This is useful when one wants to restore other match
          specifications from a file with <c>rtp/1</c>. Use
          <c>dtp/1</c> to delete specific saved match specifications. </p>
      </desc>
    </func>
    <func>
      <name>dtp(N) -> ok</name>
      <fsummary>Delete a specific saved match_spec.</fsummary>
      <type>
        <v>N = integer()</v>
      </type>
      <desc>
        <p>Use this function to "forget" a specific match specification
          saved during calls to <c>tp/2</c>.</p>
      </desc>
    </func>
    <func>
      <name>wtp(Name) -> ok | {error, IOError}</name>
      <fsummary>Write all saved and built-in match specifications to a file</fsummary>
      <type>
        <v>Name = string()</v>
        <v>IOError = term()</v>
      </type>
      <desc>
        <p>This function will save all match specifications saved
          during the session (during calls to <c>tp/2</c>)
          and built-in match specifications in a text
          file with the name designated by <c>Name</c>. The format
          of the file is textual, why it can be edited with an
          ordinary text editor, and then restored with
          <c>rtp/1</c>. </p>
        <p>Each match spec in the file ends with a full stop
          (<c>.</c>) and new (syntactically correct) match
          specifications can be added to the file manually.</p>
        <p>The function returns <c>ok</c> or an error tuple where the
          second element contains the I/O error that made the
          writing impossible.</p>
      </desc>
    </func>
    <func>
      <name>rtp(Name) -> ok | {error, Error}</name>
      <fsummary>Read saved match specifications from file.</fsummary>
      <type>
        <v>Name = string()</v>
        <v>Error = term()</v>
      </type>
      <desc>
        <p>This function reads match specifications from a file
          (possibly) generated by the <c>wtp/1</c> function. It checks
          the syntax of all match specifications and verifies that
          they are correct. The error handling principle is "all or
          nothing", i. e. if some of the match specifications are
          wrong, none of the specifications are added to the list of
          saved match specifications for the running system. </p>
        <p>The match specifications in the file are <em>merged</em>
          with the current match specifications, so that no duplicates
          are generated. Use <c>ltp/0</c> to see what numbers were
          assigned to the specifications from the file.</p>
        <p>The function will return an error, either due to I/O
          problems (like a non existing or non readable file) or due
          to file format problems. The errors from a bad format file
          are in a more or less textual format, which will give a hint
          to what's causing the problem.          <marker id="n"></marker>
</p>
      </desc>
    </func>
    <func>
      <name>n(Nodename) -> {ok, Nodename} | {error, Reason}</name>
      <fsummary>Add a remote node to the list of traced nodes</fsummary>
      <type>
        <v>Nodename = atom()</v>
        <v>Reason = term()</v>
      </type>
      <desc>
        <p>The <c>dbg</c> server keeps a list of nodes where tracing
          should be performed. Whenever a <c>tp/2</c> call or a
          <c>p/2</c> call is made, it is executed for all nodes in this
          list including the local node (except for <c>p/2</c> with a
          specific <c>pid()</c> as first argument, in which case the
          command is executed only on the node where the designated
          process resides).
          </p>
        <p>This function adds a remote node (<c>Nodename</c>) to the
          list of nodes where tracing is performed. It starts a tracer
          process on the remote node, which will send all trace messages
          to the tracer process on the local node (via the Erlang
          distribution). If no tracer process is running on the local
          node, the error reason <c>no_local_tracer</c> is returned. The
          tracer process on the local node must be started with the
          <c>tracer/0/2</c> function.
          </p>
        <p>If <c>Nodename</c> is the local node, the error reason
          <c>cant_add_local_node</c> is returned.
          </p>
        <p>If a trace port (<seealso marker="#trace_port">see</seealso><c>trace_port/2</c>) is
          running on the local node, remote nodes can not be traced with
          a tracer process. The error reason
          <c>cant_trace_remote_pid_to_local_port</c> is returned. A
          trace port can however be started on the remote node with the
          <c>tracer/3</c> function.
          </p>
        <p>The function will also return an error if the node
          <c>Nodename</c> is not reachable.</p>
      </desc>
    </func>
    <func>
      <name>cn(Nodename) -> ok</name>
      <fsummary>Clear a node from the list of traced nodes.</fsummary>
      <type>
        <v>Nodename = atom()</v>
      </type>
      <desc>
        <p>Clears a node from the list of traced nodes. Subsequent
          calls to <c>tp/2</c> and <c>p/2</c> will not consider that
          node, but tracing already activated on the node will continue
          to be in effect.</p>
        <p>Returns <c>ok</c>, cannot fail.</p>
      </desc>
    </func>
    <func>
      <name>ln() -> ok</name>
      <fsummary>Show the list of traced nodes on the console.</fsummary>
      <desc>
        <p>Shows the list of traced nodes on the console.</p>
      </desc>
    </func>
    <func>
      <name>tracer() -> {ok, pid()} | {error, already_started}</name>
      <fsummary>Start a tracer server that handles trace messages.</fsummary>
      <desc>
        <p>This function starts a server on the local node that will
          be the recipient of all trace messages. All subsequent calls
          to <c>p/2</c> will result in messages sent to the newly
          started trace server.</p>
        <p>A trace server started in this way will simply display the
          trace messages in a formatted way in the Erlang shell
          (i. e. use io:format). See <c>tracer/2</c> for a description
          of how the trace message handler can be customized.          <marker id="tracer2"></marker>
</p>
        <p>To start a similar tracer on a remote node, use <c>n/1</c>.</p>
      </desc>
    </func>
    <func>
      <name>tracer(Type, Data) -> {ok, pid()} | {error, Error}</name>
      <fsummary>Start a tracer server with additional parameters</fsummary>
      <type>
        <v>Type = port | process</v>
        <v>Data = PortGenerator | HandlerSpec</v>
        <v>HandlerSpec = {HandlerFun, InitialData}</v>
        <v>HandlerFun = fun() (two arguments)</v>
        <v>InitialData = term()</v>
        <v>PortGenerator = fun() (no arguments)</v>
        <v>Error = term()</v>
      </type>
      <desc>
        <p>This function starts a tracer server with additional
          parameters on the local node. The first parameter, the
          <c>Type</c>, indicates if trace messages should be handled
          by a receiving process (<c>process</c>) or by a tracer port
          (<c>port</c>). For a description about tracer ports see
          <c>trace_port/2</c>.
          </p>
        <p>If <c>Type</c> is a process, a message handler function can
          be specified (<c>HandlerSpec</c>). The handler function, which
          should be a <c>fun</c> taking two arguments, will be called
          for each trace message, with the first argument containing the
          message as it is and the second argument containing the return
          value from the last invocation of the fun. The initial value
          of the second parameter is specified in the <c>InitialData</c>
          part of the <c>HandlerSpec</c>. The <c>HandlerFun</c> may
          choose any appropriate action to take when invoked, and can
          save a state for the next invocation by returning it.
          </p>
        <p>If <c>Type</c> is a port, then the second parameter should
          be a <em>fun</em> which takes no arguments and returns a
          newly opened trace port when called. Such a <em>fun</em> is
          preferably generated by calling <c>trace_port/2</c>.
          </p>
        <p>If an error is returned, it can either be due to a tracer
          server already running (<c>{error,already_started}</c>) or
          due to the <c>HandlerFun</c> throwing an exception.
          </p>
        <p>To start a similar tracer on a remote node, use
          <c>tracer/3</c>.          <marker id="trace_port"></marker>
</p>
      </desc>
    </func>
    <func>
      <name>tracer(Nodename, Type, Data) -> {ok, Nodename} | {error, Reason}</name>
      <fsummary>Start a tracer server on given node with additional parameters</fsummary>
      <type>
        <v>Nodename = atom()</v>
      </type>
      <desc>
        <p>This function is equivalent to <c>tracer/2</c>, but acts on
          the given node. A tracer is started on the node
          (<c>Nodename</c>) and the node is added to the list of traced
          nodes.
          </p>
        <note>
          <p>This function is not equivalent to <c>n/1</c>. While
            <c>n/1</c> starts a process tracer which redirects all trace
            information to a process tracer on the local node (i.e. the
            trace control node), <c>tracer/3</c> starts a tracer of any
            type which is independent of the tracer on the trace control
            node.</p>
        </note>
        <p>For details, <seealso marker="#tracer2">see</seealso><c>tracer/2</c>.</p>
      </desc>
    </func>
    <func>
      <name>trace_port(Type, Parameters) -> fun()</name>
      <fsummary>Create and returns a trace port generating<em>fun</em></fsummary>
      <type>
        <v>Type = ip | file</v>
        <v>Parameters = Filename | WrapFilesSpec | IPPortSpec</v>
        <v>Filename = string() | [string()] | atom()</v>
        <v>WrapFilesSpec = {Filename, wrap, Suffix} | {Filename, wrap, Suffix, WrapSize} | {Filename, wrap, Suffix, WrapSize, WrapCnt}</v>
        <v>Suffix = string()</v>
        <v>WrapSize = integer() >= 0 | {time, WrapTime}</v>
        <v>WrapTime = integer() >= 1</v>
        <v>WrapCnt = integer() >= 1</v>
        <v>IpPortSpec = PortNumber | {PortNumber, QueSize}</v>
        <v>PortNumber = integer()</v>
        <v>QueSize = integer()</v>
      </type>
      <desc>
        <p>This function creates a trace port generating <em>fun</em>.
          The <em>fun</em> takes no arguments and returns a newly opened
          trace port. The return value from this function is suitable as
          a second parameter to tracer/2, i.e. <c>dbg:tracer(port, dbg:trace_port(ip, 4711))</c>. </p>
        <p>A trace port is an
          Erlang port to a dynamically linked in driver that handles
          trace messages directly, without the overhead of sending them
          as messages in the Erlang virtual machine.</p>
        <p>Two trace drivers are currently implemented, the
          <c>file</c> and the <c>ip</c> trace drivers. The file driver
          sends all trace messages into one or several binary files, 
          from where they later can be fetched and processed with the
          <c>trace_client/2</c> function. The ip driver opens a TCP/IP
          port where it listens for connections. When a client
          (preferably started by calling <c>trace_client/2</c> on
          another Erlang node) connects, all trace messages are sent
          over the IP network for further processing by the remote
          client. </p>
        <p>Using a trace port significantly lowers the overhead
          imposed by using tracing.</p>
        <p>The file trace driver expects a filename or a wrap files 
          specification as parameter. A file is written with a high
          degree of buffering, why all trace messages are <em>not</em>
          guaranteed to be saved in the file in case of a system
          crash. That is the price to pay for low tracing overhead.</p>
        <p>A wrap files specification is used to limit the disk
          space consumed by the trace. The trace is written to a
          limited number of files each with a limited size. 
          The actual filenames are <c>Filename ++ SeqCnt ++ Suffix</c>, where <c>SeqCnt</c> counts as a decimal string
          from <c>0</c> to <c>WrapCnt</c> and then around again from
          <c>0</c>. When a trace term written to 
          the current file makes it longer than <c>WrapSize</c>,
          that file is closed, if the number of files in this 
          wrap trace is as many as <c>WrapCnt</c> the oldest file
          is deleted then a new file is opened to become the current.
          Thus, when a wrap trace has been stopped, there are at most
          <c>WrapCnt</c> trace files saved with a size of at least
          <c>WrapSize</c> (but not much bigger), except for 
          the last file that might even be empty. The default values
          are <c>WrapSize = 128*1024</c> and <c>WrapCnt = 8</c>.</p>
        <p>The <c>SeqCnt</c> values in the filenames are all in the
          range <c>0</c> through <c>WrapCnt</c> with a gap in the
          circular sequence. The gap is needed to find the end of the
          trace.</p>
        <p>If the <c>WrapSize</c> is specified as 
          <c>{time, WrapTime}</c>, the current file is closed when it
          has been open more than <c>WrapTime</c> milliseconds,
          regardless of it being empty or not.</p>
        <p>The ip trace driver has a queue of <c>QueSize</c> messages
          waiting to be delivered. If the driver cannot deliver messages
          as fast as they are produced by the runtime system, a special
          message is sent, which indicates how many messages that are
          dropped. That message will arrive at the handler function
          specified in <c>trace_client/3</c> as the tuple <c>{drop, N}</c> where <c>N</c> is the number of consecutive messages
          dropped. In case of heavy tracing, drop's are likely to occur,
          and they surely occur if no client is reading the trace
          messages.</p>
      </desc>
    </func>
    <func>
      <name>flush_trace_port()</name>
      <fsummary>Equivalent to flush_trace_port(node()).</fsummary>
      <desc>
        <p>Equivalent to <c>flush_trace_port(node())</c>.</p>
      </desc>
    </func>
    <func>
      <name>flush_trace_port(Nodename) -> ok | {error, Reason}</name>
      <fsummary>Flush internal data buffers in a trace driver on the given node.</fsummary>
      <desc>
        <p>Equivalent to <c>trace_port_control(Nodename,flush)</c>.</p>
      </desc>
    </func>
    <func>
      <name>trace_port_control(Operation)</name>
      <fsummary>Equivalent to trace_port_control(node(),Operation).</fsummary>
      <desc>
        <p>Equivalent to <c>trace_port_control(node(),Operation)</c>.</p>
      </desc>
    </func>
    <func>
      <name>trace_port_control(Nodename,Operation) ->  ok | {ok, Result} | {error, Reason}</name>
      <fsummary>Perform a control operation on the active trace port driver on the given node.</fsummary>
      <type>
        <v>Nodename = atom()</v>
      </type>
      <desc>
        <p>This function is used to do a control operation on the
          active trace port driver on the given node
          (<c>Nodename</c>). Which operations are allowed as well
          as their return values depend on which trace driver
          is used.</p>
        <p>Returns either <c>ok</c> or <c>{ok, Result}</c> 
          if the operation was successful, or <c>{error, Reason}</c> 
          if the current tracer is a process 
          or if it is a port not supporting the operation.</p>
        <p>The allowed values for <c>Operation</c> are:</p>
        <taglist>
          <tag><c>flush</c></tag>
          <item>
            <p>This function is used to flush the internal buffers 
              held by a trace port driver. Currently only the 
              file trace driver supports this operation. 
              Returns <c>ok</c>.</p>
          </item>
          <tag><c>get_listen_port</c></tag>
          <item>
            <p>Returns <c>{ok, IpPort}</c> where <c>IpPort</c>is
              the IP port number used by the driver listen socket.
              Only the ip trace driver supports this operation.</p>
          </item>
        </taglist>
      </desc>
    </func>
    <func>
      <name>trace_client(Type, Parameters) -> pid()</name>
      <fsummary>Start a trace client that reads messages created by a trace port driver</fsummary>
      <type>
        <v>Type = ip | file | follow_file</v>
        <v>Parameters = Filename | WrapFilesSpec | IPClientPortSpec</v>
        <v>Filename = string() | [string()] | atom()</v>
        <v>WrapFilesSpec = see trace_port/2</v>
        <v>Suffix = string()</v>
        <v>IpClientPortSpec = PortNumber | {Hostname, PortNumber}</v>
        <v>PortNumber = integer()</v>
        <v>Hostname = string()</v>
      </type>
      <desc>
        <p>This function starts a trace client that reads the output
          created by a trace port driver and handles it in mostly the
          same way as a tracer process created by the <c>tracer/0</c>
          function.</p>
        <p>If <c>Type</c> is <c>file</c>, the client reads all trace
          messages stored in the file named <c>Filename</c> or 
          specified by <c>WrapFilesSpec</c> (must be the same as used
          when creating the trace, see trace_port/2)
          and let's the default handler function format the
          messages on the console. This is one way to interpret the data
          stored in a file by the file trace port driver.</p>
        <p>If <c>Type</c> is <c>follow_file</c>, the client behaves as
          in the <c>file</c> case, but keeps trying to read (and
          process) more data
          from the file until stopped by <c>stop_trace_client/1</c>.
          <c>WrapFilesSpec</c> is not allowed as second argument 
          for this <c>Type</c>.</p>
        <p>If <c>Type</c> is <c>ip</c>, the client connects to the
          TCP/IP port <c>PortNumber</c> on the host <c>Hostname</c>,
          from where it reads trace messages until the TCP/IP connection
          is closed. If no <c>Hostname</c> is specified, the local host
          is assumed.</p>
        <p>As an example, one can let trace messages be sent over the
          network to another Erlang node (preferably <em>not</em>
          distributed), where the formatting occurs:</p>
        <p>On the node <c>stack</c> there's an Erlang node
          <c>ant@stack</c>, in the shell, type the following:</p>
        <pre>
ant@stack> <input>dbg:tracer(port, dbg:trace_port(ip,4711)).</input>
&lt;0.17.0>
ant@stack> <input>dbg:p(self(), send).</input>
{ok,1}</pre>
        <p>All trace messages are now sent to the trace port driver,
          which in turn listens for connections on the TCP/IP port
          4711. If we want to see the messages on another node,
          preferably on another host, we do like this:</p>
        <pre>
-> <input>dbg:trace_client(ip, {"stack", 4711}).</input>
&lt;0.42.0></pre>
        <p>If we now send a message from the shell on the node
          <c>ant@stack</c>, where all sends from the shell are traced:</p>
        <pre>
ant@stack> <input>self() ! hello.</input>
hello</pre>
        <p>The following will appear at the console on the node that
          started the trace client:</p>
        <pre>
(&lt;0.23.0>) &lt;0.23.0> ! hello
(&lt;0.23.0>) &lt;0.22.0> ! {shell_rep,&lt;0.23.0>,{value,hello,[],[]}}</pre>
        <p>The last line is generated due to internal message passing
          in the Erlang shell. The process id's will vary.</p>
      </desc>
    </func>
    <func>
      <name>trace_client(Type, Parameters, HandlerSpec) -> pid()</name>
      <fsummary>Start a trace client that reads messages created by a trace port driver, with a user defined handler</fsummary>
      <type>
        <v>Type = ip | file | follow_file</v>
        <v>Parameters = Filename | WrapFilesSpec | IPClientPortSpec</v>
        <v>Filename = string() | [string()] | atom()</v>
        <v>WrapFilesSpec = see trace_port/2</v>
        <v>Suffix = string()</v>
        <v>IpClientPortSpec = PortNumber | {Hostname, PortNumber}</v>
        <v>PortNumber = integer()</v>
        <v>Hostname = string()</v>
        <v>HandlerSpec = {HandlerFun, InitialData}</v>
        <v>HandlerFun = fun() (two arguments)</v>
        <v>InitialData = term()</v>
      </type>
      <desc>
        <p>This function works exactly as <c>trace_client/2</c>, but
          allows you to write your own handler function. The handler
          function works mostly as the one described in
          <c>tracer/2</c>, but will also have to be prepared to handle
          trace messages of the form <c>{drop, N}</c>, where <c>N</c> is
          the number of dropped messages. This pseudo trace message will
          only occur if the ip trace driver is used.</p>
        <p>For trace type <c>file</c>, the pseudo trace message
          <c>end_of_trace</c> will appear at the end of the trace. The
          return value from the handler function is in this case
          ignored.</p>
      </desc>
    </func>
    <func>
      <name>stop_trace_client(Pid) -> ok</name>
      <fsummary>Stop a trace client gracefully.</fsummary>
      <type>
        <v>Pid = pid()</v>
      </type>
      <desc>
        <p>This function shuts down a previously started trace
          client. The <c>Pid</c> argument is the process id returned
          from the <c>trace_client/2</c> or <c>trace_client/3</c> call.</p>
      </desc>
    </func>
    <func>
      <name>get_tracer()</name>
      <fsummary>Equivalent to get_tracer(node()).</fsummary>
      <desc>
        <p>Equivalent to <c>get_tracer(node())</c>.</p>
      </desc>
    </func>
    <func>
      <name>get_tracer(Nodename) -> {ok, Tracer}</name>
      <fsummary>Return the process or port to which all trace messages are sent.</fsummary>
      <type>
        <v>Nodename = atom()</v>
        <v>Tracer = port() | pid()</v>
      </type>
      <desc>
        <p>Returns the process or port to which all trace
          messages are sent. </p>
      </desc>
    </func>
    <func>
      <name>stop() -> stopped</name>
      <fsummary>Stop the <c>dbg</c>server and the tracing of all processes.</fsummary>
      <desc>
        <p>Stops the <c>dbg</c> server and clears all trace flags for
          all processes and all trace patterns for all functions. Also
          shuts down all trace clients and closes all trace ports.</p>
        <p>Note that no trace patterns are affected by this
          function.</p>
      </desc>
    </func>
    <func>
      <name>stop_clear() -> stopped</name>
      <fsummary>Stop the <c>dbg</c>server and the tracing of all processes, and clears trace patterns.</fsummary>
      <desc>
        <p>Same as stop/0, but also clears all trace patterns on local
          and global functions calls.</p>
      </desc>
    </func>
  </funcs>

  <section>
    <marker id="simple_example"></marker>
    <title>Simple examples - tracing from the shell</title>
    <p>The simplest way of tracing from the Erlang shell is to use
      <c>dbg:c/3</c> or <c>dbg:c/4</c>, e.g. tracing the function
      <c>dbg:get_tracer/0</c>:</p>
    <pre>
(tiger@durin)84> <input>dbg:c(dbg,get_tracer,[]).</input>
(&lt;0.154.0>) &lt;0.152.0> ! {&lt;0.154.0>,{get_tracer,tiger@durin}}
(&lt;0.154.0>) out {dbg,req,1}
(&lt;0.154.0>) &lt;&lt; {dbg,{ok,&lt;0.153.0>}}
(&lt;0.154.0>) in {dbg,req,1}
(&lt;0.154.0>) &lt;&lt; timeout
{ok,&lt;0.153.0>}
(tiger@durin)85></pre>
    <p>Another way of tracing from the shell is to explicitly start a
      <em>tracer</em> and then set the <em>trace flags</em> of your
      choice on the processes you want to trace, e.g. trace messages and
      process events:</p>
    <pre>
(tiger@durin)66> <input>Pid = spawn(fun() -> receive {From,Msg} -> From ! Msg end end).</input>
&lt;0.126.0>
(tiger@durin)67> <input>dbg:tracer().</input>
{ok,&lt;0.128.0>}
(tiger@durin)68> <input>dbg:p(Pid,[m,procs]).</input>
{ok,[{matched,tiger@durin,1}]}
(tiger@durin)69> <input>Pid ! {self(),hello}.</input>
(&lt;0.126.0>) &lt;&lt; {&lt;0.116.0>,hello}
{&lt;0.116.0>,hello}
(&lt;0.126.0>) &lt;&lt; timeout
(&lt;0.126.0>) &lt;0.116.0> ! hello
(&lt;0.126.0>) exit normal
(tiger@durin)70> <input>flush().</input>
Shell got hello
ok
(tiger@durin)71></pre>
    <p>If you set the <c>call</c> trace flag, you also have to set a
      <em>trace pattern</em> for the functions you want to trace:</p>
    <pre>
(tiger@durin)77> <input>dbg:tracer().</input>
{ok,&lt;0.142.0>}
(tiger@durin)78> <input>dbg:p(all,call).</input>
{ok,[{matched,tiger@durin,3}]}
(tiger@durin)79> <input>dbg:tp(dbg,get_tracer,0,[]).</input>
{ok,[{matched,tiger@durin,1}]}
(tiger@durin)80> <input>dbg:get_tracer().</input>
(&lt;0.116.0>) call dbg:get_tracer()
{ok,&lt;0.143.0>}
(tiger@durin)81> <input>dbg:tp(dbg,get_tracer,0,[{'_',[],[{return_trace}]}]).</input>
{ok,[{matched,tiger@durin,1},{saved,1}]}
(tiger@durin)82> <input>dbg:get_tracer().</input>
(&lt;0.116.0>) call dbg:get_tracer()
(&lt;0.116.0>) returned from dbg:get_tracer/0 -> {ok,&lt;0.143.0>}
{ok,&lt;0.143.0>}
(tiger@durin)83></pre>
  </section>

  <section>
    <marker id="advanced"></marker>
    <title>Advanced topics - combining with seq_trace</title>
    <p>The <c>dbg</c> module is primarily targeted towards
      tracing through the <c>erlang:trace/3</c> function. It is
      sometimes desired to trace messages in a more delicate way, which
      can be done with the help of the <c>seq_trace</c> module. 
      </p>
    <p><c>seq_trace</c> implements sequential tracing (known in the
      AXE10 world, and sometimes called "forlopp tracing"). <c>dbg</c>
      can interpret messages generated from <c>seq_trace</c> and the
      same tracer function for both types of tracing can be used. The
      <c>seq_trace</c> messages can even be sent to a trace port for
      further analysis.
      </p>
    <p>As a match specification can turn on sequential tracing, the
      combination of <c>dbg</c> and <c>seq_trace</c> can be quite
      powerful.  This brief example shows a session where sequential
      tracing is used:</p>
    <pre>
1> <input>dbg:tracer().</input>
{ok,&lt;0.30.0>}
2> <input>{ok, Tracer} = dbg:get_tracer().</input>
{ok,&lt;0.31.0>}
3> <input>seq_trace:set_system_tracer(Tracer).</input>
false
4> <input>dbg:tp(dbg, get_tracer, 0, [{[],[],[{set_seq_token, send, true}]}]).</input>
{ok,[{matched,nonode@nohost,1},{saved,1}]}
5> <input>dbg:p(all,call).</input>
{ok,[{matched,nonode@nohost,22}]}
6> <input>dbg:get_tracer(), seq_trace:set_token([]).</input>
(&lt;0.25.0>) call dbg:get_tracer()
SeqTrace [0]: (&lt;0.25.0>) &lt;0.30.0> ! {&lt;0.25.0>,get_tracer} [Serial: {2,4}]
SeqTrace [0]: (&lt;0.30.0>) &lt;0.25.0> ! {dbg,{ok,&lt;0.31.0>}} [Serial: {4,5}]
{1,0,5,&lt;0.30.0>,4}</pre>
    <p>This session sets the system_tracer to the same process as
      the ordinary tracer process (i. e. &lt;0.31.0&gt;) and sets the
      trace pattern for the function <c>dbg:get_tracer</c> to one that
      has the action of setting a sequential token. When the function
      is called by a traced process (all processes are traced in this
      case), the process gets "contaminated" by the token and
      <c>seq_trace</c> messages are sent both for the server request
      and the response. The <c>seq_trace:set_token([])</c> after the
      call clears the <c>seq_trace</c> token, why no messages are sent
      when the answer propagates via the shell to the console port. 
      The output would otherwise have been more noisy.</p>
  </section>

  <section>
    <title>Note of caution</title>
    <p>When tracing function calls on a group leader process (an IO process), there is risk 
      of causing a deadlock. This will happen if a group leader process generates a trace 
      message and the tracer process, by calling the trace handler function, sends an IO 
      request to the same group leader. The problem can only occur if the trace handler 
      prints to tty using an <c>io</c> function such as <c>format/2</c>. Note that when
      <c>dbg:p(all,call)</c> is called, IO processes are also traced.  
      Here's an example:</p>
    <pre>
%% Using a default line editing shell
1> <input>dbg:tracer(process, {fun(Msg,_) -> io:format("~p~n", [Msg]), 0 end, 0}).</input>
{ok,&lt;0.37.0>}
2> <input>dbg:p(all, [call]).</input>
{ok,[{matched,nonode@nohost,25}]}
3> <input>dbg:tp(mymod,[{'_',[],[]}]).</input>
{ok,[{matched,nonode@nohost,0},{saved,1}]}
4> <input>mymod:</input> % TAB pressed here
%% -- Deadlock --</pre>
    <p>Here's another example:</p>
    <pre>
%% Using a shell without line editing (oldshell)
1> <input>dbg:tracer(process).</input>
{ok,&lt;0.31.0>}
2> <input>dbg:p(all, [call]).</input>
{ok,[{matched,nonode@nohost,25}]}
3> <input>dbg:tp(lists,[{'_',[],[]}]).</input>
{ok,[{matched,nonode@nohost,0},{saved,1}]}
% -- Deadlock --</pre>
    <p>The reason we get a deadlock in the first example is because when TAB is pressed 
      to expand the function name, the group leader (which handles character input) calls
      <c>mymod:module_info()</c>. This generates a trace message which, in turn, causes the 
      tracer process to send an IO request to the group leader (by calling <c>io:format/2</c>).
      We end up in a deadlock.</p>
    <p>In the second example we use the default trace handler function. This handler
      prints to tty by sending IO requests to the <c>user</c> process. When Erlang is
      started in oldshell mode, the shell process will have <c>user</c> as its
      group leader and so will the tracer process in this example. Since <c>user</c> calls 
      functions in <c>lists</c> we end up in a deadlock as soon as the first IO request is sent.</p>
    <p>Here are a few suggestions for how to avoid deadlock:</p>
    <list type="bulleted">
      <item>Don't trace the group leader of the tracer process. If tracing has been switched on
       for all processes, call <c>dbg:p(TracerGLPid,clear)</c> to stop tracing the group leader
       (<c>TracerGLPid</c>). <c>process_info(TracerPid,group_leader)</c> tells you 
       which process this is (<c>TracerPid</c> is returned from <c>dbg:get_tracer/0</c>).</item>
      <item>Don't trace the <c>user</c> process if using the default trace handler function.</item>
      <item>In your own trace handler function, call <c>erlang:display/1</c> instead of an
      <c>io</c> function or, if <c>user</c> is not used as group leader, print to 
      <c>user</c> instead of the default group leader. Example:
      <c>io:format(user,Str,Args)</c>.</item>
    </list>
  </section>
</erlref>