summaryrefslogtreecommitdiff
path: root/devel/debug/1/src/trace.dok
blob: 7de46f882041ea728df73093b77e730f8d6b107e (plain)
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
#type ("trium8")##limit (13.0)# 
#start(3.0,1.5)# 
#pagelength(18.5)# 
#block# 
#type("trium36.b")# 
#free(3.5)# 
#center#EUMEL 
#center#DEBUG 
#type("trium18.b")# 
#free(1.4)# 
#center#Version 1 
#center#87-04-24 
 
#center#G. Szalay 
#page(1)# 
#type ("trium8")##limit (13.0)# 
#head# 
#center#- % - 
 
 
#end# 
#type ("trium14.b")# 
#center#E U M E L - D E B U G 
 
#type ("trium12.b")# 
#center#Task-local Debugging Tools for EUMEL: 
#center##type("trium12.bc")#info, disasm, #type("trium12.b")#and #type("trium12.bc")#trace 
 
 
#b("1.  Features")# 
 
#it("info:")#    display and modification of a dataspace on the users terminal in the conventional dump
         format; search for a bytestring; 
 
#it("disasm:")#  disassembly of EUMEL-0-code out of the standard dataspace using symbolic opcodes
         and procedure heads; 
 
#it("trace:")#   tracing of user programs, protocolling of executed instructions and their actual operands,
         trap at a given code address, single-step-mode, multiple-step-mode (interruptable at
         any time) 
 
The procedures have no effect outside the task. Especially no other task will be halted by using the
single-step mode. 
 
 
#b("2.  Installation")# 
 
The debugging tools need a suitable system kernel ("Urlader"). They can be used with kernels for
processors Z80, 8086 and 80286 with versions 190 \#14, 181 \#347 \#1347, 180 \#347 \#1347 and higher,
and with 68000-kernel version \#3600 and higher. 
 
The archive diskette "trace" contains all necessary files. The commands 
#inb# 
   archive ("trace"); 
   fetchall (archive); 
   run ("gen.trace") 
#ine# 
insert all source files and generate a dataspace "procheads" containing procedure heads of all
inserted procedures (including the standard ones). Then the current task becomes a local mana­
ger. Now a son task may be created, in which the debugging tools are available. 
 
The first time when (in a son task) #it("disasm")# or #it("trace")# protocols a CALL-instruction the dataspace
'procheads' will be fetched from the father task for subsequent usage. If for any reason (e.g. after
inserting new packets, see below) the user will change or re-install 'procheads'  he has to inform
the debugging procedures by issuing the command 
#inb#   set procheads ("procheads") #ine# 
 
Access to the dataspace "procheads" may be suppressed by 
#inb#   set procheads ("") #ine# 
 
Procedures inserted at a later time by the user should be added to the dataspace "procheads" (in the
current task!) by typing the commands 
#inb# 
   bulletin m ("<packetname>"); 
   run ("gen.procheads") 
#ine# 
 
 
 
#b("3.  Description of the debugging procedures")# 
 
#b1("3.1  PROC info ")# 
 
The standard output is a hexadecimal dump of a dataspace in the following format: 
 
#outb# 
---------------------------- dsid=xx -------------------- 
xxxxx: -xx-xx xx xx xx xx xx xx   xx xx xx xx xx xx xx xx  yyyyyyy......... 
xxxxx:  xx xx xx ...                                       ..... 
xxxxx:  xx xx ...                                          ... 
xxxxx:  xx xx xx xx xx xx xx xx   xx xx xx xx xx xx xx xx  .........yyyyyyy 
#re("INFO: more, address, dsid, lines, find, or quit")# 
#oute# 
 
 
The first line displays the dataspace identifier (4 <= dsid <= ff, dsid=4 identifies the standard
dataspace). 
The dump lines begin with the hexadecimal word (!) address of the first word on this line. The order
of bytes is the same as on EUMEL-'Hintergrund': low byte, high byte. Following the hexadecimal
display of 16 bytes they will be shown as ascii-characters, too. Non-ascii characters will be
displayed as '.'. 
 
The last line shows (as with #it("disasm")# and #it("trace")#, too) possible commands which will be recognized by
their first letter. If a parameter is needed, it has to be typed as a hexadecimal number followed by a
<CR>. The <RUBOUT> key may be used to delete the last input character(s). 
Possible commands and their effect: 
 
m (more):     continues displaying at the next higher address 
 
a (address):  specifies a new address 
 
d (dsid):     specifies a new dataspace identifier 
 
l (lines):    specifies a new line count (=window height); this value may be larger than the
              number of lines of the terminal screen. 
 
f (find):     (tries to) find a hexadecimal or character bytestring. The prompting message 
#outb# 
                   find: hex, char, or last param? (h/H/c/C/<CR>) 
#oute# 
              may be answered in several ways. Examples: 
 
              #inb#h41<CR>#ine#    looks for a byte 41h, beginning at the actual position, marked by -xx-. 
 
              #inb#Hcafe<CR>#ine#  searches the bytestring 0cafeh, beginning at the actual word address.
                         Only strings at word addresses will be concerned for a comparison. 
 
              #inb#challo<CR>#ine# searches the character string "hallo", beginning at the actual position. 
 
              #inb#Ca<CR>#ine#     searches the letter "a", which has to be located at a word address.
                         #inb#H41<CR> #ine#has the same effect. 
 
              #inb#<CR>#ine#       searches the last bytestring explicitly specified in a search command,
                         beginning #bo("behind")# the marked position. The last parameter will be shown
                         during the search. 
 
              The search can be interrupted at any time by pressing a key. It may then be conti­
              nued by a new 'find' command and <CR>. 
 
q (quit):  leaves #it("info")# . 
 
Instead of a command the dataspace can be modified within the displayed area by the key-
sequence 
   <UP>                       positions the cursor to the first displayed byte; 
   <Cursorkey>...             moves the cursor within the hexadecimal display; 
   <2 hexadecimal digits>...  overwrite the byte under the cursor; 
   <CR>                       leaves the window. 
 
Note: in the standard dataspace changes within the address range 20000...2ffff are only allowed in
      conjunction with a 68000-kernel (see also 3.3, note a.). 
 
 
 
#b1("3.2  PROC disasm ")# 
 
EUMEL-0-code in the address range 20000...3ffff of the standard dataspace will be disassem­
bled. The code will be listed one instruction per line, using symbolic opcodes and (in case of a CALL
instruction) procedure heads as found in the dataspace "procheads". 
 
The following example shows the disassembled code of the standard procedure 
 
REAL OP MOD (REAL CONST left, right): 
  REAL VAR result := left - floor (left/right) * right; 
  IF result < 0.0 
     THEN result + abs (right) 
     ELSE result 
  FI 
ENDOP MOD; 
 
#outb# 
23edd:  LN      2000 
23ede:  PENTER  15fe 
23edf:  FDIV    09c4 0d80 2880 
23ee2:  FLOOR   637f 2880 2880 
23ee5:  FMUL    28c0 0d80 2880 
23ee8:  FSUB    09bc 2880 1880 
23eeb:  FLSEQ   6049 1880 
23eed:  BT      f700 
23eee:  PP      0dec 
23eef:  PP      28ec 
23ef0:  CALL    5d79   abs (REAL C) --> REAL 
23ef1:  FADD    18b8 2880 2880 
23ef4:  REF     28dc 2080 
23ef6:  B       f970 
23ef7:  REF     18dc 2080 
23ef9:  FMOV    21b4 1180 
23efb:  RTN     007f 
#re("DISASM: step, more, address, lines, info, or quit")# 
#oute# 
 
Possible commands: 
 
s (step):     shows the next instruction on the terminal. The command line will be rewritten. 
 
m (more):     shows the next instructions. The output will stop after 'lines' (standard=12) lines. It
              can be interrupted at any time by pressing any key. The output list terminates, when
              an invalid opcode has been detected or when the instruction count exceeds 3ffff. 
 
a (address):  specifies a new code address. Disassembly continues at this address. 
 
l (lines):    specifies a new line count; this value may be larger than the number of lines of the
              terminal screen. 
 
i (info):     calls #it("info")#. The first line of dump contains the first word of the next instruction not yet
              disassembled. This word will be marked. (After leaving #it("info")# disassembly would
              continue with this instruction.) 
 
q (quit):     leaves #it("disasm")#. 
 
 
#b1("3.3  PROC trace ")# 
 
#it("trace")# allowes controlled execution of subsequent EUMEL-0-code. The effect of the trace-mode
can be demonstrated by showing the protocol produced by 
 
    #inb#trace; putline ("hallo")<CR> 
 
    #ine##outb##re("TRACE: step, more, trap, regs, lines, info, disasm, or quit")# 
#oute##inb# 
    p 
 
#ine##outb# 
        34afb: PP       006d   >00009000 
        34afc: CALL     f37a   putline (TEXT C) 
          28d63: PENTER   38fe 
          28d64: TEST     c828   >0 
          28d65: BF       6b70 
          28d66: OUT      3c7f 0980   >"hallo" hallo 
          28d68: OUT      3c7f 6c01   >""13""10"" 
 
          28d6a: B        6e70 
          28d6e: RTN      007f   --> STOPEN NOERR ARITS 
        34afd: RTN      007f   --> STOPEN NOERR ARITS 
      20944: RTN      007f   --> STPDIS NOERR ARITU 
  trace ended by returning to nontraceable caller 
#oute# 
 
Comments on this output: 
-  the indentation of the protocol lines shows the call depth. 
-  in order to get 1 line per instruction as often as possible, some abbreviations are used in the
   procedure heads: 'C' for 'CONST', 'V' for 'VAR', 'DS' for 'DATASPACE'. 
-  the first occurrence of the string 'hallo' is part of the protocol. The second one is a result of the
   execution of the (first) OUT-instruction. The blank line is produced by the second OUT-instruc­
   tion! 
-  the flags given with a RTN-instruction reflect the flag settings #bo("after")# execution of the RTN: 
      STOPEN = stop enabled         STPDIS = stop disabled 
      NOERR  = no error             ERROR  = error occurred 
      ARITS  = signed arith mode    ARITU  = unsigned arith mode 
 
 
Possible commands: 
 
s (step):    executes and protocols one instruction (=single-step-mode). For reasons of the
             implementation, consecutive PP-instructions will be executed as one single step. The
             same holds for instructions followed by a conditional branch (e.g. EQU+BT). 
 
             The protocol contains also actual operand values. Example: 
#inb# 
 
                 trace;INT VAR a:= 2 + 11 
#ine##outb# 
 
                 34afb: ADD      001d 0101 5400   >2 >11(000b) 13(000d)> 
#oute# 
 
             '>' in front of a value indicates input-operand; 
             '>' behind a value indicates output-operand. (For the instructions MOV, FMOV and
             TMOV only 1 (output-)operand will be shown.) 
             INT-objects are shown decimal and (in parentheses) hexadecimal (4 digits). The
             numbers 0 to 9 will be shown only decimal. 
             REAL-objects will be shown in the internal representation (e.g. 11.5 as
             0115000000000082) 
             TEXT-objects will be shown as text denoters. Non-ascii characters will be converted
             (see example). For long texts only the first 14 characters will be shown, followed by
             the (correct) number of characters. 
             All other objects (TASKs, DATASPACEs and effective virtual addresses) will be shown
             hexadecimal (4 or 8 digits). 
 
m (more):    executes and protocols up to 'line count' (standard=12) instructions. Execution can be
             interrupted at any time by any key, and resumed by commands 's' or 'm'. 
 
t (trap):    sets a trap on a code address. As soon as the instruction count reaches the specified
             value, the message 
#outb# 
                trap at address ..... 
#oute# 
             will be displayed and the execution stopped. (The instruction at the trap address is the
             next one to be executed!) At the same time the trap is deleted. 
 
r (regs):    shows the relevant EUMEL-0-registers 'icount' (address of the instruction to be
             executed next), 'pbase' (=packet base, base address for packet data), 'lbase' (=local
             base, base address for local data on stack) as well as flag registers
             (STOPEN/STPDIS, NOERR/ERROR, ARITS/ARITU). 
 
l (lines):   specifies a new line count; this value may be larger than the number of lines of the
             terminal screen. 
 
i (info):    calls #it("info")#, s. 3.1. The instruction word pointed to by the instruction count is the actual
             position, marked on the first line. 
 
d (disasm):  calls #it("disasm")#, s. 3.2. Disassembly begins at the next instruction not yet executed. 
 
q (quit):    leaves the trace-mode. However, a trap (see above) may still be in effect! Tracing
             will be #bo("implicitly")# finished as soon as a RTN-instruction returns to a procedure
             running in the 'unsigned arithmetic'-mode. (Regularly this is the ELAN-Compiler.) 
 
 
#bo("Important Notes ")# 
 
Erroneous use of #it("info")# and #it("trace")# may destruct your task. Therefore read carefully and observe follow­
ing notes: 
 
a. In order to gain control at proper points of the code area, #it("trace")# temporarily modifies the user code
   by inserting instructions (CALLs to itself) into it. On EUMEL-hardware based on Z80, 8086, or
   80286, #it("trace")# does not allow modification of address range 20000...2ffff for reasons of storage
   management strategy. Therefore calls to procedures occupying this address range will be marked
   in the protocol by "(*n.t.*)" (for 'nontraceable') and executed normally, i.e. not protocolled. 
 
   WARNING:   execution of a nontraceable procedure cannot be interrupted by <SV> and 'halt'. So
              be careful! 
 
b. Traps may only be set on the first word of an instruction. In a sequence of consecutive PP-
   instructions only the first one may be trapped. In the same manner, a conditional branch (BT / BF)
   following another instruction (e.g. EQU) may not be trapped. 
 
c. On inserting #it("trace")# it may get a module number > 2047. In that case the CALL to #it("trace")# occupies
   2 words. The user will be informed of this fact at the time just after inserting #it("trace")#: 
      #outb# 
      WARNING: call to trace needs 2 words! 
      #oute# 
   In this situation special care has to be taken to set a trap, e.g.: 
 
#outb# 
            LSEQ    xxxx xxxx 
            BT      xxxx        (*branch on true to address a*) 
            ... 
            ... 
      a-1:  B       xxxx 
        a:  ... 
#oute# 
 
   In this example the branch instruction at address 'a-1' may not be trapped because the following
   instruction (at 'a') would be destroyed by a 2-word-CALL to #it("trace")#. A jump to 'a' would have an
   undefined effect. So be careful! First inspect the code environment by using #it("disasm")# and then set
   a trap at a suitable address! 
 
d. In the current version of #it("trace")# a trap will be implicitly deleted as soon as it has become active. If
   the user wants (e.g. in a loop) to trap a given address again and again, he has to choose a
   second suitable address, too, and alternately set a trap at these addresses. (A trap may be 
   #bo("explicitly")# deleted by specifying 0 as trap address.) 
 
e. One may be tempted to trace the ELAN-compiler by writing 
 #inb# 
      trace; do ("..........") 
 #ine# 
   which seems to work indeed for dozens of lines but at some point it begins to deliver wrong
   results even with such trivial instructions as an integer ADD. This trouble arises from a storage
   assignment policy during compilation of the ELAN compiler: temporary storage (e.g. for calculating
   the value of an expression) will be assigned above the stack top of a procedure if it does not call
   any other one. An #bo("implicit")# CALL to #it("trace")# causes a further stack frame to be established thus
   possibly overwriting some temporary values of a compiler procedure. (Of course, the compiler
   cannot know anything about CALLs inserted by #it("trace")# into the code area!) 
 
f. Errors (e.g. overflow) in user programs will be detected by #it("trace")# at the point of their occurrence
   and reported in the protocol. However, #it("trace")# has no influence on the error handling, i.e. it does
   not turn off the error flag by itself, nor causes it an error stop on the users level. (#it("trace")# may be
   seen as an extension of the virtual EUMEL-0-machine offering some additional features but still
   fully controlled by the users program.) 
 
g. Each time when the user has control within #it("trace")#, the users code area contains no other patches
   than a possible CALL at the trap address if specified. 
 
h. The procedures #it("trace, disasm, info")#, and some others used by them are nontraceable. The body of
   these procedures will not be protocolled. CALLs to them will be marked as nontraceable. Explicit
   CALLs to #it("trace")# (i.e. in addition to the first call to switch on the trace mode) will be ignored. 
 
i. In trace-mode the EUMEL-0-instruction KE has the same effect as an explicit call to #it("info")#. 
 
j. Protocolling the execution produces output in addition to output programmed by the user. This
   may lead to unexpected results when the user program specifies cursor positioning. The cursor
   will always be moved to the position (10,13) instead of the position specified by the user. This is
   due to the fact that cursor positioning takes place in two steps. One OUT instruction sends the
   escape character for 'cursor positioning' (=""6""), and a second one sends two bytes containing
   the coordinate values. The protocol line containing the first OUT will be followed by a lf-cr-
   sequence (""10""13"") before the next protocol line can be written.