mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
dbug: function/ (a.k.a. SUBDIR) syntax
dbug/dbug.c: function/ (a.k.a. SUBDIR) syntax dbug/tests-t.pl: 1. add support for test comments 2. add test comments 3. move tests around 4. add SUBDIR tests dbug/tests.c: support code for SUBDIR testing include/my_dbug.h: comments. change in _db_set_ prototype dbug/user.r: negative lists and function/ syntax.
This commit is contained in:
396
dbug/dbug.c
396
dbug/dbug.c
@ -71,6 +71,12 @@
|
|||||||
* thread-local settings
|
* thread-local settings
|
||||||
* negative lists (-#-d,info => everything but "info")
|
* negative lists (-#-d,info => everything but "info")
|
||||||
*
|
*
|
||||||
|
* function/ syntax
|
||||||
|
* (the logic is - think of a call stack as of a path.
|
||||||
|
* "function" means only this function, "function/" means the hierarchy.
|
||||||
|
* in the future, filters like function1/function2 could be supported.
|
||||||
|
* wildcards are a natural extension too: * and ?)
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -101,21 +107,24 @@
|
|||||||
* The following flags are used to determine which
|
* The following flags are used to determine which
|
||||||
* capabilities the user has enabled with the settings
|
* capabilities the user has enabled with the settings
|
||||||
* push macro.
|
* push macro.
|
||||||
|
*
|
||||||
|
* TRACE_ON is also used in _db_stack_frame_->level
|
||||||
|
* (until we add flags to _db_stack_frame_, increasing it by 4 bytes)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define TRACE_ON 000001 /* Trace enabled */
|
#define DEBUG_ON (1 << 1) /* Debug enabled */
|
||||||
#define DEBUG_ON 000002 /* Debug enabled */
|
#define FILE_ON (1 << 2) /* File name print enabled */
|
||||||
#define FILE_ON 000004 /* File name print enabled */
|
#define LINE_ON (1 << 3) /* Line number print enabled */
|
||||||
#define LINE_ON 000010 /* Line number print enabled */
|
#define DEPTH_ON (1 << 4) /* Function nest level print enabled */
|
||||||
#define DEPTH_ON 000020 /* Function nest level print enabled */
|
#define PROCESS_ON (1 << 5) /* Process name print enabled */
|
||||||
#define PROCESS_ON 000040 /* Process name print enabled */
|
#define NUMBER_ON (1 << 6) /* Number each line of output */
|
||||||
#define NUMBER_ON 000100 /* Number each line of output */
|
#define PROFILE_ON (1 << 7) /* Print out profiling code */
|
||||||
#define PROFILE_ON 000200 /* Print out profiling code */
|
#define PID_ON (1 << 8) /* Identify each line with process id */
|
||||||
#define PID_ON 000400 /* Identify each line with process id */
|
#define TIMESTAMP_ON (1 << 9) /* timestamp every line of output */
|
||||||
#define TIMESTAMP_ON 001000 /* timestamp every line of output */
|
#define SANITY_CHECK_ON (1 << 10) /* Check safemalloc on DBUG_ENTER */
|
||||||
#define SANITY_CHECK_ON 002000 /* Check safemalloc on DBUG_ENTER */
|
#define FLUSH_ON_WRITE (1 << 11) /* Flush on every write */
|
||||||
#define FLUSH_ON_WRITE 004000 /* Flush on every write */
|
#define OPEN_APPEND (1 << 12) /* Open for append */
|
||||||
#define OPEN_APPEND 010000 /* Open for append */
|
#define TRACE_ON (1 << 31) /* Trace enabled. MUST be the highest bit!*/
|
||||||
|
|
||||||
#define TRACING (cs->stack->flags & TRACE_ON)
|
#define TRACING (cs->stack->flags & TRACE_ON)
|
||||||
#define DEBUGGING (cs->stack->flags & DEBUG_ON)
|
#define DEBUGGING (cs->stack->flags & DEBUG_ON)
|
||||||
@ -141,7 +150,7 @@
|
|||||||
* (G?) which allowed the user to specify this.
|
* (G?) which allowed the user to specify this.
|
||||||
*
|
*
|
||||||
* If the automatic variables get allocated on the stack in
|
* If the automatic variables get allocated on the stack in
|
||||||
* reverse order from their declarations, then define AUTOS_REVERSE.
|
* reverse order from their declarations, then define AUTOS_REVERSE to 1.
|
||||||
* This is used by the code that keeps track of stack usage. For
|
* This is used by the code that keeps track of stack usage. For
|
||||||
* forward allocation, the difference in the dbug frame pointers
|
* forward allocation, the difference in the dbug frame pointers
|
||||||
* represents stack used by the callee function. For reverse allocation,
|
* represents stack used by the callee function. For reverse allocation,
|
||||||
@ -156,6 +165,8 @@
|
|||||||
|
|
||||||
#ifdef M_I386 /* predefined by xenix 386 compiler */
|
#ifdef M_I386 /* predefined by xenix 386 compiler */
|
||||||
#define AUTOS_REVERSE 1
|
#define AUTOS_REVERSE 1
|
||||||
|
#else
|
||||||
|
#define AUTOS_REVERSE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -180,9 +191,13 @@ struct link {
|
|||||||
char str[1]; /* Pointer to link's contents */
|
char str[1]; /* Pointer to link's contents */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* flags for struct link */
|
/* flags for struct link and return flags of InList */
|
||||||
#define INCLUDE 1
|
#define SUBDIR 1 /* this MUST be 1 */
|
||||||
#define EXCLUDE 2
|
#define INCLUDE 2
|
||||||
|
#define EXCLUDE 4
|
||||||
|
/* this is not a struct link flag, but only a return flags of InList */
|
||||||
|
#define MATCHED 65536
|
||||||
|
#define NOT_MATCHED 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Debugging settings can be pushed or popped off of a
|
* Debugging settings can be pushed or popped off of a
|
||||||
@ -223,15 +238,15 @@ my_bool _dbug_on_= TRUE; /* FALSE if no debugging at all */
|
|||||||
|
|
||||||
typedef struct _db_code_state_ {
|
typedef struct _db_code_state_ {
|
||||||
const char *process; /* Pointer to process name; usually argv[0] */
|
const char *process; /* Pointer to process name; usually argv[0] */
|
||||||
const char *func; /* Name of current user function */
|
const char *func; /* Name of current user function */
|
||||||
const char *file; /* Name of current user file */
|
const char *file; /* Name of current user file */
|
||||||
char **framep; /* Pointer to current frame */
|
struct _db_stack_frame_ *framep; /* Pointer to current frame */
|
||||||
struct settings *stack; /* debugging settings */
|
struct settings *stack; /* debugging settings */
|
||||||
const char *jmpfunc; /* Remember current function for setjmp */
|
const char *jmpfunc; /* Remember current function for setjmp */
|
||||||
const char *jmpfile; /* Remember current file for setjmp */
|
const char *jmpfile; /* Remember current file for setjmp */
|
||||||
int lineno; /* Current debugger output line number */
|
int lineno; /* Current debugger output line number */
|
||||||
int level; /* Current function nesting level */
|
int level; /* Current function nesting level */
|
||||||
int jmplevel; /* Remember nesting level at setjmp() */
|
int jmplevel; /* Remember nesting level at setjmp() */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following variables are used to hold the state information
|
* The following variables are used to hold the state information
|
||||||
@ -272,10 +287,18 @@ static void PushState(CODE_STATE *cs);
|
|||||||
/* Free memory associated with debug state. */
|
/* Free memory associated with debug state. */
|
||||||
static void FreeState (CODE_STATE *cs, struct settings *state, int free_state);
|
static void FreeState (CODE_STATE *cs, struct settings *state, int free_state);
|
||||||
/* Test for tracing enabled */
|
/* Test for tracing enabled */
|
||||||
static BOOLEAN DoTrace(CODE_STATE *cs);
|
static int DoTrace(CODE_STATE *cs, int tracing);
|
||||||
|
/*
|
||||||
|
return values of DoTrace.
|
||||||
|
Can also be used as bitmask: ret & DO_TRACE
|
||||||
|
*/
|
||||||
|
#define DO_TRACE 1
|
||||||
|
#define DONT_TRACE 2
|
||||||
|
#define ENABLE_TRACE 3
|
||||||
|
#define DISABLE_TRACE 4
|
||||||
|
|
||||||
/* Test to see if file is writable */
|
/* Test to see if file is writable */
|
||||||
#if !(!defined(HAVE_ACCESS) || defined(MSDOS))
|
#if defined(HAVE_ACCESS) && !defined(MSDOS)
|
||||||
static BOOLEAN Writable(const char *pathname);
|
static BOOLEAN Writable(const char *pathname);
|
||||||
/* Change file owner and group */
|
/* Change file owner and group */
|
||||||
static void ChangeOwner(CODE_STATE *cs, char *pathname);
|
static void ChangeOwner(CODE_STATE *cs, char *pathname);
|
||||||
@ -423,7 +446,7 @@ void _db_process_(const char *name)
|
|||||||
|
|
||||||
if (!db_process)
|
if (!db_process)
|
||||||
db_process= name;
|
db_process= name;
|
||||||
|
|
||||||
get_code_state_or_return;
|
get_code_state_or_return;
|
||||||
cs->process= name;
|
cs->process= name;
|
||||||
}
|
}
|
||||||
@ -431,12 +454,7 @@ void _db_process_(const char *name)
|
|||||||
/*
|
/*
|
||||||
* FUNCTION
|
* FUNCTION
|
||||||
*
|
*
|
||||||
* _db_set_ set current debugger settings
|
* ParseDbug parse control string and set current debugger settings
|
||||||
*
|
|
||||||
* SYNOPSIS
|
|
||||||
*
|
|
||||||
* VOID _db_set_(control)
|
|
||||||
* char *control;
|
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
*
|
*
|
||||||
@ -458,15 +476,17 @@ void _db_process_(const char *name)
|
|||||||
*
|
*
|
||||||
* For convenience, any leading "-#" is stripped off.
|
* For convenience, any leading "-#" is stripped off.
|
||||||
*
|
*
|
||||||
|
* RETURN
|
||||||
|
* 1 - a list of functions ("f" flag) was possibly changed
|
||||||
|
* 0 - a list of functions was not changed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void _db_set_(CODE_STATE *cs, const char *control)
|
int ParseDbug(CODE_STATE *cs, const char *control)
|
||||||
{
|
{
|
||||||
const char *end;
|
const char *end;
|
||||||
int rel;
|
int rel, f_used=0;
|
||||||
struct settings *stack;
|
struct settings *stack;
|
||||||
|
|
||||||
get_code_state_if_not_set_or_return;
|
|
||||||
stack= cs->stack;
|
stack= cs->stack;
|
||||||
|
|
||||||
if (control[0] == '-' && control[1] == '#')
|
if (control[0] == '-' && control[1] == '#')
|
||||||
@ -517,7 +537,6 @@ void _db_set_(CODE_STATE *cs, const char *control)
|
|||||||
{
|
{
|
||||||
int c, sign= (*control == '+') ? 1 : (*control == '-') ? -1 : 0;
|
int c, sign= (*control == '+') ? 1 : (*control == '-') ? -1 : 0;
|
||||||
if (sign) control++;
|
if (sign) control++;
|
||||||
/* if (!rel) sign=0; */
|
|
||||||
c= *control++;
|
c= *control++;
|
||||||
if (*control == ',') control++;
|
if (*control == ',') control++;
|
||||||
/* XXX when adding new cases here, don't forget _db_explain_ ! */
|
/* XXX when adding new cases here, don't forget _db_explain_ ! */
|
||||||
@ -546,6 +565,7 @@ void _db_set_(CODE_STATE *cs, const char *control)
|
|||||||
stack->delay= atoi(control);
|
stack->delay= atoi(control);
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
|
f_used= 1;
|
||||||
if (sign < 0 && control == end)
|
if (sign < 0 && control == end)
|
||||||
{
|
{
|
||||||
if (!is_shared(stack,functions))
|
if (!is_shared(stack,functions))
|
||||||
@ -684,8 +704,139 @@ void _db_set_(CODE_STATE *cs, const char *control)
|
|||||||
control=end+1;
|
control=end+1;
|
||||||
end= DbugStrTok(control);
|
end= DbugStrTok(control);
|
||||||
}
|
}
|
||||||
|
return !rel || f_used;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define framep_trace_flag(cs, frp) (frp ? \
|
||||||
|
frp->level & TRACE_ON : \
|
||||||
|
(ListFlags(cs->stack->functions) & INCLUDE) ? \
|
||||||
|
0 : (uint)TRACE_ON)
|
||||||
|
|
||||||
|
void FixTraceFlags_helper(CODE_STATE *cs, const char *func,
|
||||||
|
struct _db_stack_frame_ *framep)
|
||||||
|
{
|
||||||
|
if (framep->prev)
|
||||||
|
FixTraceFlags_helper(cs, framep->func, framep->prev);
|
||||||
|
|
||||||
|
cs->func= func;
|
||||||
|
cs->level= framep->level & ~TRACE_ON;
|
||||||
|
framep->level= cs->level | framep_trace_flag(cs, framep->prev);
|
||||||
|
/*
|
||||||
|
we don't set cs->framep correctly, even though DoTrace uses it.
|
||||||
|
It's ok, because cs->framep may only affect DO_TRACE/DONT_TRACE return
|
||||||
|
values, but we ignore them here anyway
|
||||||
|
*/
|
||||||
|
switch(DoTrace(cs, 1)) {
|
||||||
|
case ENABLE_TRACE:
|
||||||
|
framep->level|= TRACE_ON;
|
||||||
|
break;
|
||||||
|
case DISABLE_TRACE:
|
||||||
|
framep->level&= ~TRACE_ON;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define fflags(cs) cs->stack->out_file ? ListFlags(cs->stack->functions) : TRACE_ON;
|
||||||
|
|
||||||
|
void FixTraceFlags(int old_fflags, CODE_STATE *cs)
|
||||||
|
{
|
||||||
|
const char *func;
|
||||||
|
int new_fflags, traceon, level;
|
||||||
|
struct _db_stack_frame_ *framep;
|
||||||
|
|
||||||
|
/*
|
||||||
|
first (a.k.a. safety) check:
|
||||||
|
if we haven't started tracing yet, no call stack at all - we're safe.
|
||||||
|
*/
|
||||||
|
framep=cs->framep;
|
||||||
|
if (framep == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ok, the tracing has started, call stack isn't empty.
|
||||||
|
|
||||||
|
second check: does the new list have a SUBDIR rule ?
|
||||||
|
*/
|
||||||
|
new_fflags=fflags(cs);
|
||||||
|
if (new_fflags & SUBDIR)
|
||||||
|
goto yuck;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ok, new list doesn't use SUBDIR.
|
||||||
|
|
||||||
|
third check: we do NOT need to re-scan if
|
||||||
|
neither old nor new lists used SUBDIR flag and if a default behavior
|
||||||
|
(whether an unlisted function is traced) hasn't changed.
|
||||||
|
Default behavior depends on whether there're INCLUDE elements in the list.
|
||||||
|
*/
|
||||||
|
if (!(old_fflags & SUBDIR) && !((new_fflags^old_fflags) & INCLUDE))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ok, old list may've used SUBDIR, or defaults could've changed.
|
||||||
|
|
||||||
|
fourth check: are we inside a currently active SUBDIR rule ?
|
||||||
|
go up the call stack, if TRACE_ON flag ever changes its value - we are.
|
||||||
|
*/
|
||||||
|
for (traceon=framep->level; framep; framep=framep->prev)
|
||||||
|
if ((traceon ^ framep->level) & TRACE_ON)
|
||||||
|
goto yuck;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ok, TRACE_ON flag doesn't change in the call stack.
|
||||||
|
|
||||||
|
fifth check: but is the top-most value equal to a default one ?
|
||||||
|
*/
|
||||||
|
if (((traceon & TRACE_ON) != 0) == ((new_fflags & INCLUDE) == 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
yuck:
|
||||||
|
/*
|
||||||
|
Yuck! function list was changed, and one of the currently active rules
|
||||||
|
was possibly affected. For example, a tracing could've been enabled or
|
||||||
|
disabled for a function somewhere up the call stack.
|
||||||
|
To react correctly, we must go up the call stack all the way to
|
||||||
|
the top and re-match rules to set TRACE_ON bit correctly.
|
||||||
|
|
||||||
|
We must traverse the stack forwards, not backwards.
|
||||||
|
That's what a recursive helper is doing.
|
||||||
|
It'll destroy two CODE_STATE fields, save them now.
|
||||||
|
*/
|
||||||
|
func= cs->func;
|
||||||
|
level= cs->level;
|
||||||
|
FixTraceFlags_helper(cs, func, cs->framep);
|
||||||
|
/* now we only need to restore CODE_STATE fields, and we're done */
|
||||||
|
cs->func= func;
|
||||||
|
cs->level= level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FUNCTION
|
||||||
|
*
|
||||||
|
* _db_set_ set current debugger settings
|
||||||
|
*
|
||||||
|
* SYNOPSIS
|
||||||
|
*
|
||||||
|
* VOID _db_set_(control)
|
||||||
|
* char *control;
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* Given pointer to a debug control string in "control",
|
||||||
|
* parses the control string, and sets
|
||||||
|
* up a current debug settings.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _db_set_(const char *control)
|
||||||
|
{
|
||||||
|
CODE_STATE *cs;
|
||||||
|
int old_fflags;
|
||||||
|
get_code_state_or_return;
|
||||||
|
old_fflags=fflags(cs);
|
||||||
|
if (ParseDbug(cs, control))
|
||||||
|
FixTraceFlags(old_fflags, cs);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION
|
* FUNCTION
|
||||||
@ -701,16 +852,19 @@ void _db_set_(CODE_STATE *cs, const char *control)
|
|||||||
*
|
*
|
||||||
* Given pointer to a debug control string in "control", pushes
|
* Given pointer to a debug control string in "control", pushes
|
||||||
* the current debug settings, parses the control string, and sets
|
* the current debug settings, parses the control string, and sets
|
||||||
* up a new debug settings with _db_set_()
|
* up a new debug settings
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void _db_push_(const char *control)
|
void _db_push_(const char *control)
|
||||||
{
|
{
|
||||||
CODE_STATE *cs;
|
CODE_STATE *cs;
|
||||||
|
int old_fflags;
|
||||||
get_code_state_or_return;
|
get_code_state_or_return;
|
||||||
|
old_fflags=fflags(cs);
|
||||||
PushState(cs);
|
PushState(cs);
|
||||||
_db_set_(cs, control);
|
if (ParseDbug(cs, control))
|
||||||
|
FixTraceFlags(old_fflags, cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -733,7 +887,7 @@ void _db_set_init_(const char *control)
|
|||||||
CODE_STATE tmp_cs;
|
CODE_STATE tmp_cs;
|
||||||
bzero((uchar*) &tmp_cs, sizeof(tmp_cs));
|
bzero((uchar*) &tmp_cs, sizeof(tmp_cs));
|
||||||
tmp_cs.stack= &init_settings;
|
tmp_cs.stack= &init_settings;
|
||||||
_db_set_(&tmp_cs, control);
|
ParseDbug(&tmp_cs, control);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -756,6 +910,7 @@ void _db_set_init_(const char *control)
|
|||||||
void _db_pop_()
|
void _db_pop_()
|
||||||
{
|
{
|
||||||
struct settings *discard;
|
struct settings *discard;
|
||||||
|
int old_fflags;
|
||||||
CODE_STATE *cs;
|
CODE_STATE *cs;
|
||||||
|
|
||||||
get_code_state_or_return;
|
get_code_state_or_return;
|
||||||
@ -763,8 +918,10 @@ void _db_pop_()
|
|||||||
discard= cs->stack;
|
discard= cs->stack;
|
||||||
if (discard->next != NULL)
|
if (discard->next != NULL)
|
||||||
{
|
{
|
||||||
|
old_fflags=fflags(cs);
|
||||||
cs->stack= discard->next;
|
cs->stack= discard->next;
|
||||||
FreeState(cs, discard, 1);
|
FreeState(cs, discard, 1);
|
||||||
|
FixTraceFlags(old_fflags, cs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -794,7 +951,11 @@ void _db_pop_()
|
|||||||
while (listp) \
|
while (listp) \
|
||||||
{ \
|
{ \
|
||||||
if (listp->flags & (f)) \
|
if (listp->flags & (f)) \
|
||||||
|
{ \
|
||||||
str_to_buf(listp->str); \
|
str_to_buf(listp->str); \
|
||||||
|
if (listp->flags & SUBDIR) \
|
||||||
|
char_to_buf('/'); \
|
||||||
|
} \
|
||||||
listp=listp->next_link; \
|
listp=listp->next_link; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -928,15 +1089,11 @@ int _db_explain_init_(char *buf, size_t len)
|
|||||||
*
|
*
|
||||||
* SYNOPSIS
|
* SYNOPSIS
|
||||||
*
|
*
|
||||||
* VOID _db_enter_(_func_, _file_, _line_,
|
* VOID _db_enter_(_func_, _file_, _line_, _stack_frame_)
|
||||||
* _sfunc_, _sfile_, _slevel_, _sframep_)
|
|
||||||
* char *_func_; points to current function name
|
* char *_func_; points to current function name
|
||||||
* char *_file_; points to current file name
|
* char *_file_; points to current file name
|
||||||
* int _line_; called from source line number
|
* int _line_; called from source line number
|
||||||
* char **_sfunc_; save previous _func_
|
* struct _db_stack_frame_ allocated on the caller's stack
|
||||||
* char **_sfile_; save previous _file_
|
|
||||||
* int *_slevel_; save previous nesting level
|
|
||||||
* char ***_sframep_; save previous frame pointer
|
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
*
|
*
|
||||||
@ -960,54 +1117,60 @@ int _db_explain_init_(char *buf, size_t len)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void _db_enter_(const char *_func_, const char *_file_,
|
void _db_enter_(const char *_func_, const char *_file_,
|
||||||
uint _line_, const char **_sfunc_, const char **_sfile_,
|
uint _line_, struct _db_stack_frame_ *_stack_frame_)
|
||||||
uint *_slevel_, char ***_sframep_ __attribute__((unused)))
|
|
||||||
{
|
{
|
||||||
int save_errno;
|
int save_errno;
|
||||||
CODE_STATE *cs;
|
CODE_STATE *cs;
|
||||||
if (!((cs=code_state())))
|
if (!((cs=code_state())))
|
||||||
{
|
{
|
||||||
*_slevel_= 0; /* Set to avoid valgrind warnings if dbug is enabled later */
|
_stack_frame_->level= 0; /* Set to avoid valgrind warnings if dbug is enabled later */
|
||||||
|
_stack_frame_->prev= 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
save_errno= errno;
|
save_errno= errno;
|
||||||
|
|
||||||
*_sfunc_= cs->func;
|
_stack_frame_->func= cs->func;
|
||||||
*_sfile_= cs->file;
|
_stack_frame_->file= cs->file;
|
||||||
cs->func= _func_;
|
cs->func= _func_;
|
||||||
cs->file= _file_;
|
cs->file= _file_;
|
||||||
*_slevel_= ++cs->level;
|
_stack_frame_->prev= cs->framep;
|
||||||
|
_stack_frame_->level= ++cs->level | framep_trace_flag(cs, cs->framep);
|
||||||
|
cs->framep= _stack_frame_;
|
||||||
#ifndef THREAD
|
#ifndef THREAD
|
||||||
*_sframep_= cs->framep;
|
|
||||||
cs->framep= (char **) _sframep_;
|
|
||||||
if (DoProfile(cs))
|
if (DoProfile(cs))
|
||||||
{
|
{
|
||||||
long stackused;
|
long stackused;
|
||||||
if (*cs->framep == NULL)
|
if (cs->framep->prev == NULL)
|
||||||
stackused= 0;
|
stackused= 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stackused= ((long)(*cs->framep)) - ((long)(cs->framep));
|
stackused= (char*)(cs->framep->prev) - (char*)(cs->framep);
|
||||||
stackused= stackused > 0 ? stackused : -stackused;
|
stackused= stackused > 0 ? stackused : -stackused;
|
||||||
}
|
}
|
||||||
(void) fprintf(cs->stack->prof_file, PROF_EFMT , Clock(), cs->func);
|
(void) fprintf(cs->stack->prof_file, PROF_EFMT , Clock(), cs->func);
|
||||||
#ifdef AUTOS_REVERSE
|
|
||||||
(void) fprintf(cs->stack->prof_file, PROF_SFMT, cs->framep, stackused, *_sfunc_);
|
|
||||||
#else
|
|
||||||
(void) fprintf(cs->stack->prof_file, PROF_SFMT, (ulong) cs->framep, stackused,
|
(void) fprintf(cs->stack->prof_file, PROF_SFMT, (ulong) cs->framep, stackused,
|
||||||
cs->func);
|
AUTOS_REVERSE ? _stack_frame_->func : cs->func);
|
||||||
#endif
|
|
||||||
(void) fflush(cs->stack->prof_file);
|
(void) fflush(cs->stack->prof_file);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (DoTrace(cs))
|
switch (DoTrace(cs, TRACING)) {
|
||||||
{
|
case ENABLE_TRACE:
|
||||||
|
cs->framep->level|= TRACE_ON;
|
||||||
|
if (!TRACING) break;
|
||||||
|
/* fall through */
|
||||||
|
case DO_TRACE:
|
||||||
if (!cs->locked)
|
if (!cs->locked)
|
||||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||||
DoPrefix(cs, _line_);
|
DoPrefix(cs, _line_);
|
||||||
Indent(cs, cs->level);
|
Indent(cs, cs->level);
|
||||||
(void) fprintf(cs->stack->out_file, ">%s\n", cs->func);
|
(void) fprintf(cs->stack->out_file, ">%s\n", cs->func);
|
||||||
dbug_flush(cs); /* This does a unlock */
|
dbug_flush(cs); /* This does a unlock */
|
||||||
|
break;
|
||||||
|
case DISABLE_TRACE:
|
||||||
|
cs->framep->level&= ~TRACE_ON;
|
||||||
|
/* fall through */
|
||||||
|
case DONT_TRACE:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#ifdef SAFEMALLOC
|
#ifdef SAFEMALLOC
|
||||||
if (cs->stack->flags & SANITY_CHECK_ON)
|
if (cs->stack->flags & SANITY_CHECK_ON)
|
||||||
@ -1024,11 +1187,9 @@ void _db_enter_(const char *_func_, const char *_file_,
|
|||||||
*
|
*
|
||||||
* SYNOPSIS
|
* SYNOPSIS
|
||||||
*
|
*
|
||||||
* VOID _db_return_(_line_, _sfunc_, _sfile_, _slevel_)
|
* VOID _db_return_(_line_, _stack_frame_)
|
||||||
* int _line_; current source line number
|
* int _line_; current source line number
|
||||||
* char **_sfunc_; where previous _func_ is to be retrieved
|
* struct _db_stack_frame_ allocated on the caller's stack
|
||||||
* char **_sfile_; where previous _file_ is to be retrieved
|
|
||||||
* int *_slevel_; where previous level was stashed
|
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
*
|
*
|
||||||
@ -1040,14 +1201,14 @@ void _db_enter_(const char *_func_, const char *_file_,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* helper macro */
|
/* helper macro */
|
||||||
void _db_return_(uint _line_, const char **_sfunc_,
|
void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_)
|
||||||
const char **_sfile_, uint *_slevel_)
|
|
||||||
{
|
{
|
||||||
int save_errno=errno;
|
int save_errno=errno;
|
||||||
|
int _slevel_=_stack_frame_->level & ~TRACE_ON;
|
||||||
CODE_STATE *cs;
|
CODE_STATE *cs;
|
||||||
get_code_state_or_return;
|
get_code_state_or_return;
|
||||||
|
|
||||||
if (cs->level != (int) *_slevel_)
|
if (cs->level != _slevel_)
|
||||||
{
|
{
|
||||||
if (!cs->locked)
|
if (!cs->locked)
|
||||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||||
@ -1060,7 +1221,7 @@ void _db_return_(uint _line_, const char **_sfunc_,
|
|||||||
#ifdef SAFEMALLOC
|
#ifdef SAFEMALLOC
|
||||||
if (cs->stack->flags & SANITY_CHECK_ON)
|
if (cs->stack->flags & SANITY_CHECK_ON)
|
||||||
{
|
{
|
||||||
if (_sanity(*_sfile_,_line_))
|
if (_sanity(_stack_frame_->file,_line_))
|
||||||
cs->stack->flags &= ~SANITY_CHECK_ON;
|
cs->stack->flags &= ~SANITY_CHECK_ON;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1068,7 +1229,7 @@ void _db_return_(uint _line_, const char **_sfunc_,
|
|||||||
if (DoProfile(cs))
|
if (DoProfile(cs))
|
||||||
(void) fprintf(cs->stack->prof_file, PROF_XFMT, Clock(), cs->func);
|
(void) fprintf(cs->stack->prof_file, PROF_XFMT, Clock(), cs->func);
|
||||||
#endif
|
#endif
|
||||||
if (DoTrace(cs))
|
if (TRACING && DoTrace(cs, 1) & DO_TRACE)
|
||||||
{
|
{
|
||||||
if (!cs->locked)
|
if (!cs->locked)
|
||||||
pthread_mutex_lock(&THR_LOCK_dbug);
|
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||||
@ -1082,13 +1243,11 @@ void _db_return_(uint _line_, const char **_sfunc_,
|
|||||||
Check to not set level < 0. This can happen if DBUG was disabled when
|
Check to not set level < 0. This can happen if DBUG was disabled when
|
||||||
function was entered and enabled in function.
|
function was entered and enabled in function.
|
||||||
*/
|
*/
|
||||||
cs->level= *_slevel_ != 0 ? *_slevel_-1 : 0;
|
cs->level= _slevel_ != 0 ? _slevel_ - 1 : 0;
|
||||||
cs->func= *_sfunc_;
|
cs->func= _stack_frame_->func;
|
||||||
cs->file= *_sfile_;
|
cs->file= _stack_frame_->file;
|
||||||
#ifndef THREAD
|
|
||||||
if (cs->framep != NULL)
|
if (cs->framep != NULL)
|
||||||
cs->framep= (char **) *cs->framep;
|
cs->framep= cs->framep->prev;
|
||||||
#endif
|
|
||||||
errno=save_errno;
|
errno=save_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1252,13 +1411,13 @@ void _db_dump_(uint _line_, const char *keyword,
|
|||||||
*
|
*
|
||||||
* The mode of operation is defined by "todo" parameter.
|
* The mode of operation is defined by "todo" parameter.
|
||||||
*
|
*
|
||||||
* If it's INCLUDE, elements (strings from "cltp") are added to the
|
* If it is INCLUDE, elements (strings from "cltp") are added to the
|
||||||
* list, they'll have INCLUDE flag set. If the list already contains
|
* list, they will have INCLUDE flag set. If the list already contains
|
||||||
* the string in question, new element is not added, but a flag of
|
* the string in question, new element is not added, but a flag of
|
||||||
* the existing element is adjusted (INCLUDE bit is set, EXCLUDE bit
|
* the existing element is adjusted (INCLUDE bit is set, EXCLUDE bit
|
||||||
* is removed).
|
* is removed).
|
||||||
*
|
*
|
||||||
* If it's EXCLUDE, elements are added to the list with the EXCLUDE
|
* If it is EXCLUDE, elements are added to the list with the EXCLUDE
|
||||||
* flag set. If the list already contains the string in question,
|
* flag set. If the list already contains the string in question,
|
||||||
* it is removed, new element is not added.
|
* it is removed, new element is not added.
|
||||||
*/
|
*/
|
||||||
@ -1268,16 +1427,22 @@ static struct link *ListAddDel(struct link *head, const char *ctlp,
|
|||||||
{
|
{
|
||||||
const char *start;
|
const char *start;
|
||||||
struct link **cur;
|
struct link **cur;
|
||||||
int len;
|
int len, subdir;
|
||||||
|
|
||||||
ctlp--;
|
ctlp--;
|
||||||
next:
|
next:
|
||||||
while (++ctlp < end)
|
while (++ctlp < end)
|
||||||
{
|
{
|
||||||
start= ctlp;
|
start= ctlp;
|
||||||
|
subdir=0;
|
||||||
while (ctlp < end && *ctlp != ',')
|
while (ctlp < end && *ctlp != ',')
|
||||||
ctlp++;
|
ctlp++;
|
||||||
len=ctlp-start;
|
len=ctlp-start;
|
||||||
|
if (start[len-1] == '/')
|
||||||
|
{
|
||||||
|
len--;
|
||||||
|
subdir=SUBDIR;
|
||||||
|
}
|
||||||
if (len == 0) continue;
|
if (len == 0) continue;
|
||||||
for (cur=&head; *cur; cur=&((*cur)->next_link))
|
for (cur=&head; *cur; cur=&((*cur)->next_link))
|
||||||
{
|
{
|
||||||
@ -1291,8 +1456,8 @@ next:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(*cur)->flags&=~EXCLUDE;
|
(*cur)->flags&=~(EXCLUDE & SUBDIR);
|
||||||
(*cur)->flags|=INCLUDE;
|
(*cur)->flags|=INCLUDE | subdir;
|
||||||
}
|
}
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
@ -1300,7 +1465,7 @@ next:
|
|||||||
*cur= (struct link *) DbugMalloc(sizeof(struct link)+len);
|
*cur= (struct link *) DbugMalloc(sizeof(struct link)+len);
|
||||||
memcpy((*cur)->str, start, len);
|
memcpy((*cur)->str, start, len);
|
||||||
(*cur)->str[len]=0;
|
(*cur)->str[len]=0;
|
||||||
(*cur)->flags=todo;
|
(*cur)->flags=todo | subdir;
|
||||||
(*cur)->next_link=0;
|
(*cur)->next_link=0;
|
||||||
}
|
}
|
||||||
return head;
|
return head;
|
||||||
@ -1355,12 +1520,6 @@ static struct link *ListCopy(struct link *orig)
|
|||||||
*
|
*
|
||||||
* InList test a given string for member of a given list
|
* InList test a given string for member of a given list
|
||||||
*
|
*
|
||||||
* SYNOPSIS
|
|
||||||
*
|
|
||||||
* static int InList(linkp, cp)
|
|
||||||
* struct link *linkp;
|
|
||||||
* char *cp;
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
*
|
*
|
||||||
* Tests the string pointed to by "cp" to determine if it is in
|
* Tests the string pointed to by "cp" to determine if it is in
|
||||||
@ -1373,9 +1532,7 @@ static struct link *ListCopy(struct link *orig)
|
|||||||
* is a list, only those strings in the list will be accepted.
|
* is a list, only those strings in the list will be accepted.
|
||||||
*
|
*
|
||||||
* RETURN
|
* RETURN
|
||||||
* 0 - not in the list (or matched an EXCLUDE element)
|
* combination of SUBDIR, INCLUDE, EXCLUDE, MATCHED flags
|
||||||
* 1 - in the list by default (list is empty or only has EXCLUDE elements)
|
|
||||||
* 2 - in the list explictly (matched an INCLUDE element)
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1383,12 +1540,14 @@ static int InList(struct link *linkp, const char *cp)
|
|||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
for (result=1; linkp != NULL; linkp= linkp->next_link)
|
for (result=MATCHED; linkp != NULL; linkp= linkp->next_link)
|
||||||
{
|
{
|
||||||
if (!strcmp(linkp->str, cp))
|
if (!strcmp(linkp->str, cp))
|
||||||
return linkp->flags & EXCLUDE ? 0 : 2;
|
return linkp->flags;
|
||||||
if (!(linkp->flags & EXCLUDE))
|
if (!(linkp->flags & EXCLUDE))
|
||||||
result=0;
|
result=NOT_MATCHED;
|
||||||
|
if (linkp->flags & SUBDIR)
|
||||||
|
result|=SUBDIR;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1535,25 +1694,34 @@ void _db_end_()
|
|||||||
*
|
*
|
||||||
* DoTrace check to see if tracing is current enabled
|
* DoTrace check to see if tracing is current enabled
|
||||||
*
|
*
|
||||||
* SYNOPSIS
|
* tracing is the value of TRACING to check if the tracing is enabled
|
||||||
*
|
* or 1 to check if the function is enabled (in _db_keyword_)
|
||||||
* static BOOLEAN DoTrace(stack)
|
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
*
|
*
|
||||||
* Checks to see if tracing is enabled based on whether the
|
* Checks to see if tracing is enabled based on whether the
|
||||||
* user has specified tracing, the maximum trace depth has
|
* user has specified tracing, the maximum trace depth has
|
||||||
* not yet been reached, the current function is selected,
|
* not yet been reached, the current function is selected,
|
||||||
* and the current process is selected. Returns TRUE if
|
* and the current process is selected.
|
||||||
* tracing is enabled, FALSE otherwise.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static BOOLEAN DoTrace(CODE_STATE *cs)
|
static int DoTrace(CODE_STATE *cs, int tracing)
|
||||||
{
|
{
|
||||||
return (TRACING && cs->level <= cs->stack->maxdepth &&
|
if ((cs->stack->maxdepth == 0 || cs->level <= cs->stack->maxdepth) &&
|
||||||
InList(cs->stack->functions, cs->func) &&
|
InList(cs->stack->processes, cs->process) & (MATCHED|INCLUDE))
|
||||||
InList(cs->stack->processes, cs->process));
|
switch(InList(cs->stack->functions, cs->func)) {
|
||||||
|
case INCLUDE|SUBDIR: return ENABLE_TRACE;
|
||||||
|
case INCLUDE: return tracing ? DO_TRACE : DONT_TRACE;
|
||||||
|
case MATCHED|SUBDIR:
|
||||||
|
case NOT_MATCHED|SUBDIR:
|
||||||
|
case MATCHED: return tracing && framep_trace_flag(cs, cs->framep) ?
|
||||||
|
DO_TRACE : DONT_TRACE;
|
||||||
|
case EXCLUDE:
|
||||||
|
case NOT_MATCHED: return DONT_TRACE;
|
||||||
|
case EXCLUDE|SUBDIR: return DISABLE_TRACE;
|
||||||
|
}
|
||||||
|
return DONT_TRACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1581,8 +1749,8 @@ static BOOLEAN DoProfile(CODE_STATE *cs)
|
|||||||
{
|
{
|
||||||
return PROFILING &&
|
return PROFILING &&
|
||||||
cs->level <= cs->stack->maxdepth &&
|
cs->level <= cs->stack->maxdepth &&
|
||||||
InList(cs->stack->p_functions, cs->func) &&
|
InList(cs->stack->p_functions, cs->func) & (INCLUDE|MATCHED) &&
|
||||||
InList(cs->stack->processes, cs->process);
|
InList(cs->stack->processes, cs->process) & (INCLUDE|MATCHED);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1616,12 +1784,10 @@ FILE *_db_fp_(void)
|
|||||||
BOOLEAN _db_keyword_(CODE_STATE *cs, const char *keyword, int strict)
|
BOOLEAN _db_keyword_(CODE_STATE *cs, const char *keyword, int strict)
|
||||||
{
|
{
|
||||||
get_code_state_if_not_set_or_return FALSE;
|
get_code_state_if_not_set_or_return FALSE;
|
||||||
|
strict=strict ? INCLUDE : INCLUDE|MATCHED;
|
||||||
|
|
||||||
return (DEBUGGING &&
|
return DEBUGGING && DoTrace(cs, 1) & DO_TRACE &&
|
||||||
(!TRACING || cs->level <= cs->stack->maxdepth) &&
|
InList(cs->stack->keywords, keyword) & strict;
|
||||||
InList(cs->stack->functions, cs->func) &&
|
|
||||||
InList(cs->stack->keywords, keyword) > (strict != 0) &&
|
|
||||||
InList(cs->stack->processes, cs->process));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
318
dbug/tests-t.pl
318
dbug/tests-t.pl
@ -12,8 +12,10 @@ die unless $exe =~ s/(tests)-t(\.exe)?$/$1$2 /;
|
|||||||
# load tests
|
# load tests
|
||||||
@tests=();
|
@tests=();
|
||||||
while (<DATA>) {
|
while (<DATA>) {
|
||||||
if (/^% tests /) {
|
if (/^% \.\/tests /) {
|
||||||
push @tests, [ $' ]
|
push @tests, [ $' ]
|
||||||
|
} elsif (/^#/) {
|
||||||
|
next;
|
||||||
} else {
|
} else {
|
||||||
push @{$tests[$#tests]}, $_
|
push @{$tests[$#tests]}, $_
|
||||||
}
|
}
|
||||||
@ -36,24 +38,27 @@ for (@tests) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__DATA__
|
__DATA__
|
||||||
% tests -#d
|
% ./tests -#d
|
||||||
func2: info: s=ok
|
|
||||||
func2: info: s=ok
|
func2: info: s=ok
|
||||||
=> execute
|
=> execute
|
||||||
=> evaluate: ON
|
=> evaluate: ON
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
main: explain: dbug explained: d
|
main: explain: dbug explained: d
|
||||||
% tests -#d,ret3
|
func2: info: s=ok
|
||||||
|
% ./tests d,ret3
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
% tests -#d:-d,ret3
|
#
|
||||||
func2: info: s=ko
|
## Testing negative lists
|
||||||
|
#
|
||||||
|
% ./tests d:-d,ret3
|
||||||
func2: info: s=ko
|
func2: info: s=ko
|
||||||
=> execute
|
=> execute
|
||||||
=> evaluate: ON
|
=> evaluate: ON
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
main: explain: dbug explained: d:-d,ret3
|
main: explain: dbug explained: d:-d,ret3
|
||||||
% tests -#t:-d,ret3
|
func2: info: s=ko
|
||||||
|
% ./tests t:-d,ret3
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | >func2
|
| | >func2
|
||||||
@ -61,14 +66,14 @@ main: explain: dbug explained: d:-d,ret3
|
|||||||
| | | <func3
|
| | | <func3
|
||||||
| | <func2
|
| | <func2
|
||||||
| <func1
|
| <func1
|
||||||
|
=> evaluate: OFF
|
||||||
|
=> evaluate_if: OFF
|
||||||
| >func2
|
| >func2
|
||||||
| | >func3
|
| | >func3
|
||||||
| | <func3
|
| | <func3
|
||||||
| <func2
|
| <func2
|
||||||
=> evaluate: OFF
|
|
||||||
=> evaluate_if: OFF
|
|
||||||
<main
|
<main
|
||||||
% tests -#t:d,info:-d,ret3
|
% ./tests t:d,info:-d,ret3
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | >func2
|
| | >func2
|
||||||
@ -77,159 +82,168 @@ main: explain: dbug explained: d:-d,ret3
|
|||||||
| | | info: s=ko
|
| | | info: s=ko
|
||||||
| | <func2
|
| | <func2
|
||||||
| <func1
|
| <func1
|
||||||
|
=> evaluate: OFF
|
||||||
|
=> evaluate_if: OFF
|
||||||
| >func2
|
| >func2
|
||||||
| | >func3
|
| | >func3
|
||||||
| | <func3
|
| | <func3
|
||||||
| | info: s=ko
|
| | info: s=ko
|
||||||
| <func2
|
| <func2
|
||||||
=> evaluate: OFF
|
|
||||||
=> evaluate_if: OFF
|
|
||||||
<main
|
<main
|
||||||
% tests -#t:d,info:-d,ret3:-f,func2
|
% ./tests t:d,info:-d,ret3:-f,func2
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | | >func3
|
| | | >func3
|
||||||
| | | <func3
|
| | | <func3
|
||||||
| <func1
|
| <func1
|
||||||
| | >func3
|
|
||||||
| | <func3
|
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
<main
|
<main
|
||||||
% tests -#t:d,info:-d,ret3:-f,func2 d,evaluate
|
% ./tests t:d,info:-d,ret3:-f,func2 d,evaluate
|
||||||
=> evaluate: ON
|
=> evaluate: ON
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
% tests -#t:d,info:-d,ret3:-f,func2 d,evaluate_if
|
% ./tests t:d,info:-d,ret3:-f,func2 d,evaluate_if
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: ON
|
=> evaluate_if: ON
|
||||||
% tests -#t:d:-d,ret3:-f,func2 d,evaluate_if
|
% ./tests t:d:-d,ret3:-f,func2 d,evaluate_if
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: ON
|
=> evaluate_if: ON
|
||||||
% tests -#t:d:-d,ret3:-f,func2 +d,evaluate_if
|
% ./tests t:d:-d,ret3:-f,func2
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | | >func3
|
| | | >func3
|
||||||
| | | <func3
|
| | | <func3
|
||||||
| <func1
|
| <func1
|
||||||
| | >func3
|
|
||||||
| | <func3
|
|
||||||
=> evaluate: OFF
|
|
||||||
=> evaluate_if: ON
|
|
||||||
<main
|
|
||||||
% tests -#t:d:-d,ret3:-f,func2
|
|
||||||
>main
|
|
||||||
| >func1
|
|
||||||
| | | >func3
|
|
||||||
| | | <func3
|
|
||||||
| <func1
|
|
||||||
| | >func3
|
|
||||||
| | <func3
|
|
||||||
=> execute
|
=> execute
|
||||||
=> evaluate: ON
|
=> evaluate: ON
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
| explain: dbug explained: d:-d,ret3:f:-f,func2:t
|
| explain: dbug explained: d:-d,ret3:f:-f,func2:t
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
<main
|
<main
|
||||||
% tests -#t:d:-d,ret3:f:-f,func2 -#+d,dump
|
#
|
||||||
|
## Adding incremental settings to the brew
|
||||||
|
#
|
||||||
|
% ./tests t:d:-d,ret3:-f,func2 +d,evaluate_if
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | | >func3
|
| | | >func3
|
||||||
| | | <func3
|
| | | <func3
|
||||||
| <func1
|
| <func1
|
||||||
|
=> evaluate: OFF
|
||||||
|
=> evaluate_if: ON
|
||||||
| | >func3
|
| | >func3
|
||||||
| | <func3
|
| | <func3
|
||||||
|
<main
|
||||||
|
#
|
||||||
|
## DBUG_DUMP
|
||||||
|
#
|
||||||
|
% ./tests t:d:-d,ret3:f:-f,func2 +d,dump
|
||||||
|
>main
|
||||||
|
| >func1
|
||||||
|
| | | >func3
|
||||||
|
| | | <func3
|
||||||
|
| <func1
|
||||||
| dump: Memory: 0x#### Bytes: (27)
|
| dump: Memory: 0x#### Bytes: (27)
|
||||||
64 2C 64 75 6D 70 3A 2D 64 2C 72 65 74 33 3A 66 3A 2D 66 2C 66 75 6E 63 32 3A
|
64 2C 64 75 6D 70 3A 2D 64 2C 72 65 74 33 3A 66 3A 2D 66 2C 66 75 6E 63 32 3A
|
||||||
74
|
74
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
<main
|
<main
|
||||||
% tests -#t:d:-d,ret3:f:-f,func2 +d,dump
|
% ./tests t:d:-d,ret3:f:-f,func2 +d,dump
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | | >func3
|
| | | >func3
|
||||||
| | | <func3
|
| | | <func3
|
||||||
| <func1
|
| <func1
|
||||||
| | >func3
|
|
||||||
| | <func3
|
|
||||||
| dump: Memory: 0x#### Bytes: (27)
|
| dump: Memory: 0x#### Bytes: (27)
|
||||||
64 2C 64 75 6D 70 3A 2D 64 2C 72 65 74 33 3A 66 3A 2D 66 2C 66 75 6E 63 32 3A
|
64 2C 64 75 6D 70 3A 2D 64 2C 72 65 74 33 3A 66 3A 2D 66 2C 66 75 6E 63 32 3A
|
||||||
74
|
74
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
<main
|
<main
|
||||||
% tests -#t:d:-d,ret3:f:-f,func2:+d,dump
|
% ./tests t:d:-d,ret3:f:-f,func2:+d,dump
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | | >func3
|
| | | >func3
|
||||||
| | | <func3
|
| | | <func3
|
||||||
| <func1
|
| <func1
|
||||||
| | >func3
|
|
||||||
| | <func3
|
|
||||||
| dump: Memory: 0x#### Bytes: (27)
|
| dump: Memory: 0x#### Bytes: (27)
|
||||||
64 2C 64 75 6D 70 3A 2D 64 2C 72 65 74 33 3A 66 3A 2D 66 2C 66 75 6E 63 32 3A
|
64 2C 64 75 6D 70 3A 2D 64 2C 72 65 74 33 3A 66 3A 2D 66 2C 66 75 6E 63 32 3A
|
||||||
74
|
74
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
<main
|
<main
|
||||||
% tests -#t:d:-d,ret3:f:-f,func2 +d,dump,explain
|
% ./tests t:d:-d,ret3:f:-f,func2 +d,dump,explain
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | | >func3
|
| | | >func3
|
||||||
| | | <func3
|
| | | <func3
|
||||||
| <func1
|
| <func1
|
||||||
| | >func3
|
|
||||||
| | <func3
|
|
||||||
| dump: Memory: 0x#### Bytes: (35)
|
| dump: Memory: 0x#### Bytes: (35)
|
||||||
64 2C 64 75 6D 70 2C 65 78 70 6C 61 69 6E 3A 2D 64 2C 72 65 74 33 3A 66 3A 2D
|
64 2C 64 75 6D 70 2C 65 78 70 6C 61 69 6E 3A 2D 64 2C 72 65 74 33 3A 66 3A 2D
|
||||||
66 2C 66 75 6E 63 32 3A 74
|
66 2C 66 75 6E 63 32 3A 74
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
| explain: dbug explained: d,dump,explain:-d,ret3:f:-f,func2:t
|
| explain: dbug explained: d,dump,explain:-d,ret3:f:-f,func2:t
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
<main
|
<main
|
||||||
% tests -#t:d:-d,ret3:f:-f,func2 +d,dump,explain:P
|
% ./tests t:d:-d,ret3:f:-f,func2 +d,dump,explain:P
|
||||||
dbug: >main
|
dbug: >main
|
||||||
dbug-tests: | >func1
|
dbug-tests: | >func1
|
||||||
dbug-tests: | | | >func3
|
dbug-tests: | | | >func3
|
||||||
dbug-tests: | | | <func3
|
dbug-tests: | | | <func3
|
||||||
dbug-tests: | <func1
|
dbug-tests: | <func1
|
||||||
dbug-tests: | | >func3
|
|
||||||
dbug-tests: | | <func3
|
|
||||||
dbug-tests: | dump: Memory: 0x#### Bytes: (37)
|
dbug-tests: | dump: Memory: 0x#### Bytes: (37)
|
||||||
64 2C 64 75 6D 70 2C 65 78 70 6C 61 69 6E 3A 2D 64 2C 72 65 74 33 3A 66 3A 2D
|
64 2C 64 75 6D 70 2C 65 78 70 6C 61 69 6E 3A 2D 64 2C 72 65 74 33 3A 66 3A 2D
|
||||||
66 2C 66 75 6E 63 32 3A 50 3A 74
|
66 2C 66 75 6E 63 32 3A 50 3A 74
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
dbug-tests: | explain: dbug explained: d,dump,explain:-d,ret3:f:-f,func2:P:t
|
dbug-tests: | explain: dbug explained: d,dump,explain:-d,ret3:f:-f,func2:P:t
|
||||||
|
dbug-tests: | | >func3
|
||||||
|
dbug-tests: | | <func3
|
||||||
dbug-tests: <main
|
dbug-tests: <main
|
||||||
% tests -#t:d:-d,ret3:f:-f,func2 +d,dump,explain:P:F
|
% ./tests t:d:-d,ret3:f:-f,func2 +d,dump,explain:P:F
|
||||||
dbug: tests.c: >main
|
dbug: tests.c: >main
|
||||||
dbug-tests: tests.c: | >func1
|
dbug-tests: tests.c: | >func1
|
||||||
dbug-tests: tests.c: | | | >func3
|
dbug-tests: tests.c: | | | >func3
|
||||||
dbug-tests: tests.c: | | | <func3
|
dbug-tests: tests.c: | | | <func3
|
||||||
dbug-tests: tests.c: | <func1
|
dbug-tests: tests.c: | <func1
|
||||||
dbug-tests: tests.c: | | >func3
|
|
||||||
dbug-tests: tests.c: | | <func3
|
|
||||||
dbug-tests: tests.c: | dump: Memory: 0x#### Bytes: (39)
|
dbug-tests: tests.c: | dump: Memory: 0x#### Bytes: (39)
|
||||||
64 2C 64 75 6D 70 2C 65 78 70 6C 61 69 6E 3A 2D 64 2C 72 65 74 33 3A 66 3A 2D
|
64 2C 64 75 6D 70 2C 65 78 70 6C 61 69 6E 3A 2D 64 2C 72 65 74 33 3A 66 3A 2D
|
||||||
66 2C 66 75 6E 63 32 3A 46 3A 50 3A 74
|
66 2C 66 75 6E 63 32 3A 46 3A 50 3A 74
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
dbug-tests: tests.c: | explain: dbug explained: d,dump,explain:-d,ret3:f:-f,func2:F:P:t
|
dbug-tests: tests.c: | explain: dbug explained: d,dump,explain:-d,ret3:f:-f,func2:F:P:t
|
||||||
|
dbug-tests: tests.c: | | >func3
|
||||||
|
dbug-tests: tests.c: | | <func3
|
||||||
dbug-tests: tests.c: <main
|
dbug-tests: tests.c: <main
|
||||||
% tests -#t:d:-d,ret3:f:-f,func2
|
#
|
||||||
|
## DBUG_EXPLAIN, DBUG_PUSH, DBUG_POP, DBUG_SET
|
||||||
|
#
|
||||||
|
% ./tests t:d:-d,ret3:f:-f,func2
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | | >func3
|
| | | >func3
|
||||||
| | | <func3
|
| | | <func3
|
||||||
| <func1
|
| <func1
|
||||||
| | >func3
|
|
||||||
| | <func3
|
|
||||||
=> execute
|
=> execute
|
||||||
=> evaluate: ON
|
=> evaluate: ON
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
| explain: dbug explained: d:-d,ret3:f:-f,func2:t
|
| explain: dbug explained: d:-d,ret3:f:-f,func2:t
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
<main
|
<main
|
||||||
% tests -#t:d:-d,ret3
|
% ./tests t:d:-d,ret3
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | >func2
|
| | >func2
|
||||||
@ -238,58 +252,48 @@ dbug-tests: tests.c: <main
|
|||||||
| | | info: s=ko
|
| | | info: s=ko
|
||||||
| | <func2
|
| | <func2
|
||||||
| <func1
|
| <func1
|
||||||
| >func2
|
|
||||||
| | >func3
|
|
||||||
| | <func3
|
|
||||||
| | info: s=ko
|
|
||||||
| <func2
|
|
||||||
=> execute
|
=> execute
|
||||||
=> evaluate: ON
|
=> evaluate: ON
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
| explain: dbug explained: d:-d,ret3:t
|
| explain: dbug explained: d:-d,ret3:t
|
||||||
<main
|
|
||||||
% tests -#t:d,info:-d,ret3:d,push
|
|
||||||
>main
|
|
||||||
| >func1
|
|
||||||
| | >func2
|
|
||||||
| | | >func3
|
|
||||||
| | | <func3
|
|
||||||
| | | info: s=ko
|
|
||||||
| | <func2
|
|
||||||
| <func1
|
|
||||||
| >func2
|
| >func2
|
||||||
| | >func3
|
| | >func3
|
||||||
| | <func3
|
| | <func3
|
||||||
| | info: s=ko
|
| | info: s=ko
|
||||||
| <func2
|
| <func2
|
||||||
=> evaluate: OFF
|
|
||||||
=> evaluate_if: OFF
|
|
||||||
<main
|
<main
|
||||||
% tests -#d,info:-d,ret3:d,push
|
% ./tests d,info:-d,ret3:d,push
|
||||||
func2: info: s=ko
|
|
||||||
func2: info: s=ko
|
func2: info: s=ko
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
|
| >func2
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
|
| | info: s=ko
|
||||||
|
| <func2
|
||||||
<main
|
<main
|
||||||
% tests -#d,info:-d,ret3:d,push,explain
|
% ./tests d,info:-d,ret3:d,push,explain
|
||||||
func2: info: s=ko
|
|
||||||
func2: info: s=ko
|
func2: info: s=ko
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
| explain: dbug explained: d,info,push,explain:-d,ret3:t
|
| explain: dbug explained: d,info,push,explain:-d,ret3:t
|
||||||
|
| >func2
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
|
| | info: s=ko
|
||||||
|
| <func2
|
||||||
<main
|
<main
|
||||||
% tests -#d,info:-d,ret3:d,explain
|
% ./tests d,info:-d,ret3:d,explain
|
||||||
func2: info: s=ko
|
|
||||||
func2: info: s=ko
|
func2: info: s=ko
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
main: explain: dbug explained: d,info,explain:-d,ret3
|
main: explain: dbug explained: d,info,explain:-d,ret3
|
||||||
% tests -#d,info:-d,ret3:d,explain,pop
|
|
||||||
func2: info: s=ko
|
func2: info: s=ko
|
||||||
|
% ./tests d,info:-d,ret3:d,explain,pop
|
||||||
func2: info: s=ko
|
func2: info: s=ko
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
% tests -#d,info:-d,ret3:d,explain,pop t
|
% ./tests d,info:-d,ret3:d,explain t:d,pop
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | >func2
|
| | >func2
|
||||||
@ -297,14 +301,11 @@ func2: info: s=ko
|
|||||||
| | | <func3
|
| | | <func3
|
||||||
| | <func2
|
| | <func2
|
||||||
| <func1
|
| <func1
|
||||||
| >func2
|
|
||||||
| | >func3
|
|
||||||
| | <func3
|
|
||||||
| <func2
|
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
<main
|
main: explain: dbug explained: d,info,explain:-d,ret3
|
||||||
% tests -#d,info:-d,ret3:d,explain,pop +t
|
func2: info: s=ko
|
||||||
|
% ./tests d,info:-d,ret3:d,explain,pop +t
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | >func2
|
| | >func2
|
||||||
@ -313,21 +314,17 @@ func2: info: s=ko
|
|||||||
| | | info: s=ko
|
| | | info: s=ko
|
||||||
| | <func2
|
| | <func2
|
||||||
| <func1
|
| <func1
|
||||||
| >func2
|
|
||||||
| | >func3
|
|
||||||
| | <func3
|
|
||||||
| | info: s=ko
|
|
||||||
| <func2
|
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
main: explain: dbug explained: d,info,explain,pop:-d,ret3
|
main: explain: dbug explained: d,info,explain,pop:-d,ret3
|
||||||
% tests -#d,info:-d,ret3:d,explain,set
|
|
||||||
func2: info: s=ko
|
func2: info: s=ko
|
||||||
|
% ./tests d,info:-d,ret3:d,explain,set
|
||||||
func2: info: s=ko
|
func2: info: s=ko
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
tests.c: main: explain: dbug explained: d,info,explain,set:-d,ret3:F
|
tests.c: main: explain: dbug explained: d,info,explain,set:-d,ret3:F
|
||||||
% tests -#d,info:-d,ret3:d,explain,set:t
|
tests.c: func2: info: s=ko
|
||||||
|
% ./tests d,info:-d,ret3:d,explain,set:t
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | >func2
|
| | >func2
|
||||||
@ -336,16 +333,16 @@ func2: info: s=ko
|
|||||||
| | | info: s=ko
|
| | | info: s=ko
|
||||||
| | <func2
|
| | <func2
|
||||||
| <func1
|
| <func1
|
||||||
| >func2
|
|
||||||
| | >func3
|
|
||||||
| | <func3
|
|
||||||
| | info: s=ko
|
|
||||||
| <func2
|
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
tests.c: | explain: dbug explained: d,info,explain,set:-d,ret3:F:t
|
tests.c: | explain: dbug explained: d,info,explain,set:-d,ret3:F:t
|
||||||
|
tests.c: | >func2
|
||||||
|
tests.c: | | >func3
|
||||||
|
tests.c: | | <func3
|
||||||
|
tests.c: | | info: s=ko
|
||||||
|
tests.c: | <func2
|
||||||
tests.c: <main
|
tests.c: <main
|
||||||
% tests t -#d,info:-d,ret3:d,explain,set:t
|
% ./tests t d,info:-d,ret3:d,explain,set:t
|
||||||
>main
|
>main
|
||||||
| >func1
|
| >func1
|
||||||
| | >func2
|
| | >func2
|
||||||
@ -354,18 +351,133 @@ func2: info: s=ko
|
|||||||
| | | info: s=ko
|
| | | info: s=ko
|
||||||
| | <func2
|
| | <func2
|
||||||
| <func1
|
| <func1
|
||||||
| >func2
|
|
||||||
| | >func3
|
|
||||||
| | <func3
|
|
||||||
| | info: s=ko
|
|
||||||
| <func2
|
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
tests.c: | explain: dbug explained: d,info,explain,set:-d,ret3:F:t
|
tests.c: | explain: dbug explained: d,info,explain,set:-d,ret3:F:t
|
||||||
|
tests.c: | >func2
|
||||||
|
tests.c: | | >func3
|
||||||
|
tests.c: | | <func3
|
||||||
|
tests.c: | | info: s=ko
|
||||||
|
tests.c: | <func2
|
||||||
tests.c: <main
|
tests.c: <main
|
||||||
% tests t -#d,info:-d,ret3:d,explain,set,pop
|
% ./tests t d,info:-d,ret3:d,explain,set,pop
|
||||||
func2: info: s=ko
|
|
||||||
func2: info: s=ko
|
func2: info: s=ko
|
||||||
=> evaluate: OFF
|
=> evaluate: OFF
|
||||||
=> evaluate_if: OFF
|
=> evaluate_if: OFF
|
||||||
|
| >func2
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
|
| <func2
|
||||||
|
<main
|
||||||
|
% ./tests t:f,func2
|
||||||
|
| | >func2
|
||||||
|
| | <func2
|
||||||
|
=> evaluate: OFF
|
||||||
|
=> evaluate_if: OFF
|
||||||
|
| >func2
|
||||||
|
| <func2
|
||||||
|
#
|
||||||
|
## Testing SUBDIR rules
|
||||||
|
#
|
||||||
|
% ./tests t:-f,func2/:d
|
||||||
|
>main
|
||||||
|
| >func1
|
||||||
|
| <func1
|
||||||
|
=> execute
|
||||||
|
=> evaluate: ON
|
||||||
|
=> evaluate_if: OFF
|
||||||
|
| explain: dbug explained: d:f:-f,func2/:t
|
||||||
|
<main
|
||||||
|
% ./tests t:f,func1/:d
|
||||||
|
| >func1
|
||||||
|
| | >func2
|
||||||
|
| | | >func3
|
||||||
|
| | | <func3
|
||||||
|
| | | info: s=ok
|
||||||
|
| | <func2
|
||||||
|
| <func1
|
||||||
|
=> evaluate: OFF
|
||||||
|
=> evaluate_if: OFF
|
||||||
|
% ./tests t:f,main/:d,pop
|
||||||
|
>main
|
||||||
|
| >func1
|
||||||
|
| | >func2
|
||||||
|
| | | >func3
|
||||||
|
| | | <func3
|
||||||
|
| | <func2
|
||||||
|
| <func1
|
||||||
|
=> evaluate: OFF
|
||||||
|
=> evaluate_if: OFF
|
||||||
|
% ./tests f,main/:d,push
|
||||||
|
=> evaluate: OFF
|
||||||
|
=> evaluate_if: OFF
|
||||||
|
| >func2
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
|
| <func2
|
||||||
|
<main
|
||||||
|
#
|
||||||
|
## Testing FixTraceFlags() - when we need to traverse the call stack
|
||||||
|
# (these tests fail with FixTraceFlags() disabled)
|
||||||
|
#
|
||||||
|
# delete the INCLUDE rule up the stack
|
||||||
|
% ./tests t:f,func1/ --push1=t:f,func3/
|
||||||
|
| >func1
|
||||||
|
| | >func2
|
||||||
|
| | | >func3
|
||||||
|
| | | <func3
|
||||||
|
| | <func2
|
||||||
|
=> push1
|
||||||
|
=> evaluate: OFF
|
||||||
|
=> evaluate_if: OFF
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
|
# delete the EXCLUDE rule up the stack
|
||||||
|
% ./tests t:-f,func1/ --push1=t
|
||||||
|
>main
|
||||||
|
=> push1
|
||||||
|
| <func1
|
||||||
|
=> evaluate: OFF
|
||||||
|
=> evaluate_if: OFF
|
||||||
|
| >func2
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
|
| <func2
|
||||||
|
<main
|
||||||
|
# add the INCLUDE rule up the stack
|
||||||
|
% ./tests t:f,func3 --push1=t:f,main/
|
||||||
|
| | | >func3
|
||||||
|
| | | <func3
|
||||||
|
=> push1
|
||||||
|
| <func1
|
||||||
|
=> evaluate: OFF
|
||||||
|
=> evaluate_if: OFF
|
||||||
|
| >func2
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
|
| <func2
|
||||||
|
<main
|
||||||
|
# add the EXCLUDE rule up the stack
|
||||||
|
% ./tests t --push1=t:-f,main/
|
||||||
|
>main
|
||||||
|
| >func1
|
||||||
|
| | >func2
|
||||||
|
| | | >func3
|
||||||
|
| | | <func3
|
||||||
|
| | <func2
|
||||||
|
=> push1
|
||||||
|
=> evaluate: OFF
|
||||||
|
=> evaluate_if: OFF
|
||||||
|
# change the defaults
|
||||||
|
% ./tests t:f,func3 --push1=t
|
||||||
|
| | | >func3
|
||||||
|
| | | <func3
|
||||||
|
=> push1
|
||||||
|
| <func1
|
||||||
|
=> evaluate: OFF
|
||||||
|
=> evaluate_if: OFF
|
||||||
|
| >func2
|
||||||
|
| | >func3
|
||||||
|
| | <func3
|
||||||
|
| <func2
|
||||||
<main
|
<main
|
||||||
|
16
dbug/tests.c
16
dbug/tests.c
@ -6,6 +6,8 @@
|
|||||||
#undef DBUG_OFF
|
#undef DBUG_OFF
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
char *push1=0;
|
||||||
|
|
||||||
#include <my_global.h> /* This includes dbug.h */
|
#include <my_global.h> /* This includes dbug.h */
|
||||||
#include <my_pthread.h>
|
#include <my_pthread.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -29,6 +31,11 @@ int func1()
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("func1");
|
DBUG_ENTER("func1");
|
||||||
func2();
|
func2();
|
||||||
|
if (push1)
|
||||||
|
{
|
||||||
|
DBUG_PUSH(push1);
|
||||||
|
fprintf(DBUG_FILE, "=> push1\n");
|
||||||
|
}
|
||||||
DBUG_RETURN(10);
|
DBUG_RETURN(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,12 +50,16 @@ int main (int argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
dup2(1, 2);
|
dup2(1, 2);
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
DBUG_PUSH (argv[i]);
|
{
|
||||||
|
if (strncmp(argv[i], "--push1=", 8) == 0)
|
||||||
|
push1=argv[i]+8;
|
||||||
|
else
|
||||||
|
DBUG_PUSH (argv[i]);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
DBUG_ENTER ("main");
|
DBUG_ENTER ("main");
|
||||||
DBUG_PROCESS ("dbug-tests");
|
DBUG_PROCESS ("dbug-tests");
|
||||||
func1();
|
func1();
|
||||||
func2();
|
|
||||||
DBUG_EXECUTE_IF("dump",
|
DBUG_EXECUTE_IF("dump",
|
||||||
{
|
{
|
||||||
char s[1000];
|
char s[1000];
|
||||||
@ -68,6 +79,7 @@ int main (int argc, char *argv[])
|
|||||||
DBUG_EXPLAIN(s, sizeof(s)-1);
|
DBUG_EXPLAIN(s, sizeof(s)-1);
|
||||||
DBUG_PRINT("explain", ("dbug explained: %s", s));
|
DBUG_PRINT("explain", ("dbug explained: %s", s));
|
||||||
}
|
}
|
||||||
|
func2();
|
||||||
DBUG_RETURN (0);
|
DBUG_RETURN (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
dbug/user.r
23
dbug/user.r
@ -908,17 +908,17 @@ via the
|
|||||||
.B DBUG_PUSH
|
.B DBUG_PUSH
|
||||||
or
|
or
|
||||||
.B DBUG_SET
|
.B DBUG_SET
|
||||||
macros. Control string consists of colon separate flags. Colons
|
macros. Control string consists of colon separated flags. Colons
|
||||||
that are part of ':\\', ':/', or '::' are not considered flag
|
that are part of ':\\', ':/', or '::' are not considered flag
|
||||||
separators. A flag may take an argument or a list of arguments.
|
separators. A flag may take an argument or a list of arguments.
|
||||||
If a control string starts from a '+' sign it works
|
If a control string starts from a '+' sign it works
|
||||||
.I incrementally,
|
.I incrementally,
|
||||||
that is, it can modify existing state without overriding it. In such a
|
that is, it can modify existing state without overriding it. Every
|
||||||
string every flag may be preceded by a '+' or '-' to enable or disable
|
flag may be preceded by a '+' or '-' to enable or disable a
|
||||||
a corresponding option in the debugger state. This section summarizes
|
corresponding option in the debugger state or to add or remove
|
||||||
the currently available debugger options and the flag characters which
|
arguments to the list. This section summarizes the currently available
|
||||||
enable or disable them. Argument lists enclosed in '[' and ']' are
|
debugger options and the flag characters which enable or disable them.
|
||||||
optional.
|
Argument lists enclosed in '[' and ']' are optional.
|
||||||
.SP 2
|
.SP 2
|
||||||
.BL 22
|
.BL 22
|
||||||
.LI a[,file]
|
.LI a[,file]
|
||||||
@ -942,6 +942,15 @@ Default is zero.
|
|||||||
.LI f[,functions]
|
.LI f[,functions]
|
||||||
Limit debugger actions to the specified list of functions.
|
Limit debugger actions to the specified list of functions.
|
||||||
An empty list of functions implies that all functions are selected.
|
An empty list of functions implies that all functions are selected.
|
||||||
|
Every function in the list may optionally be followed by a '/' -
|
||||||
|
this will implicitly select all the functions down the call stack.
|
||||||
|
.SP 1
|
||||||
|
EX: \fCf,func1,func2/:-f,func3,func4/\fR
|
||||||
|
.SP 1
|
||||||
|
This would enable debugger in functions 'func1()', 'func2()' and all
|
||||||
|
functions called from it (directly or indirectly). But not in
|
||||||
|
functions 'func3()' or 'func4()' and all functions called from
|
||||||
|
it.
|
||||||
.LI F
|
.LI F
|
||||||
Mark each debugger output line with the name of the source file
|
Mark each debugger output line with the name of the source file
|
||||||
containing the macro causing the output.
|
containing the macro causing the output.
|
||||||
|
@ -16,44 +16,47 @@
|
|||||||
#ifndef _dbug_h
|
#ifndef _dbug_h
|
||||||
#define _dbug_h
|
#define _dbug_h
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#if !defined(DBUG_OFF) && !defined(_lint)
|
#if !defined(DBUG_OFF) && !defined(_lint)
|
||||||
|
|
||||||
|
struct _db_stack_frame_ {
|
||||||
|
const char *func; /* function name of the previous stack frame */
|
||||||
|
const char *file; /* filename of the function of previous frame */
|
||||||
|
uint level; /* this nesting level, highest bit enables tracing */
|
||||||
|
struct _db_stack_frame_ *prev; /* pointer to the previous frame */
|
||||||
|
};
|
||||||
|
|
||||||
struct _db_code_state_;
|
struct _db_code_state_;
|
||||||
extern my_bool _dbug_on_;
|
extern my_bool _dbug_on_;
|
||||||
extern my_bool _db_keyword_(struct _db_code_state_ *, const char *, int);
|
extern my_bool _db_keyword_(struct _db_code_state_ *, const char *, int);
|
||||||
extern int _db_explain_(struct _db_code_state_ *cs, char *buf, size_t len);
|
extern int _db_explain_(struct _db_code_state_ *cs, char *buf, size_t len);
|
||||||
extern int _db_explain_init_(char *buf, size_t len);
|
extern int _db_explain_init_(char *buf, size_t len);
|
||||||
extern void _db_setjmp_(void);
|
extern void _db_setjmp_(void);
|
||||||
extern void _db_longjmp_(void);
|
extern void _db_longjmp_(void);
|
||||||
extern void _db_process_(const char *name);
|
extern void _db_process_(const char *name);
|
||||||
extern void _db_push_(const char *control);
|
extern void _db_push_(const char *control);
|
||||||
extern void _db_pop_(void);
|
extern void _db_pop_(void);
|
||||||
extern void _db_set_(struct _db_code_state_ *cs, const char *control);
|
extern void _db_set_(const char *control);
|
||||||
extern void _db_set_init_(const char *control);
|
extern void _db_set_init_(const char *control);
|
||||||
extern void _db_enter_(const char *_func_,const char *_file_,uint _line_,
|
extern void _db_enter_(const char *_func_, const char *_file_, uint _line_,
|
||||||
const char **_sfunc_,const char **_sfile_,
|
struct _db_stack_frame_ *_stack_frame_);
|
||||||
uint *_slevel_, char ***);
|
extern void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_);
|
||||||
extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_,
|
extern void _db_pargs_(uint _line_,const char *keyword);
|
||||||
uint *_slevel_);
|
extern void _db_doprnt_ _VARARGS((const char *format,...))
|
||||||
extern void _db_pargs_(uint _line_,const char *keyword);
|
|
||||||
extern void _db_doprnt_ _VARARGS((const char *format,...))
|
|
||||||
ATTRIBUTE_FORMAT(printf, 1, 2);
|
ATTRIBUTE_FORMAT(printf, 1, 2);
|
||||||
extern void _db_dump_(uint _line_,const char *keyword,
|
extern void _db_dump_(uint _line_,const char *keyword,
|
||||||
const unsigned char *memory, size_t length);
|
const unsigned char *memory, size_t length);
|
||||||
extern void _db_end_(void);
|
extern void _db_end_(void);
|
||||||
extern void _db_lock_file_(void);
|
extern void _db_lock_file_(void);
|
||||||
extern void _db_unlock_file_(void);
|
extern void _db_unlock_file_(void);
|
||||||
extern FILE *_db_fp_(void);
|
extern FILE *_db_fp_(void);
|
||||||
extern void _db_force_flush();
|
extern void _db_force_flush();
|
||||||
|
|
||||||
#define DBUG_ENTER(a) const char *_db_func_, *_db_file_; uint _db_level_; \
|
#define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \
|
||||||
char **_db_framep_; \
|
_db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_)
|
||||||
_db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, \
|
#define DBUG_LEAVE _db_return_ (__LINE__, &_db_stack_frame_)
|
||||||
&_db_framep_)
|
|
||||||
#define DBUG_LEAVE \
|
|
||||||
_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_)
|
|
||||||
#define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0)
|
#define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0)
|
||||||
#define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0)
|
#define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0)
|
||||||
#define DBUG_EXECUTE(keyword,a1) \
|
#define DBUG_EXECUTE(keyword,a1) \
|
||||||
@ -68,7 +71,7 @@ extern void _db_force_flush();
|
|||||||
do {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;} while(0)
|
do {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;} while(0)
|
||||||
#define DBUG_PUSH(a1) _db_push_ (a1)
|
#define DBUG_PUSH(a1) _db_push_ (a1)
|
||||||
#define DBUG_POP() _db_pop_ ()
|
#define DBUG_POP() _db_pop_ ()
|
||||||
#define DBUG_SET(a1) _db_set_ (0, (a1))
|
#define DBUG_SET(a1) _db_set_ (a1)
|
||||||
#define DBUG_SET_INITIAL(a1) _db_set_init_ (a1)
|
#define DBUG_SET_INITIAL(a1) _db_set_init_ (a1)
|
||||||
#define DBUG_PROCESS(a1) _db_process_(a1)
|
#define DBUG_PROCESS(a1) _db_process_(a1)
|
||||||
#define DBUG_FILE _db_fp_()
|
#define DBUG_FILE _db_fp_()
|
||||||
@ -84,7 +87,7 @@ extern void _db_force_flush();
|
|||||||
#define DEBUGGER_OFF do { _dbug_on_= 0; } while(0)
|
#define DEBUGGER_OFF do { _dbug_on_= 0; } while(0)
|
||||||
#define DEBUGGER_ON do { _dbug_on_= 1; } while(0)
|
#define DEBUGGER_ON do { _dbug_on_= 1; } while(0)
|
||||||
#define IF_DBUG(A) A
|
#define IF_DBUG(A) A
|
||||||
#else /* No debugger */
|
#else /* No debugger */
|
||||||
|
|
||||||
#define DBUG_ENTER(a1)
|
#define DBUG_ENTER(a1)
|
||||||
#define DBUG_LEAVE
|
#define DBUG_LEAVE
|
||||||
@ -114,7 +117,7 @@ extern void _db_force_flush();
|
|||||||
#define DEBUGGER_ON do { } while(0)
|
#define DEBUGGER_ON do { } while(0)
|
||||||
#define IF_DBUG(A)
|
#define IF_DBUG(A)
|
||||||
#endif
|
#endif
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user