cfad47cfa3/tads2/dbg.h

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
/*
2
$Header: d:/cvsroot/tads/TADS2/DBG.H,v 1.3 1999/07/11 00:46:29 MJRoberts Exp $
3
*/
4
5
/* 
6
 *   Copyright (c) 1992, 2002 Michael J. Roberts.  All Rights Reserved.
7
 *   
8
 *   Please see the accompanying license file, LICENSE.TXT, for information
9
 *   on using and copying this software.  
10
 */
11
/*
12
Name
13
  dbg.h - debug interface
14
Function
15
  Debugger interface definitions
16
Notes
17
  The Debugger implementation is split into two parts:  the "engine",
18
  which implements the parts of the debugger that are independent of
19
  user interface; and the UI.  The UI is in a separate module so that
20
  several user interfaces can be provided, and a particular one chosen
21
  at link time.  The UI section should contain nothing that is generic,
22
  but only the parts specific to that user interface.
23
Modified
24
  04/11/99 CNebel        - Move extern C.
25
  03/28/92 MJRoberts     - creation
26
*/
27
28
#ifndef DBG_INCLUDED
29
#define DBG_INCLUDED
30
31
#ifndef OBJ_INCLUDED
32
#include "obj.h"
33
#endif
34
#ifndef PRP_INCLUDED
35
#include "prp.h"
36
#endif
37
38
#ifdef __cplusplus
39
extern "C" {
40
#endif
41
42
/* forward declarations */
43
struct bifcxdef;
44
struct toksdef;
45
struct toktdef;
46
struct tokcxdef;
47
48
/* stack frame record */
49
struct dbgfdef
50
{
51
    struct runsdef *dbgfbp;                        /* base pointer of frame */
52
    objnum  dbgfself;             /* 'self' object (MCMONINV for functions) */
53
    objnum  dbgftarg;                               /* actual target object */
54
    prpnum  dbgfprop;                          /* property being evalutated */
55
    int     dbgfargc;                                /* number of arguments */
56
    int     dbgfbif;      /* set to built-in function number if in built-in */
57
    uint    dbgffr;         /* offset in object of local frame symbol table */
58
    uint    dbgflin;                      /* OPCLINE operand of latest line */
59
};
60
typedef struct dbgfdef dbgfdef;
61
62
/* max number of frames to store in debug frame memory */
63
#define DBGMAXFRAME  100
64
65
/* maximum number of breakpoints set concurrently */
66
#define DBGBPMAX 50
67
68
/* breakpoint structure */
69
struct dbgbpdef
70
{
71
    objnum dbgbpself;               /* the "self" object for the breakpoint */
72
    objnum dbgbptarg;            /* actual target object for the breakpoint */
73
    uint   dbgbpofs;                  /* offset in object of the breakpoint */
74
    uint   dbgbpflg;                                    /* breakpoint flags */
75
#   define DBGBPFUSED  0x01                      /* breakpoint has been set */
76
#   define DBGBPFNAME  0x02              /* name of address has been stored */
77
#   define DBGBPFCOND  0x04          /* breakpoint has a condition attached */
78
#   define DBGBPFDISA  0x08                       /* breakpoint is disabled */
79
#   define DBGBPFCONDNAME 0x10     /* condition name string has been stored */
80
    uint   dbgbpnam;       /* offset of address name within dbgcxnam buffer */
81
    uint   dbgbpcondnam;        /* offset of condition string within buffer */
82
    objnum dbgbpcond;        /* object containing compiled condition for bp */
83
};
84
typedef struct dbgbpdef dbgbpdef;
85
86
/* maximum number of watch expressions set concurrently */
87
#define DBGWXMAX 30
88
89
/* watch expression structure */
90
struct dbgwxdef
91
{
92
    objnum  dbgwxobj;              /* object containing compiled expression */
93
    objnum  dbgwxself;                         /* 'self' for the expression */
94
    uint    dbgwxnam;   /* offset of expression text within dbgcxnam buffer */
95
    uint    dbgwxflg;               /* flags for this watch expression slot */
96
#   define DBGWXFUSED  0x01                         /* watch slot is in use */
97
#   define DBGWXFNAME  0x02                /* name of watch has been stored */
98
};
99
typedef struct dbgwxdef dbgwxdef;
100
101
/* amount of space for bp names (original address strings from user) */
102
#define DBGCXNAMSIZ 2048
103
104
/* debug context */
105
struct dbgcxdef
106
{
107
    struct tiocxdef *dbgcxtio;                          /* text i/o context */
108
    struct tokthdef *dbgcxtab;                              /* symbol table */
109
    struct mcmcxdef *dbgcxmem;              /* memory cache manager context */
110
    struct errcxdef *dbgcxerr;                    /* error handling context */
111
    struct    lindef *dbgcxlin;                    /* chain of line sources */
112
    int       dbgcxfcn;                          /* number of frames in use */
113
    int       dbgcxdep;          /* actual depth (if overflow frame buffer) */
114
    int       dbgcxfid;                        /* source file serial number */
115
    dbgfdef   dbgcxfrm[DBGMAXFRAME];                        /* stack frames */
116
    int       dbgcxflg;                          /* flags for debug session */
117
#   define    DBGCXFSS   0x01               /* single-stepping source lines */
118
#   define    DBGCXFSO   0x02       /* stepping over a function/method call */
119
#   define    DBGCXFOK   0x04                      /* debugger is linked in */
120
#   define    DBGCXFIND  0x08  /* in debugger - suppress stack trace on err */
121
#   define    DBGCXFGBP  0x10               /* global breakpoints in effect */
122
#   define    DBGCXFTRC  0x20                     /* call tracing activated */
123
#   define    DBGCXFLIN2 0x40      /* new-style line records (line numbers) */
124
    int       dbgcxsof;                    /* frame depth at step-over time */
125
    dbgbpdef  dbgcxbp[DBGBPMAX];                             /* breakpoints */
126
    dbgwxdef  dbgcxwx[DBGWXMAX];                       /* watch expressions */
127
    struct    prscxdef *dbgcxprs;                        /* parsing context */
128
    struct    runcxdef *dbgcxrun;                      /* execution context */
129
    uint      dbgcxnamf;               /* next free byte of dbgcxnam buffer */
130
    uint      dbgcxnams;                         /* size of dbgcxnam buffer */
131
    char     *dbgcxnam;                       /* space for bp address names */
132
    char     *dbgcxhstp;                             /* call history buffer */
133
    uint      dbgcxhstl;                           /* history buffer length */
134
    uint      dbgcxhstf;             /* offset of next free byte of history */
135
136
    /* 
137
     *   This member is for the use of the user interface code.  If the
138
     *   user interface implementation needs to store additional context,
139
     *   it can allocate a structure of its own (it should probably do
140
     *   this in dbguini()) and store a pointer to that structure here.
141
     *   Since the user interface entrypoints always have the debugger
142
     *   context passed as a parameter, the user interface code can
143
     *   recover its extra context information by following this pointer
144
     *   and casting it to its private structure type.  The TADS code
145
     *   won't do anything with this pointer except initialize it to null
146
     *   when initializing the debugger context.  
147
     */
148
    void     *dbgcxui;
149
};
150
typedef struct dbgcxdef dbgcxdef;
151
152
153
/* ======================================================================== */
154
/*
155
 *   Compiler interface.  These routines are called by the compiler to
156
 *   inform the debug record generator about important events as
157
 *   compilation proceeds. 
158
 */
159
160
161
/*
162
 *   Tell the current line source that we're compiling an executable
163
 *   line, and tell it the object number and offset of the code within the
164
 *   object. 
165
 */
166
void dbgclin(struct tokcxdef *tokctx, objnum objn, uint ofs);
167
168
/* size of information given to line source via lincmpinf method */
169
#define DBGLINFSIZ   4
170
171
172
173
/* ======================================================================== */
174
/*
175
 *   Run-time interface.  These routines are called by the run-time
176
 *   system to apprise the debugger of important events during execution.
177
 */
178
179
180
/*
181
 *   Determine if the debugger is present.  Returns true if so, false if
182
 *   not.  This should return false for any stand-alone version of the
183
 *   executable that isn't linked with the debugger.  If this returns
184
 *   true, dbgucmd() must not have a trivial implementation -- dbgucmd()
185
 *   must at least let the user quit out of the game.
186
 *   
187
 *   This can be switched at either link time or compile time.  If DBG_OFF
188
 *   is defined, we'll force this to return false; otherwise, we'll let
189
 *   the program define the appropriate implementation through the linker.
190
 */
191
#ifdef DBG_OFF
192
#define dbgpresent() (FALSE)
193
#else
194
int dbgpresent();
195
#endif
196
197
198
/* add a debug tracing record */
199
/* void dbgenter(dbgcxdef *ctx, runsdef *bp, objnum self, objnum target,
200
                 prpnum prop, int binum, int argc); */ 
201
202
/* tell debugger where the current line's local frame table is located */
203
/* void dbgframe(dbgcxdef *ctx, uint ofsfr, ofslin); */
204
205
/* 
206
 *   Single-step interrupt: the run-time has reached a new source line.
207
 *   ofs is the offset from the start of the object of the line record,
208
 *   and p is the current execution pointer.  *p can be changed upon
209
 *   return, in which case the run-time will continue from the new
210
 *   position; however, the new address must be within the same function
211
 *   or method as it was originally.
212
 */
213
/* void dbgssi(dbgcxdef *ctx, uint ofs, int instr,
214
               int err, uchar *noreg *p); */
215
216
/* pop debug trace level */
217
/* void dbgleave(dbgcxdef *ctx, int exittype); */
218
#define DBGEXRET   0                                /* return with no value */
219
#define DBGEXVAL   1                                 /* return with a value */
220
#define DBGEXPASS  2                       /* use 'pass' to exit a function */
221
222
/* dump the stack into text output */
223
/* void dbgdump(dbgcxdef *ctx); */
224
225
/* reset debug stack (throw away entire contents) */
226
/* void dbgrst(dbgcxdef *ctx); */
227
228
/* activate debugger if possible; returns TRUE if no debugger is present */
229
int dbgstart(dbgcxdef *ctx);
230
231
/* add a string to the history buffer */
232
void dbgaddhist(dbgcxdef *ctx, char *buf, int bufl);
233
234
/*
235
 *   Find a base pointer, given the object+offset of the frame.  If the
236
 *   frame is not active, this routine signals ERR_INACTFR; otherwise, the
237
 *   bp value for the frame is returned. 
238
 */
239
struct runsdef *dbgfrfind(dbgcxdef *ctx, objnum frobj, uint frofs);
240
241
242
/* ======================================================================== */
243
/*
244
 *   User Interface Support routines.  These routines are called by the
245
 *   user interface layer to get information from the debugger and perform
246
 *   debugging operations. 
247
 */
248
249
250
/* get a symbol name; returns length of name */
251
int dbgnam(dbgcxdef *ctx, char *outbuf, int typ, int val);
252
253
/*
254
 *   Get information about current line.  It is assumed that the caller
255
 *   knows the size of the line information .
256
 */
257
void dbglget(dbgcxdef *ctx, uchar *buf);
258
259
/*
260
 *   Get information about a line in an enclosing stack frame.  Level 0 is
261
 *   the current line, level 1 is the first enclosing frame, and so on.
262
 *   Returns 0 on success, non-zero if the frame level is invalid.  
263
 */
264
int dbglgetlvl(dbgcxdef *ctx, uchar *buf, int level);
265
266
/*
267
 *   Set a breakpoint by symbolic address: "function" or
268
 *   "object.property".  The string may contain whitespace characters
269
 *   around each symbol; it must be null-terminated.  If an error occurs,
270
 *   the error number is returned.  bpnum returns with the breakpoint
271
 *   number if err == 0.  If the condition string is given (and is not an
272
 *   empty string), the condition is compiled in the scope of the
273
 *   breakpoint and attached as the breakpoint condition.  
274
 */
275
int dbgbpset(dbgcxdef *ctx, char *addr, int *bpnum);
276
277
/* 
278
 *   Set a breakpoint at an object + offset location.  If 'toggle' is
279
 *   true, and there's already a breakpoint at the given location, we'll
280
 *   clear the breakpoint; in this case, *did_set will return false to
281
 *   indicate that an existing breakpoint was cleared rather than a new
282
 *   breakpoint created.  *did_set will return true if a new breakpoint
283
 *   was set.  
284
 */
285
int dbgbpat(dbgcxdef *ctx, objnum objn, objnum self,
286
            uint ofs, int *bpnum, char *bpname, int toggle,
287
            char *condition, int *did_set);
288
289
/* 
290
 *   Set a breakpoint at an object + offset location, optionally with a
291
 *   condition, using an existing breakpoint slot.  If the slot is already
292
 *   in use, we'll return an error.  
293
 */
294
int dbgbpatid(dbgcxdef *ctx, int bpnum, objnum target, objnum self,
295
              uint ofs, char *bpname, int toggle, char *cond,
296
              int *did_set);
297
298
/*
299
 *   Determine if there's a breakpoint at a given code location.  Fills in
300
 *   *bpnum with the breakpoint identifier and returns true if a
301
 *   breakpoint is found at the given location; returns false if there are
302
 *   no breakpoints matching the description.  
303
 */
304
int dbgisbp(dbgcxdef *ctx, objnum target, objnum self, uint ofs, int *bpnum);
305
306
/*
307
 *   Determine if the given breakpoint is enabled 
308
 */
309
int dbgisbpena(dbgcxdef *ctx, int bpnum);
310
311
/*
312
 *   Delete a breakpoint by breakpoint number (as returned from
313
 *   dbgbpset).  Returns error number, or 0 for success. 
314
 */
315
int dbgbpdel(dbgcxdef *ctx, int bpnum);
316
317
/* disable or enable a breakpoint, by breakpoint number; returns error num */
318
int dbgbpdis(dbgcxdef *ctx, int bpnum, int disable);
319
320
/*
321
 *   Set a new condition for the given breakpoint.  Replaces any existing
322
 *   condition.  If an error occurs, we'll leave the old condition as it
323
 *   was and return a non-zero error code; on success, we'll update the
324
 *   condition and return zero. 
325
 */
326
int dbgbpsetcond(dbgcxdef *ctx, int bpnum, char *cond);
327
328
/* list breakpoints, using user callback to do display */
329
void dbgbplist(dbgcxdef *ctx,
330
               void (*dispfn)(void *ctx, const char *str, int len),
331
               void *dispctx);
332
333
/* enumerate breakpoints */
334
void dbgbpenum(dbgcxdef *ctx,
335
               void (*cbfunc)(void *cbctx, int bpnum, const char *desc,
336
                              const char *cond, int disabled), void *cbctx);
337
338
/* call callback with lindef data for each breakpoint currently set */
339
void dbgbpeach(dbgcxdef *ctx,
340
               void (*fn)(void *, int, uchar *, uint),
341
               void *fnctx);
342
343
/* 
344
 *   Get information on a specific breakpoint.  Returns zero on success,
345
 *   non-zero on failure. 
346
 */
347
int dbgbpgetinfo(dbgcxdef *ctx, int bpnum, char *descbuf, size_t descbuflen,
348
                 char *condbuf, size_t condbuflen);
349
350
/* 
351
 *   Evaluate an expression (a text string to be parsed) at a particular
352
 *   stack context level; returns error number.  Invokes the callback
353
 *   function repeatedly to display the value string, and ends the display
354
 *   with a newline.  If showtype is true, we'll include a type name
355
 *   prefix, otherwise we'll simply display the value.  
356
 */
357
int dbgeval(dbgcxdef *ctx, char *expr,
358
            void (*dispfn)(void *dispctx, const char *str, int strl),
359
            void *dispctx, int level, int showtype);
360
361
/*
362
 *   Evaluate an expression, extended version.  For aggregate values
363
 *   (objects, lists), we'll invoke a callback function for each value
364
 *   contained by the aggregate value, passing the callback the name and
365
 *   relationship of the subitem.  The relationship is simply the operator
366
 *   that should be used to join the parent expression and the subitem
367
 *   name to form the full subitem expression; for objects, it's ".", and
368
 *   for lists it's null (because for lists the subitem names will include
369
 *   brackets).  'speculative' is passed to dbgcompile; see the comments
370
 *   there for information on the purpose of this flag.  
371
 */
372
int dbgevalext(dbgcxdef *ctx, char *expr,
373
               void (*dispfn)(void *dispctx, const char *str, int strl),
374
               void *dispctx, int level, int showtype, dattyp *dat,
375
               void (*aggcb)(void *aggctx, const char *subname,
376
                             int subnamelen, const char *relationship),
377
               void *aggctx, int speculative);
378
379
/* 
380
 *   enumerate local variables at a given stack context level by calling
381
 *   the given function once for each local variable 
382
 */
383
void dbgenumlcl(dbgcxdef *ctx, int level,
384
                void (*func)(void *ctx, const char *lclnam, size_t lclnamlen),
385
                void *cbctx);
386
387
/* 
388
 *   Compile an expression in a given frame context.  Returns an error
389
 *   number.  Allocates a new object to contain the compiled code, and
390
 *   returns the object number in *objn; the caller is responsible for
391
 *   freeing the object when done with it.
392
 *   
393
 *   If 'speculative' is set to true, we'll prohibit the expression from
394
 *   making any assignments or calling any methods or functions.  This
395
 *   mode can be used to try compiling an expression that the user could
396
 *   conceivably be interested in but has not expressly evaluated; for
397
 *   example, this can be used to implement "tooltip evaluation," where
398
 *   the debugger automatically shows a little pop-up window with the
399
 *   expression under the mouse cursor if the mouse cursor is left
400
 *   hovering over some text for a few moments.  In such cases, since the
401
 *   user hasn't explicitly requested evaluation, it would be bad to make
402
 *   any changes to game state, hence the prohibition of assignments or
403
 *   calls.  
404
 */
405
int dbgcompile(dbgcxdef *ctx, char *expr, dbgfdef *fr, objnum *objn,
406
               int speculative);
407
408
/* display a stack traceback through a user callback */
409
void dbgstktr(dbgcxdef *ctx,
410
              void (*dispfn)(void *dispctx, const char *str, int strl),
411
              void *dispctx, int level, int toponly, int include_markers);
412
413
/* format a display of where execution is stopped into a buffer */
414
void dbgwhere(dbgcxdef *ctx, char *buf);
415
416
/* set a watch expression; returns error or 0 for success */
417
int dbgwxset(dbgcxdef *ctx, char *expr, int *wxnum, int level);
418
419
/* delete a watch expression */
420
int dbgwxdel(dbgcxdef *ctx, int wxnum);
421
422
/* update all watch expressions */
423
void dbgwxupd(dbgcxdef *ctx,
424
              void (*dispfn)(void *dispctx, const char *txt, int len),
425
              void *dispctx);
426
427
/* switch to a new active lindef */
428
void dbgswitch(struct lindef **linp, struct lindef *newlin);
429
430
431
432
/* ======================================================================== */
433
/*
434
 *   User Interface Routines.  The routines are called by the debugger
435
 *   to perform user interaction.
436
 */
437
438
/* 
439
 *   Debugger user interface initialization, phase one.  TADS calls this
440
 *   routine during startup, before reading the .GAM file, to let the user
441
 *   interface perform any initialization it requires before the .GAM file
442
 *   is loaded.  
443
 */
444
void dbguini(dbgcxdef *ctx, const char *game_filename);
445
446
/*
447
 *   Debugger user interface initialization, phase two.  TADS calls this
448
 *   routine during startup, after read the .GAM file.  The debugger user
449
 *   interface code can perform any required initialization that depends
450
 *   on the .GAM file having been read.  
451
 */
452
void dbguini2(dbgcxdef *ctx);
453
454
/*
455
 *   Determine if the debugger can resume from a run-time error.  This
456
 *   reflects the capabilities of the user interface of the debugger.  In
457
 *   particular, if the UI provides a way to change the instruction
458
 *   pointer, then the debugger can resume from an error, since the user
459
 *   can always move past the run-time error and continue execution.  If
460
 *   the UI doesn't let the user change the instruction pointer, resuming
461
 *   from an error won't work, since the program will keep hitting the
462
 *   same error and re-entering the debugger.  If this returns false, the
463
 *   run-time will trap to the debugger on an error, but will simply abort
464
 *   the current command when the debugger returns.  If this returns true,
465
 *   the run-time will trap to the debugger on an error with the
466
 *   instruction pointer set back to the start of the line containing the
467
 *   error, and will thus re-try the same line of code when the debugger
468
 *   returns, unless the debugger explicitly moves the instruction pointer
469
 *   before returning.  
470
 */
471
int dbgu_err_resume(dbgcxdef *ctx);
472
473
/*
474
 *   Find a source file.  origname is the name of the source file as it
475
 *   appears in the game's debugging information; this routine should
476
 *   figure out where the file actually is, and put the fully-qualified
477
 *   path to the file in fullname.  The debugger calls this after it
478
 *   exhausts all of its other methods of finding a source file (such as
479
 *   searching the include path).
480
 *   
481
 *   Return true if the source file should be considered valid, false if
482
 *   not.  Most implementations will simply return true if the file was
483
 *   found, false if not; however, this approach will cause the debugger
484
 *   to terminate with an error at start-up if the user hasn't set up the
485
 *   debugger's include path correctly before running the debugger.  Some
486
 *   implementations, in particular GUI implementations, may wish to wait
487
 *   to find a file until the file is actually needed, rather than pester
488
 *   the user with file search dialogs repeatedly at start-up.
489
 *   
490
 *   must_find_file specifies how to respond if we can't find the file.
491
 *   If must_find_file is true, we should always return false if we can't
492
 *   find the file.  If must_find_file is false, however, we can
493
 *   optionally return true even if we can't find the file.  Doing so
494
 *   indicates that the debugger UI will defer locating the file until it
495
 *   is actually needed.
496
 *   
497
 *   If this routine returns true without actually finding the file, it
498
 *   should set fullname[0] to '\0' to indicate that fullname doesn't
499
 *   contain a valid filename.  
500
 */
501
int dbgu_find_src(const char *origname, int origlen,
502
                  char *fullname, size_t full_len, int must_find_file);
503
504
505
/* 
506
 *   Debugger user interface main command loop.  If err is non-zero, the
507
 *   debugger was entered because a run-time error occurred; otherwise, if
508
 *   bphit is non-zero, it's the number of the breakpoint that was
509
 *   encountered; otherwise, the debugger was entered through a
510
 *   single-step of some kind.  exec_ofs is the byte offset within the
511
 *   target object of the next instruction to be executed.  This can be
512
 *   changed upon return, in which case execution will continue from the
513
 *   new offset, but the offset must be within the same method of the same
514
 *   object (or within the same function) as it was upon entry. 
515
 */
516
void dbgucmd(dbgcxdef *ctx, int bphit, int err, unsigned int *exec_ofs);
517
518
/*
519
 *   Debugger UI - quitting game.  The runtime calls this routine just
520
 *   before the play loop is about to terminate after the game code has
521
 *   called the "quit" built-in function.  If the debugger wants, it can
522
 *   take control here (just as with dbgucmd()) for as long as it wants.
523
 *   If the debugger wants to restart the game, it should call bifrst().
524
 *   If this routine returns without signalling a RUN_RESTART error, TADS
525
 *   will terminate.  If a RUN_RESTART error is signalled, TADS will
526
 *   resume the play loop.  
527
 */
528
void dbguquitting(dbgcxdef *ctx);
529
530
/* 
531
 *   debugger user interface termination - this routine is called when the
532
 *   debugger is about to terminate, so that the user interface can close
533
 *   itself down (close windows, release memory, etc) 
534
 */
535
void dbguterm(dbgcxdef *ctx);
536
537
/*
538
 *   Debugger user interface: display an error.  This is called mainly so
539
 *   that the debugger can display an error using special output
540
 *   formatting if the error occurs while debugging. 
541
 */
542
void dbguerr(dbgcxdef *ctx, int errnum, char *msg);
543
544
/* turn hidden output tracing on/off */
545
void trchid(void);
546
void trcsho(void);
547
548
549
/* ======================================================================== */
550
/*
551
 *   optional debugger macros - these compile to nothing when compiling a
552
 *   version for use without the debugger 
553
 */
554
555
#ifdef DBG_OFF
556
# define dbgenter(ctx, bp, self, target, prop, binum, argc)
557
# define dbgleave(ctx, exittype)
558
# define dbgdump(ctx)
559
# define dbgrst(ctx) ((void)0)
560
# define dbgframe(ctx, frofs, linofs)
561
# define dbgssi(ctx, ofs, instr, err, p)
562
#else /* DBG_OFF */
563
# define dbgenter(ctx, bp, self, target, prop, binum, argc) \
564
   dbgent(ctx, bp, self, target, prop, binum, argc)
565
# define dbgleave(ctx, exittype) dbglv(ctx, exittype)
566
# define dbgdump(ctx) dbgds(ctx)
567
# define dbgrst(ctx) ((ctx)->dbgcxfcn = (ctx)->dbgcxdep = 0)
568
# define dbgframe(ctx, frofs, linofs) \
569
   (((ctx)->dbgcxfrm[(ctx)->dbgcxfcn - 1].dbgffr = (frofs)), \
570
    ((ctx)->dbgcxfrm[(ctx)->dbgcxfcn - 1].dbgflin = (linofs)))
571
# define dbgssi(ctx, ofs, instr, err, p) dbgss(ctx, ofs, instr, err, p)
572
#endif /* DBG_OFF */
573
574
575
/* ======================================================================== */
576
/* private internal routines */
577
578
void dbgent(dbgcxdef *ctx, struct runsdef *bp, objnum self, objnum target,
579
            prpnum prop, int binum, int argc);
580
581
void dbglv(dbgcxdef *ctx, int exittype);
582
583
void dbgds(dbgcxdef *ctx);
584
585
void dbgss(dbgcxdef *ctx, uint ofs, int instr, int err, uchar *noreg *p);
586
587
void dbgpval(struct dbgcxdef *ctx, struct runsdef *val,
588
             void (*dispfn)(void *, const char *, int),
589
             void *dispctx, int showtype);
590
591
int dbgtabsea(struct toktdef *tab, char *name, int namel, int hash,
592
              struct toksdef *ret);
593
594
595
#ifdef __cplusplus
596
}
597
#endif
598
599
#endif /* DBG_INCLUDED */