pike.git/
src/
builtin.cmod
Branch:
Tag:
Non-build tags
All tags
No tags
2018-11-29
2018-11-29 03:13:19 by William Welliver <william@welliver.org>
e15f8269c41425dfae8ded58a8dbcd26769dc410 (
148
lines) (+
137
/-
11
)
[
Show
|
Annotate
]
Branch:
bill/debugger-concept
debugger: multiple breakpoint support, enable/disable support.
516:
}
-
PMOD
_
EXPORT
-
PIKEFUN
int
add
_breakpoint
(program
p,
string fname, int line_number)
+
PIKECLASS debug
_
breakpoint {
+
+
PIKEVAR program prog flags ID_PROTECTED|ID_PRIVATE;
+
PIKEVAR string fname flags ID_PROTECTED|ID_PRIVATE;
+
PIKEVAR
int
line
_
number flags ID_PROTECTED|ID_PRIVATE;
+
PIKEVAR int enabled flags ID_PROTECTED|ID_PRIVATE;
+
+
CVAR struct debug_
breakpoint
*
bp;
+
+
PIKEFUN void create(
string fname, int line_number)
+
flags ID_PROTECTED;
optflags OPT_SIDE_EFFECT;
-
efun;
+
{
-
+
THIS->fname = fname;
+
THIS->line_number = line_number;
+
add_ref(fname);
+
}
+
+
PIKEFUN void create(
+
program p, string fname, int line_number)
+
flags ID_PROTECTED;
+
optflags OPT_SIDE_EFFECT;
+
{
+
THIS->prog = p;
+
THIS->fname = fname;
+
THIS->line_number = line_number;
+
add_ref(p);
+
add_ref(fname);
+
}
+
PIKEFUN program get_program() {
+
if(THIS->prog)
+
RETURN THIS->prog;
+
else push_int(0);
+
}
+
+
PIKEFUN string get_filename() {
+
add_ref(THIS->fname); /* it seems strange to need this, but whatever. */
+
RETURN THIS->fname;
+
}
+
+
PIKEFUN int get_line_number() {
+
RETURN THIS->line_number;
+
}
+
+
PIKEFUN int get_enabled() {
+
RETURN THIS->enabled;
+
}
+
+
PIKEFUN int enable() {
+
ptrdiff_t offset;
+
if(THIS->enabled)
+
Pike_error("Breakpoint already enabled.\n");
+
/* This should eventually be a deferred breakpoint initialization. */
+
if(!(THIS->prog))
+
Pike_error("Program for breakpoint has not been resolved. Unable to enable.\n");
+
offset = low_get_offset_for_line(THIS->prog, THIS->fname, THIS->line_number);
+
if(offset < 0) Pike_error("Unable to find offset of line number in program!\n");
+
#ifdef PIKE_DEBUG
+
struct debug_breakpoint * bp = malloc(sizeof(struct debug_breakpoint));
+
if(!bp) Pike_fatal("Unable to allocate memory for breakpoint\n");
+
if(THIS->prog->breakpoints)
+
bp->next = THIS->prog->breakpoints;
+
else
+
bp->next = NULL;
+
bp->prev = NULL;
+
bp->offset = offset;
+
/* this may be unnecessary */
+
bp->prog = THIS->prog;
+
THIS->prog->breakpoints = bp;
+
THIS->bp = bp;
+
THIS->enabled = 1;
+
#else
+
Pike_error("Cannot enable breakpoints if debug is not enabled.\n");
+
#endif /*PIKE_DEBUG*/
+
}
+
+
void low_disable_breakpoint() {
+
struct debug_breakpoint * bp, *pbp;
+
+
if((THIS->prog) && (bp = (THIS->prog->breakpoints)) != NULL) {
+
while(bp != NULL) {
+
if(bp == (THIS->bp)) {
+
printf("found a breakpoint to free.\n");
+
if(bp->next && bp->prev) { // somewhere in the middle, connect the previous and next.
+
bp->prev->next = bp->next;
+
bp->next->prev = bp->prev;
+
} else if(bp->next) { // only next pointer: at the beginning, so make next the new first.
+
bp->next->prev = NULL;
+
THIS->prog->breakpoints = bp->next;
+
} else if(bp->prev) { // only prev pointer: at the end, just unlink us.
+
bp->prev->next = NULL;
+
} else {
+
THIS->prog->breakpoints = NULL;
+
}
+
pbp = bp;
+
bp = bp->next;
+
free(pbp);
+
THIS->bp = NULL;
+
} else {
+
bp = bp->next;
+
}
+
};
+
}
+
}
+
+
ptrdiff_t low_add_breakpoint() {
ptrdiff_t pc_offset; // TODO: we need to develop the line search further: a file can be included multiple times within a program, and so // in theory, a breakpoint for a line within a file could actually be multiple breakpoints. we stop at the first one.
-
pc_offset = low_get_offset_for_line(
p
, fname, line_number);
-
pop_n_elems(args);
-
bp_offset = pc_offset;
-
bp_prog = p;
-
if(!pc_offset)
Pike_error("Line
number not found\n")
;
-
push_int(
pc_offset
)
;
+
pc_offset = low_get_offset_for_line(
THIS->prog
,
THIS->
fname,
THIS->
line_number);
+
if(!pc_offset)
return
-1
;
+
return
pc_offset;
}
-
+
PIKEFUN int disable() {
+
if(!(THIS->enabled))
+
Pike_error("Breakpoint not enabled.\n");
+
low_disable_breakpoint();
+
THIS->enabled = 0;
+
}
+
+
INIT {
+
THIS->prog = NULL;
+
THIS->fname = NULL;
+
THIS->line_number = 0;
+
THIS->enabled = 0;
+
}
+
+
EXIT {
+
low_disable_breakpoint();
+
if(THIS->prog)
+
free_program(THIS->prog);
+
if(THIS->fname)
+
free_string(THIS->fname);
+
THIS->bp = NULL; /* should already have been freed by low_disable_breakpoint(). */
+
THIS->prog = NULL;
+
THIS->fname = NULL;
+
THIS->line_number = 0;
+
}
+
}
+
/*! @decl string basetype(mixed x) *! *! Same as sprintf("%t",x);
3026:
} PMOD_EXPORT
-
PIKEFUN array(mixed) debug_backtrace()
-
efun
;
+
PIKEFUN array(mixed)
__
debug_backtrace()
+
flags ID_PROTECTED
;
optflags OPT_EXTERNAL_DEPEND; { low_low_backtrace(& Pike_interpreter, 1);