-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathedebug.texi
1665 lines (1349 loc) · 73.5 KB
/
edebug.texi
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
@comment -*-texinfo-*-
@c This is part of the GNU Emacs Lisp Reference Manual.
@c Copyright (C) 1992-1994, 1998-1999, 2001-2015 Free Software
@c Foundation, Inc.
@c See the file elisp.texi for copying conditions.
@c This file can also be used by an independent Edebug User
@c Manual in which case the Edebug node below should be used
@c with the following links to the Bugs section and to the top level:
@c , Bugs and Todo List, Top, Top
@node Edebug
@section Edebug
@cindex Edebug デバッガ
EdebugはEmacs Lispプログラムのソースレベルデバッガであり、
つぎのことを行える。
@itemize @bullet
@item
各式の前後で停止して評価をステップ実行する。
@item
条件付きブレークポイント、無条件ブレークポイントを設定する。
@item
指定した条件が真の場合に停止する(グローバルブレークイベント)。
@item
各停止位置や各ブレークポイントで停止し低速/高速トレースする。
@item
Edebugの外側であるかのように、式の結果を表示したり式を評価する。
@item
Edebugが表示を更新するたびに、
自動的に式の並びを再評価しその結果を表示する。
@item
関数の出入りに関するトレース情報を出力する。
@item
エラーが発生すると停止する。
@item
Edebug自身のフレームを省いて、バックトレースを表示する。
@item
マクロや定義フォームに対して引数の評価を指定する。
@item
基本的なカバレッジテストや頻度数計測を行う。
@end itemize
以下の最初の3つの節では、Edebugを使うのに十分な情報を与えます。
@menu
* Using Edebug:: Introduction to use of Edebug.
* Instrumenting:: You must instrument your code
in order to debug it with Edebug.
* Modes: Edebug Execution Modes. Execution modes, stopping more or less often.
* Jumping:: Commands to jump to a specified place.
* Misc: Edebug Misc. Miscellaneous commands.
* Breaks:: Setting breakpoints to make the program stop.
* Trapping Errors:: Trapping errors with Edebug.
* Views: Edebug Views. Views inside and outside of Edebug.
* Eval: Edebug Eval. Evaluating expressions within Edebug.
* Eval List:: Expressions whose values are displayed
each time you enter Edebug.
* Printing in Edebug:: Customization of printing.
* Trace Buffer:: How to produce trace output in a buffer.
* Coverage Testing:: How to test evaluation coverage.
* The Outside Context:: Data that Edebug saves and restores.
* Edebug and Macros:: Specifying how to handle macro calls.
* Options: Edebug Options. Option variables for customizing Edebug.
@end menu
@node Using Edebug
@subsection Edebugの使い方
EdebugでLispプログラムをデバッグするには、
デバッグしたいLispコードをまず@dfn{処置}(instrument)しておく必要があります。
これを行う簡単な方法は、関数やマクロの定義にポイントを移動してから、
@kbd{C-u C-M-x}(前置引数を指定した@code{eval-defun})を実行します。
コードを処置する別の方法については、@xref{Instrumenting}。
関数をいったん処置しておけば、当該関数を呼び出すとEdebugを活性にします。
Edebugが活性になると実行を停止し、
読者が選択したEdebugの実行モードに応じて、
関数をステップ実行したりデバッグコマンドを検査しながら
表示を更新しつつ実行を継続します。
デフォルトの実行モードはステップ実行であり、
いったん実行を停止します。
@xref{Edebug Execution Modes}。
Edebugでは、デバッグ中のLispコードのソースを
表示したEmacsバッファを読者は見ます。
このバッファを@dfn{ソースコードバッファ}と呼びます。
このバッファは一時的に読み出し専用です。
左端の矢印は、関数の実行中の行を表します。
ポイントの初期位置は関数の実行中の行にありますが、
読者自身がポイントを移動すると変わります。
(以下の)@code{fac}の定義を処置してから@code{(fac 3)}を実行したとすると、
つぎのようになります。
ポイントは@code{if}のまえの開き括弧にあります。
@example
(defun fac (n)
=>@point{}(if (< 0 n)
(* n (fac (1- n)))
1))
@end example
@cindex 停止位置
Edebugが関数内で実行を停止できる箇所を@dfn{停止位置}(stop point)と呼びます。
これらは、リストである各部分式の前後と各変数参照のうしろにあります。
関数@code{fac}の中にある停止位置をピリオドで示します。
@example
(defun fac (n)
.(if .(< 0 n.).
.(* n. .(fac .(1- n.).).).
1).)
@end example
ソースコードバッファでは、Emacsのlispモードのコマンドに加えて
Edebugの特別なコマンドを使えます。
たとえば、つぎの停止位置まで実行するには
Edebugコマンド@key{SPC}を打ちます。
@code{fac}に入ったあとで@key{SPC}を1回打つと、
つぎのような表示になります。
@example
(defun fac (n)
=>(if @point{}(< 0 n)
(* n (fac (1- n)))
1))
@end example
式のうしろでEdebugが実行を停止すると、
式の値をエコー領域に値を表示します。
多用される他のコマンドには、
停止位置にブレークポイントを設定する@kbd{b}、
ブレークポイントに達するまで実行する@kbd{g}、
Edebugを終了してトップレベルのコマンドループへ戻る@kbd{q}があります。
Edebugのコマンド一覧を表示するには@kbd{?}を打ちます。
@node Instrumenting
@subsection Edebug向けの処置
@cindex instrumenting for Edebug
LispコードのデバッグにEdebugを使うためには、
コードをまず@dfn{処置}する必要があります。
コードを処置すると、適当な箇所でEdebugを起動するための追加コードが挿入されます。
@kindex C-M-x
@findex eval-defun @r{(Edebug)}
いったんEdebugをロードすると、
コマンド@kbd{C-M-x}(@code{eval-defun})は再定義されます。
定義内で前置引数を指定して起動すると
定義を評価するまえに処置するようになります。
(ソースコード自体は変更しない。)
変数@code{edebug-all-defs}が@code{nil}以外であると、
前置引数の意味を逆にします。
つまり、前置引数を指定し@emph{ない限り}、
@kbd{C-M-x}は関数定義を処置します。
変数@code{edebug-all-defs}のデフォルト値は@code{nil}です。
コマンド@kbd{M-x edebug-all-defs}は変数@code{edebug-all-defs}の値を
トグルします。
@findex eval-region @r{(Edebug)}
@findex eval-buffer @r{(Edebug)}
@findex eval-current-buffer @r{(Edebug)}
@code{edebug-all-defs}が@code{nil}以外であると、
コマンド@code{eval-region}、@code{eval-current-buffer}、@code{eval-buffer}も
それらが評価する定義を処置します。
同様に、@code{edebug-all-forms}は、
定義以外のフォームであっても@code{eval-region}が
@emph{任意}のフォームを処置するかどうか制御します。
これは、ミニバッファでのロードや評価には適用されません。
コマンド@kbd{M-x edebug-all-forms}はこのオプションをトグルします。
@findex edebug-eval-top-level-form
@findex edebug-defun
別のコマンド@kbd{M-x edebug-eval-top-level-form}は、
@code{edebug-all-defs}と@code{edebug-all-forms}の値に関わらず
任意のトップレベルのフォームを処置するために使えます。
@code{edebug-defun} is an alias for @code{edebug-eval-top-level-form}.
Edebugが動作中は、
コマンド@kbd{I}(@code{edebug-instrument-callee})で、
ポイントのうしろのフォームから呼ばれる関数やマクロの定義を
処置済みでなければ処置できます。
これは、Edebugが当該関数のソースを探せる場合にのみ可能です。
Edebugをロード後には、
@code{eval-region}は、処置していないものも含めて、
評価した各定義の位置を記録しています。
関数を処置後に呼び出してステップ実行する
コマンド@kbd{i}(@pxref{Jumping})も参照してください。
Edebugは、標準のスペシャルフォームすべて、
式を引数とする@code{interactive}フォーム、
無名ラムダ式、他の定義フォームをどのように処置するかわかっています。
Edebugは、マクロ呼び出しを引数に持つユーザー定義マクロをどのように
処置すべきかわかりませんから、読者がそれを指示する必要があります。
詳しくは、@pxref{Edebug and Macros}。
Edebugは、あるセッションで初めてコードを処置する場合、
フック@code{edebug-setup-hook}を実行してから
それに@code{nil}を設定します。
これを利用すると、読者が使用するパッケージに対応した
Edebug用仕様(@pxref{Instrumenting Macro Calls})を
Edebugを使用する場合にのみロードするようにできます。
@findex eval-expression @r{(Edebug)}
定義から処置を取り除くには、
処置しないような方法でその定義を単に再評価するだけです。
けっして処置せずにフォームを評価する方法は2つあります。
ファイルを@code{load}するか、
ミニバッファで@code{eval-expression}(@kbd{M-:})を使います。
Edebugが処置中に構文エラーを検出すると、
コードのエラー箇所にポイントを置いて、
エラー@code{invalid-read-syntax}を通知します。
@c FIXME? I can't see that it "leaves point at the erroneous code".
Edebugの内側で使える他の評価関数については@xref{Edebug Eval}。
@node Edebug Execution Modes
@subsection edebugの実行モード
@cindex edebugの実行モード
Edebugには読者がデバッグしているプログラムを実行するための
実行モードが複数あります。
これらを@dfn{edebugの実行モード}と呼びます。
これらをメジャーモードやマイナモードと混同しないでください。
Edebugの実行モードは、停止するまでにどの程度Edebugが実行を継続するか、
たとえば、各停止位置で停止するのかつぎのブレークポイントまで継続するのか、
また、停止するまでに評価の進行状況をどの程度Edebugが表示するのかを
決定します。
通常、あるモードにおいて、
プログラムを継続するコマンドを打つことでEdebugの実行モードを指定します。
以下にそれらのコマンドの一覧を示します。
@kbd{S}を除くすべてのコマンドは、
少なくともある程度プログラムの実行を再開します。
@table @kbd
@item S
停止:プログラムをいっさい実行せずに、
Edebugコマンドの入力を待つ(@code{edebug-stop})。
@c FIXME Does not work. http://debbugs.gnu.org/9764
@item @key{SPC}
ステップ実行:@code{ }つぎに出会う停止位置で止まる(@code{edebug-step-mode})。
@item n
つぎ:@code{ }式のうしろでつぎに出会う停止位置で止まる
(@code{edebug-next-mode})。
@ref{Edebug Misc}の@code{edebug-forward-sexp}も参照。
@item t
トレース:@code{ }Edebugの各停止位置で1秒間休止する
(@code{edebug-trace-mode})。
@item T
高速トレース:@code{ }各停止位置で表示を更新するが休止しない
(@code{edebug-Trace-fast-mode})。
@item g
実行:@code{ }つぎのブレークポイントまで実行する
(@code{edebug-go-mode})。
@xref{Breakpoints}。
@item c
継続:@code{ }各ブレークポイントで1秒間休止してから継続する
(@code{edebug-continue-mode})。
@item C
高速継続:@code{ }各ブレークポイントへポイントを移動するが休止しない
(@code{edebug-Continue-fast-mode})。
@item G
非停止実行:@code{ }ブレークポイントを無視する
(@code{edebug-Go-nonstop-mode})。
@kbd{S}や編集コマンドを打てば停止できる。
@end table
一般に、上記一覧の上にある実行モードほど下にあるものに比べると
プログラムをゆっくり実行、つまり、早く停止します。
実行中やトレース中には、Edebugコマンドをなにか打てば実行に割り込めます。
Edebugはつぎの停止位置でプログラムを止め、
読者が打ったコマンドを実行します。
たとえば、実行中に@kbd{t}を打てば、つぎの停止位置でトレースモードに
切り替わります。
単に実行を停止するには@kbd{S}を使います。
読者の関数が入力を読み取る場合、実行に割り込むつもりで打った文字を
関数が読み取ってしまうかもしれません。
読者のプログラムがいつ入力するかに注意していれば、
このような意図しない結果を避けることができます。
@cindex キーボードマクロ(Edebug)
本節で述べたコマンドを含むキーボードマクロは動作しません。
つまり、プログラムを再開するためにEdebugから抜けると
キーボードマクロの制御を失ってしまいます。
これを修正するのは簡単ではありません。
また、Edebugの外側でキーボードマクロを定義したり実行しても、
Edebug内のコマンドにはなんの影響もありません。
これは普通は利点です。
しかし、オプション@code{edebug-continue-kbd-macro}
(@ref{Edebug Options})も参照してください。
Edebugの新たなレベルに入ると、変数@code{edebug-initial-mode}の値を
実行モードの初期値とします(@pxref{Edebug Options})。
デフォルトでは、これはステップ実行モードを指定します。
処置した関数を1つのコマンドから複数回呼び出すなどして
Edebugの同一レベルに再度入ることができることに注意してください。
@defopt edebug-sit-for-seconds
This option specifies how many seconds to wait between execution steps
in trace mode or continue mode. The default is 1 second.
@end defopt
@node Jumping
@subsection ジャンプ
本節で述べるコマンドは、指定した位置に達するまで実行します。
@kbd{i}を除くすべてのものは、停止する場所に一時的なブレークポイントを
設定してから実行モードに移行します。
意図したブレークポイントより先に別のブレークポイントに達しても
実行を停止します。
ブレークポイントについて詳しくは@xref{Breakpoints}。
非ローカル脱出は、読者が意図したプログラムの停止すべき
一時的なブレークポイントを迂回するため、
これらのコマンドは非ローカル脱出があると意図したように動作しません。
@table @kbd
@item h
ポイント位置付近の停止位置まで進む(@code{edebug-goto-here})。
@item f
プログラムの式1つ分先へ進む(@code{edebug-forward-sexp})。
@item o
囲んでいるS式の終りまでプログラムを実行する(@code{edebug-step-out})。
@item i
ポイントのあとのフォームから呼ばれる関数やマクロへ進む(@code{edebug-step-in})。
@end table
コマンド@kbd{h}は、一時的なブレークポイントを使って、
ポイント位置付近の停止位置まで進みます。
コマンド@kbd{f}は、プログラムの式1つ分先へ進みます。
より正確には、@code{forward-sexp}による到達箇所へ一時的なブレークポイントを設定し、
プログラムがブレークポイントで停止するような実行モードで実行します。
前置引数@var{n}を指定すると、
ポイント位置から@var{n}個先のS式に一時的なブレークポイントを設定します。
囲んでいるリストの残り要素数が@var{n}より少なければ、
囲んでいる式の末尾で停止します。
@code{forward-sexp}による移動先は本当にプログラムが停止する箇所か、確認する必要があります。
たとえば、@code{cond}では正しくありません。
コマンド@kbd{f}は、柔軟性のために、
停止位置ではなくポイント位置で@code{forward-sexp}を使います。
@emph{現在の停止位置から}式1つだけ実行したい場合には、
まず@kbd{w}(@code{edebug-where})と打ってポイントを停止位置に移動してから@kbd{f}を打ちます。
コマンド@kbd{o}は式から『出る』まで実行します。
ポイントを含むS式の末尾に一時的なブレークポイントを置きます。
このS式が関数定義そのものである場合には、
@kbd{o}は定義の最後のS式の手前まで実行します。
現在この箇所にいた場合には、関数から戻ってから停止します。
いいかえれば、最後のS式のあとに位置していない限り、
このコマンドは現在実行中の関数から抜けません。
コマンド@kbd{i}は、
ポイント位置のあとにあるリストフォームから呼ばれる関数やマクロへ進み、
最初に出会った停止位置で止まります。
そのフォームはこれから評価されるフォームである必要はありません。
しかし、評価されるフォームが関数呼び出しである場合には、
引数を評価するまえにこのコマンドを使うことを覚えておいてください。
さもないとこのコマンドを使う時期が遅すぎます。
コマンド@kbd{i}は、呼び出す関数やマクロが処置されていないと
それらを処置します。
これは便利ですが、それらの関数やマクロは、明示的に処置を取り除かない限り、
処置したままになります。
@node Edebug Misc
@subsection edebugのその他のコマンド
Edebugの他のコマンドを以下に示します。
@table @kbd
@item ?
Edebugのヘルプメッセージを表示する(@code{edebug-help})。
@item C-]
1つまえのレベルのコマンドレベルへ戻る(@code{abort-recursive-edit})。
@item q
エディタのトップレベルのコマンドループへ戻る(@code{top-level})。
Edebugのすべての動作中のレベルを含めて、すべての再帰編集レベルから抜ける。
しかし、フォーム@code{unwind-protect}や@code{condition-case}で保護した
処置済みのコードがあるとデバッガを再開する。
@item Q
@kbd{q}と同様であるが保護したコードでも停止しない
(@code{edebug-top-level-nonstop})。
@item r
もっとも最近の式の既知の結果をエコー領域に再表示する
(@code{edebug-previous-result})。
@item d
わかりやすいようにEdebug自体の関数を除外してバックトレースを表示する
(@code{edebug-backtrace})。
Edebugのバックトレースバッファでは、
標準のデバッガのようにはデバッガのコマンドを使えない。
実行を継続するとバックトレースバッファは自動的に削除される。
@end table
Edebugの再帰編集から、Edebugを再帰的に活性にするコマンドを起動できます。
Edebugが活性であるときにはいつでも@kbd{q}でトップレベルへ戻るか、
@kbd{C-]}で1つの再帰編集レベルを抜けることができます。
保留している評価すべてのバックトレースは@kbd{d}で表示できます。
@node Breaks
@subsection Breaks
Edebug's step mode stops execution when the next stop point is reached.
There are three other ways to stop Edebug execution once it has started:
breakpoints, the global break condition, and source breakpoints.
Edebugのステップ実行モードは、つぎの停止位置に達すると実行を停止します。
Edebugが実行を止める方法は3つあります。
ブレークポイント、グローバルブレーク条件、ソースのブレークポイントです。
@menu
* Breakpoints:: Breakpoints at stop points.
* Global Break Condition:: Breaking on an event.
* Source Breakpoints:: Embedding breakpoints in source code.
@end menu
@node Breakpoints
@subsubsection ブレークポイント
@cindex ブレークポイント
Edebugを使用中には、読者がテスト中のプログラムに@dfn{ブレークポイント}
(breakpoint)、つまり、実行を停止すべき箇所を設定できます。
@ref{Using Edebug}で定義した任意の停止位置にブレークポイントを設定できます。
ブレークポイントの設定や解除において対象となる停止位置は、
ソースコードバッファのポイント位置かそのあとにある停止位置です。
ブレークポイントに関するEdebugコマンドはつぎのとおりです。
@table @kbd
@item b
ポイント位置かそのうしろにある停止位置にブレークポイントを設定する
(@code{edebug-set-breakpoint})。
前置引数を指定すると、一時的なブレークポイントになる
(そこでプログラムが停止すると解除される)。
@item u
ポイント位置かそのうしろにある停止位置の(あれば)ブレークポイントを解除する
(@code{edebug-unset-breakpoint})。
@item x @var{condition} @key{RET}
@var{condition}が@code{nil}以外の値に評価される場合にのみ
プログラムを停止する条件付きブレークポイントを設定する
(@code{edebug-set-conditional-breakpoint})。
前置引数を指定すると、一時的なブレークポイントになる。
@item B
現在の定義内にあるつぎのブレークポイントにポイント位置を移動する
(@code{edebug-next-breakpoint})。
@end table
Edebug内では、@kbd{b}でブレークポイントを設定し、
@kbd{u}で解除できます。
まず目的のedegugの停止位置にポイント位置を移動し、
@kbd{b}を打ってその箇所にブレークポイントを設定したり、
@kbd{u}を打ってその箇所のブレークポイントを解除します。
設定されていないブレークポイントを解除しても、なにも起こりません。
定義を再評価したり再処置すると、その中のブレークポイントすべてを解除します。
@dfn{条件付きブレークポイント}(conditional breakpoint)は、
プログラムがこの箇所に達するたびに条件を検査します。
条件を評価中に発生するどんなエラーも無視し、
@code{nil}として扱います。
条件付きブレークポイントを設定するには@kbd{x}を使い、
条件式はミニバッファで指定します。
すでに条件付きブレークポイントを設定してある停止位置に
条件付きブレークポイントを設定し直すと、
それまでの条件式がミニバッファに入るので編集できます。
ブレークポイントを設定するコマンドに前置引数を指定すると、
条件付き/無条件ブレークポイントを@dfn{一時的}なものにできます。
一時的ブレークポイントでプログラムが停止すると、
そのブレークポイントは自動的に解除されます。
Edebugのモードが非停止実行でなければ、
Edebugはブレークポイントでつねに停止するか休止します。
非停止実行モードでは、ブレークポイントを完全に無視します。
ブレークポイントの場所を確認するには、コマンド@kbd{B}を使います。
同じ関数内のポイント箇所のうしろにあるブレークポイントか、
後続のものがなければ最初のブレークポイントにポイント位置を移動します。
このコマンドは実行を継続しません。
バッファ内で単にポイントを移動するだけです。
@node Global Break Condition
@subsubsection グローバルブレーク条件
@cindex イベントによる停止
@cindex グローバルブレーク条件
@dfn{グローバルブレーク条件}(global break condition)は、
指定した条件が満たされると、その場所に関わらず、実行を停止させます。
Edebugは各停止位置においてグローバルブレーク条件を評価します。
これが@code{nil}以外の値であると、
ブレークポイントに達したかのように、
実行モードに依存して実行を停止するか休止します。
条件の評価中にエラーが発生しても実行は停止しません。
@findex edebug-set-global-break-condition
条件式は@code{edebug-global-break-condition}に保存されます。
コマンド@kbd{X}で新たな条件式を指定できます
(@code{edebug-set-global-break-condition})。
グローバルブレーク条件は、読者のコードのどこでイベントが発生するかを
調べるもっとも簡単な方法ですが、コードの実行速度をかなり遅くします。
ですから、使用しない場合には条件を@code{nil}に再設定すべきです。
@node Source Breakpoints
@subsubsection ソース上のブレークポイント
@findex edebug
@cindex ソース上のブレークポイント
定義内のすべてのブレークポイントは、定義を処置し直すたびに失われます。
ブレークポイントを失いたくない場合には、
@dfn{ソース上のブレークポイント}(source breakpoint)を指定できます。
これはソースコード上で関数@code{edebug}を呼び出すだけです。
もちろん、条件付けして呼び出せます。
たとえば、関数@code{fac}において、引数がゼロの場合に停止するには、
以下に示すように最初の行を挿入します。
@example
(defun fac (n)
(if (= n 0) (Edebug))
(if (< 0 n)
(* n (fac (1- n)))
1))
@end example
関数@code{fac}を処置してこの関数を呼び出すと、
@code{edebug}の呼び出しはブレークポイントのように動作します。
実行モードに応じて、Edebugはその箇所で停止するか休止します。
@code{edebug}を呼び出したコードが処置済みでなければ、
この関数は@code{debug}を呼び出します。
@c This may not be a good idea anymore.
@node Trapping Errors
@subsection エラーの捕捉
Emacsは、通常、エラーが通知されても@code{condition-case}で処理されなかった
場合、エラーメッセージを表示します。
Edebugが活性であり処置済みのコードを実行していると、
Edebugは処理されなかったエラーすべてに反応します。
この動作を@code{edebug-on-error}と@code{edebug-on-quit}で
カスタマイズできます。
@xref{Edebug Options}。
Edebugがエラーに反応すると、
エラーを起こすまえ出会った最後の停止位置を表示します。
この位置は、実際にエラーを起こした処置してない関数の呼び出し位置である
場合もあります。
未束縛な変数のエラーでは、最後の停止位置は、
当該変数の参照位置からかなり離れている場合があります。
そのような場合には、完全なバックトレースを表示したいでしょう
(@pxref{Edebug Misc})。
@c Edebug should be changed for the following: -- dan
Edebugが活性なときに@code{debug-on-error}や@code{debug-on-quit}を変更しても、
Edebugが不活性になったときにそれらの変更を取り消してしまいます。
さらに、Edebugの再帰編集中は、これらの変数はEdebugの外側での値に
束縛されます。
@node Edebug Views
@subsection edebugのビュー
これらのEdebugのコマンドは、Edebugに入るまえのバッファやウィンドウの
状態を調べるものです。
外部ウィンドウ構成は、Edebugの外側でのウィンドウの集まりや内容に
関するものです。
@table @kbd
@item v
外部ウィンドウ構成を一時的に見る
(@code{edebug-view-outside})。
@item p
Edebugの外側でのカレントバッファと外側でのポイント位置を
一時的に表示し(@code{edebug-bounce-point})、
1秒間休止した後、Edebugに復帰する。
前置引数@var{n}は、かわりに休止秒数@var{n}を指定する。
@item w
ソースコードバッファで現在の停止位置にポイント位置を戻す
(@code{edebug-where})。
同じバッファを表示している別のウィンドウでこのコマンドを使うと、
それ以後、そのウィンドウに現在の定義が表示されるようになる。
@item W
@c Its function is not simply to forget the saved configuration -- dan
Edebugが外部ウィンドウ構成を保存/復元するかどうかを切り替える
(@code{edebug-toggle-save-windows})。
前置引数を指定すると、@code{W}は選択したウィンドウだけの保存/復元をトグルする。
ソースコードバッファを表示していないウィンドウを指定するには、
グローバルキーマップの@kbd{C-x X W}を使う必要がある。
@end table
@kbd{v}で外部ウィンドウ構成を見ることができます。
あるいは、(Edebugの外側での)カレントバッファが表示されていなくても
@kbd{p}でカレントバッファのポイント位置を見ることができます。
ポイント位置を移動したら、停止位置に戻りたいと思うかもしれません。
@kbd{w}でソースコードバッファから停止位置へ戻れます。
You can jump
back to the stop point in the source code buffer from any buffer using
@kbd{C-x X w}.
外部ウィンドウ構成を保存@emph{しない}ように@kbd{W}を使うたびに、
Edebugは保存しておいた外部ウィンドウ構成を破棄します。
そのため、保存@emph{する}ように戻しても、
(プログラムを続行することで)Edebugを抜けると、
現在のウィンドウ構成は変更されません。
しかし、@file{*edebug*}と@file{*edebug-trace*}の自動再表示は、
十分なウィンドウが開いてないと、
読者が見たいバッファと衝突するかもしれません。
@node Edebug Eval
@subsection 評価
Edebugの内側では、Edebugが動作していないがごとく式を評価できます。
Edebugは、式の評価と表示に対して見えないようにします。
Edebugが明示的に保存/復元する場合を除いて、
副作用を持つ式の評価も期待どおり動作します。
この処理に関して詳しくは@xref{The Outside Context}。
@table @kbd
@item e @var{exp} @key{RET}
Edebugの外側の文脈で式@var{exp}を評価する
(@code{edebug-eval-expression})。
つまり、Edebugは評価への干渉を最小限にとどめようとする。
@item M-: @var{exp} @key{RET}
Edebug自身の文脈で式@var{exp}を評価する
(@code{eval-expression})。
@item C-x C-e
Edebugの外側の文脈でポイント位置のまえの式を評価する
(@code{edebug-eval-last-sexp})。
@end table
@cindex レキシカル束縛(Edebug)
Edebugは@file{cl.el}(版2.03以降)内の構文
@code{lexical-let}、@code{macrolet}、@code{symbol-macrolet}で
作成されるレキシカル(テキスト上の)束縛を参照する式の評価を扱えます。
@c FIXME? What about lexical-binding = t?
@node Eval List
@subsection 評価リストバッファ
@file{*edebug*}と呼ばれる@dfn{評価リストバッファ}を使って、
式を対話的に評価できます。
さらに、Edebugが表示を更新するたびに自動的に評価される
式の@dfn{評価リスト}を設定することもできます。
@table @kbd
@item E
評価リストバッファ@file{*edebug*}へ切り替える
(@code{edebug-visit-eval-list})。
@end table
バッファ@file{*edebug*}では、以下の特別なコマンドに加えて
lisp対話モード
(@pxref{Lisp Interaction,, lisp対話バッファ, emacs, GNU Emacs マニュアル})
のコマンドも使えます。
@table @kbd
@item C-j
外側の文脈でポイント位置のまえの式を評価し、
その値をバッファに挿入する
(@code{edebug-eval-print-last-sexp})。
@item C-x C-e
Edebugの外側の文脈でポイント位置のまえの式を評価する
(@code{edebug-eval-last-sexp})。
@item C-c C-u
バッファの内容から新たな評価リストを構築する
(@code{edebug-update-eval-list})。
@item C-c C-d
ポイント位置にある評価リストグループを削除する
(@code{edebug-delete-eval-item})。
@item C-c C-w
ソースコードバッファに切り替え現在の停止位置に戻る
(@code{edebug-where})。
@end table
@file{*scratch*}で行うのと同様に、
評価リストウィンドウでは@kbd{C-j}や@kbd{C-x C-e}で式を評価できますが、
それらはEdebugの外側の文脈で評価されます。
実行を継続すると、対話的に入力した式(やその結果)は破棄されますが、
実行を停止するたびに評価される式から成る@dfn{評価リスト}(evaluation list)
を設定できます。
@cindex 評価リストグループ
これを行うには、評価リストバッファにて、
1つ以上の@dfn{評価リストグループ}(evaluation list group)を書きます。
評価リストグループは、1つ以上のLisp式から成ります。
グループはコメント行で区切ります。
コマンド@kbd{C-c C-u}(@code{edebug-update-eval-list})は、
バッファを走査して各グループの最初の式を使って
評価リストを再構築します。
(各グループの2番目の式は計算結果を表示した値とみなす。)
Edebugに入るたびに、各式に続けてその現在値をバッファに挿入することで
評価リストを再表示します。
このとき、各式がそれぞれグループになるようにコメント行も挿入します。
したがって、バッファのテキストを変更せずに再度@kbd{C-c C-u}と打つと、
評価リストは実質的には変更されません。
評価リストの評価中にエラーが発生すると、
エラーメッセージを評価結果とみなして文字列で表示します。
したがって、現在の文脈では不正な変数を式に使っても
読者のデバッグを遮ることはありません。
評価リストウィンドウに数個の式を追加したときのようすを以下に示します。
@smallexample
(current-buffer)
#<buffer *scratch*>
;---------------------------------------------------------------
(selected-window)
#<window 16 on *scratch*>
;---------------------------------------------------------------
(point)
196
;---------------------------------------------------------------
bad-var
"Symbol's value as variable is void: bad-var"
;---------------------------------------------------------------
(recursion-depth)
0
;---------------------------------------------------------------
this-command
eval-last-sexp
;---------------------------------------------------------------
@end smallexample
グループを削除するには、そこへポイントを移動して@kbd{C-c C-d}と打ちます。
あるいは、グループのテキストを単に削除してから@kbd{C-c C-u}で
評価リストを更新します。
評価リストに新たに式を追加するには、
適切な位置に式を挿入し、新たなコメント行を挿入します。
(コメント行にマイナス記号を挿入する必要はない。
コメントの内容は関係ない。)
そして、@kbd{C-c C-u}と打ちます
@file{*edebug*}を選択したあとは、
@kbd{C-c C-w}でソースコードバッファへ戻れます。
読者が実行を継続するとバッファ@file{*edebug*}は削除され、
つぎに必要なときに再度作成されます。
@node Printing in Edebug
@subsection Edebugでの出力
@cindex 出力(Edebug)
@cindex 循環構造の出力
@pindex cust-print
読者のプログラムの式が循環リスト構造を含む値を作り出す場合、
Edebugがそれを出力しようとするとエラーになることがあります。
循環構造を扱う1つの方法は、出力を切り詰めるために
@code{print-length}や@code{print-level}を設定することです。
Edebugが読者のためにこれを行います。
Edebugは@code{print-length}と@code{print-level}の値を
それぞれ@code{edebug-print-length}と@code{edebug-print-level}に
設定します(これらが@code{nil}でなければその限りでない)。
@xref{Output Variables}。
@defopt edebug-print-length
@code{nil}以外であると、Edebugが結果を出力するときには、
これを@code{print-length}に束縛する。
デフォルト値は@code{50}。
@end defopt
@defopt edebug-print-level
@code{nil}以外であると、Edebugが結果を出力するときには、
これを@code{print-level}に束縛する。
デフォルト値は@code{50}。
@end defopt
You can also print circular structures and structures that share
elements more informatively by binding @code{print-circle}
to a non-@code{nil} value.
循環構造を作るコードの例を示します。
@example
(setq a '(x y))
(setcar a a)
@end example
@noindent
特別な出力ではこれを@samp{Result: #1=(#1# y)}と出力します。
@samp{#1=}の記法は、これに続く構造に@samp{1}というラベルを付けます。
また、@samp{#1#}の記法はすでにラベル付けした構造を参照します。
この記法は、リストやベクトルの任意の共有された要素に使われます。
@defopt edebug-print-circle
@code{nil}以外であると、Edebugが結果を出力するときには、
これを@code{print-circle}に束縛する。
デフォルト値は@code{t}。
@end defopt
他のプログラムでもこの特別な出力を使えます。
詳しくは、@file{cust-print.el}を参照してください。
@node Trace Buffer
@subsection トレースバッファ
@cindex トレースバッファ
Edebugは、実行トレースを@file{*edebug-trace*}というバッファに保存することで
それらを記録できます。
これは、関数名とそれらの引数、戻り値から成る
関数呼び出しとその戻りの記録です。
トレース記録を有効にするには、
@code{edebug-trace}に@code{nil}以外の値を設定します。
トレースバッファを作成することとトレース実行モードとは
同じではありません(@pxref{Edebug Execution Modes})。
トレース記録を有効にしていると、
各関数へ入るときと出るときに、トレースバッファに行が追加されます。
関数へ入るときの記録は、@samp{::::@{}に関数名と引数値が続きます。
関数から出るときの記録は、@samp{::::@}}に関数名とその結果が続きます。
入るときの@samp{:}の個数は、再帰の深さを表します。
関数呼び出しの対応する開始や対応する終了を探すために
トレースバッファでは中括弧を使えます。
@findex edebug-print-trace-before
@findex edebug-print-trace-after
関数@code{edebug-print-trace-before}と@code{edebug-print-trace-after}を
再定義すれば、関数へ入ったときと出るときのトレース記録をカスタマイズできます。
@defmac edebug-tracing string body@dots{}
このマクロはフォーム@var{body}の周りにトレース情報を追加する。
引数@var{string}は、トレースバッファの、
@samp{@{}または@samp{@}}の後に入れるテキストを指定する。
すべての引数は評価され、
@code{edebug-tracing}は@var{body}の最後のフォームの値を返す。
@end defmac
@defun edebug-trace format-string &rest format-args
この関数はトレースバッファにテキストを挿入する。
テキストは@code{(apply 'format @var{format-string} @var{format-args})}で
計算する。
区切りとして改行も挿入する。
@end defun
@code{edebug-tracing}と@code{edebug-trace}は、
Edebugが活性でない場合であっても呼ばれるとトレースバッファに行を挿入します。
トレースバッファにテキストを挿入するとき、
挿入した最後の行が見えるようにウィンドウをスクロールします。
@node Coverage Testing
@subsection カバレッジテスト
@cindex カバレッジテスト
@cindex 頻度数計測
@cindex 効率解析
Edebugでは、初歩的なカバレッジテストや実行頻度を表示できます。
カバレッジテストでは、各式の結果を以前の結果と比較します。
現在のEmacsセッションでカバレッジテストを始めて以降、
プログラムの各フォームが異なる2つの値を返せば、
当該フォームを『カバーした』とみなします。
したがって、読者のプログラムについてカバレッジテストを行うには、
さまざまな条件でそれを実行して正しく動作しているか注意します。
読者が各フォームが異なる2つの値を返すように試行し終れば、
Edebugはそのように通知します。
カバレッジテストは実行速度を遅くするので、
@code{edebug-test-coverage}が@code{nil}以外の場合にのみテストします。
すべての処置済み関数の実行に関する頻度数計測は、
非停止実行モードであってもカバレッジテストのオン/オフに関わらず行います。
@kindex C-x X =
@findex edebug-temp-display-freq-count
Use @kbd{C-x X =} (@code{edebug-display-freq-count}) to display both
the coverage information and the frequency counts for a definition.
Just @kbd{=} (@code{edebug-temp-display-freq-count}) displays the same
information temporarily, only until you type another key.
ある定義に関するカバレッジテストと頻度数計測を表示するには
@kbd{M-x edebug-display-freq-count}を使います。
@deffn Command edebug-display-freq-count
このコマンドは、現在の定義の各行について頻度数データを表示する。
頻度数は、コードの各行のあとにコメント行として表示され、
コマンド@code{undo}でそれらのコメント行の挿入をアンドゥできる。
頻度数は、式のまえの@samp{(}や式のうしろの@samp{)}の直下、
あるいは、変数の最後の文字に表示される。
表示を簡素にするために、頻度数が同じ行のまえのほうの式の頻度数と同じであると
表示しない。
式の頻度数に続く文字@samp{=}は、
その式を評価するたびに同じ値を返したことを意味する。
いいかえれば、カバレッジテストとしては、
その式はまだ『カバーして』いないことになる。
ある定義に関する頻度数計測とカバレッジデータをクリアするには、
@code{eval-defun}で単に再処置すればよい。
@end deffn
たとえば、@code{edebug-test-coverage}を@code{t}とし、
ソース上のブレークポイントを設定して@code{(fac 5)}を評価すると、
ブレークポイントに達したときの頻度数データはつぎのようになります。
@example
(defun fac (n)
(if (= n 0) (Edebug))
;#6 1 = =5
(if (< 0 n)
;#5 =
(* n (fac (1- n)))
;# 5 0
1))
;# 0
@end example
コメント行は、@code{fac}が6回呼ばれたことを表します。
最初の@code{if}文は、5回とも同じ結果を返したのです。
2番目の@code{if}についても同じです。
@code{fac}の再帰呼び出しは1度も戻っていません。
@node The Outside Context
@subsection 外側の文脈
Edebugは、読者がデバッグ中のプログラムに対しては透過であるように努めますが、
完全にうまくいくとは限りません。
また、@kbd{e}で読者が式を評価するときや評価リストバッファでも、
外側の文脈を一時的に復元して透過であるように努めます。
本節では、Edebugが復元する文脈について正確に説明し、
Edebugが透過にならない場合についても説明します。
@menu
* Checking Whether to Stop:: When Edebug decides what to do.
* Edebug Display Update:: When Edebug updates the display.
* Edebug Recursive Edit:: When Edebug stops execution.
@end menu
@node Checking Whether to Stop
@subsubsection 停止すべきかどうかの検査
Edebugに入ると、トレース情報を作るのかプログラムを停止するのかを
決定するまえであってもある種のデータを保存/復元する必要が
つねにあります。
@itemize @bullet
@item
Edebugがスタックに与える影響を軽減するために、
@code{max-lisp-eval-depth}と@code{max-specpdl-size}を一度増加する。
しかし、こうしてもEdebugを使うときにスタックを使い切ってしまうことがある。
@item
キーボードマクロの実行状態を保存し復元する。
Edebugが活性であると、@code{executing-kbd-macro}は