Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance context log #1390

Merged
merged 11 commits into from
Jan 7, 2024
8 changes: 0 additions & 8 deletions src/eggdrop.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,14 +278,6 @@
#define nrealloc(x,y) n_realloc((x),(y),__FILE__,__LINE__)
#define nfree(x) n_free((x),__FILE__,__LINE__)

#ifdef DEBUG_CONTEXT
# define Context eggContext(__FILE__, __LINE__, NULL)
# define ContextNote(note) eggContextNote(__FILE__, __LINE__, NULL, note)
#else
# define Context do {} while (0)
# define ContextNote(note) do {} while (0)
#endif

#ifdef DEBUG_ASSERT
# define Assert(expr) do { \
if (!(expr)) \
Expand Down
81 changes: 14 additions & 67 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*/

/* We need config.h for CYGWIN_HACKS, but windows.h must be included before
* eggdrop headers, because the malloc/free/Context macros break the inclusion.
* eggdrop headers, because the malloc/free macros break the inclusion.
* The SSL undefs are a workaround for bug #2182 in openssl with msys/mingw.
*/
#include <config.h>
Expand Down Expand Up @@ -171,11 +171,7 @@ unsigned long itraffic_unknown = 0;
unsigned long itraffic_unknown_today = 0;

#ifdef DEBUG_CONTEXT
/* Context storage for fatal crashes */
char cx_file[16][32];
char cx_note[16][256];
int cx_line[16];
int cx_ptr = 0;
extern char last_bind_called[];
#endif

#ifdef TLS
Expand Down Expand Up @@ -261,31 +257,25 @@ static void write_debug()
{
int x;
char s[25];
int y;

if (nested_debug) {
/* Yoicks, if we have this there's serious trouble!
* All of these are pretty reliable, so we'll try these.
*
* NOTE: don't try and display context-notes in here, it's
* _not_ safe <cybah>
*/
x = creat("DEBUG.DEBUG", 0644);
if (x >= 0) {
setsock(x, SOCK_NONSOCK);
strlcpy(s, ctime(&now), sizeof s);
dprintf(-x, "Debug (%s) written %s\n", ver, s);
dprintf(-x, "Please report problem to https://github.com/eggheads/eggdrop/issues\n");
dprintf(-x, "Debug (%s) written %s\n"
"Please report problem to https://github.com/eggheads/eggdrop/issues\n"
"Check doc/BUG-REPORT on how to do so.", ver, s);
#ifdef EGG_PATCH
dprintf(-x, "Patch level: %s\n", EGG_PATCH);
#else
dprintf(-x, "Patch level: %s\n", "stable");
#endif
dprintf(-x, "Context: ");
cx_ptr = cx_ptr & 15;
for (y = ((cx_ptr + 1) & 15); y != cx_ptr; y = ((y + 1) & 15))
dprintf(-x, "%s/%d,\n ", cx_file[y], cx_line[y]);
dprintf(-x, "%s/%d\n\n", cx_file[y], cx_line[y]);
if (*last_bind_called)
dprintf(-x, "Last bind (may not be related): %s\n", last_bind_called);
killsock(x);
close(x);
}
Expand All @@ -294,10 +284,10 @@ static void write_debug()
* have caused the fault last time. */
} else
nested_debug = 1;
putlog(LOG_MISC, "*", "* Last context: %s/%d [%s]", cx_file[cx_ptr],
cx_line[cx_ptr], cx_note[cx_ptr][0] ? cx_note[cx_ptr] : "");
putlog(LOG_MISC, "*", "* Please REPORT this BUG!");
putlog(LOG_MISC, "*", "* Please report problem to https://github.com/eggheads/eggdrop/issues");
putlog(LOG_MISC, "*", "* Check doc/BUG-REPORT on how to do so.");
if (*last_bind_called)
putlog(LOG_MISC, "*", "* Last bind (may not be related): %s", last_bind_called);
x = creat("DEBUG", 0644);
setsock(x, SOCK_NONSOCK);
if (x < 0) {
Expand Down Expand Up @@ -353,14 +343,7 @@ static void write_debug()
#ifdef STRIPFLAGS
dprintf(-x, "Strip flags: %s\n", STRIPFLAGS);
#endif

dprintf(-x, "Context: ");
cx_ptr = cx_ptr & 15;
for (y = ((cx_ptr + 1) & 15); y != cx_ptr; y = ((y + 1) & 15))
dprintf(-x, "%s/%d, [%s]\n ", cx_file[y], cx_line[y],
(cx_note[y][0]) ? cx_note[y] : "");
dprintf(-x, "%s/%d [%s]\n\n", cx_file[cx_ptr], cx_line[cx_ptr],
(cx_note[cx_ptr][0]) ? cx_note[cx_ptr] : "");
dprintf(-x, "Last bind (may not be related): %s\n", last_bind_called);
tell_dcc(-x);
dprintf(-x, "\n");
debug_mem_to_dcc(-x);
Expand Down Expand Up @@ -445,40 +428,12 @@ static void got_ill(int z)
{
check_tcl_signal("sigill");
#ifdef DEBUG_CONTEXT
putlog(LOG_MISC, "*", "* Context: %s/%d [%s]", cx_file[cx_ptr],
cx_line[cx_ptr], (cx_note[cx_ptr][0]) ? cx_note[cx_ptr] : "");
putlog(LOG_MISC, "*", "* Please REPORT this BUG!");
putlog(LOG_MISC, "*", "* Check doc/BUG-REPORT on how to do so.");
putlog(LOG_MISC, "*", "* Last bind (may not be related): %s", last_bind_called);
#endif
}

#ifdef DEBUG_CONTEXT
/* Called from the Context macro.
*/
void eggContext(const char *file, int line, const char *module)
{
eggContextNote(file, line, module, NULL);
}

/* Called from the ContextNote macro.
*/
void eggContextNote(const char *file, int line, const char *module,
const char *note)
{
char *p;

p = strrchr(file, '/');
cx_ptr = ((cx_ptr + 1) & 15);
if (!module)
strlcpy(cx_file[cx_ptr], p ? p + 1 : file, sizeof cx_file[cx_ptr]);
else
snprintf(cx_file[cx_ptr], sizeof cx_file[cx_ptr], "%s:%s", module, p ? p + 1 : file);
cx_line[cx_ptr] = line;
if (!note)
cx_note[cx_ptr][0] = 0;
else
strlcpy(cx_note[cx_ptr], note, sizeof cx_note[cx_ptr]);
}
#endif /* DEBUG_CONTEXT */

#ifdef DEBUG_ASSERT
/* Called from the Assert macro.
*/
Expand Down Expand Up @@ -610,8 +565,6 @@ static time_t then;
static struct tm nowtm;

/* Called once a second.
*
* Note: Try to not put any Context lines in here (guppy 21Mar2000).
*/
static void core_secondly()
{
Expand Down Expand Up @@ -1032,12 +985,6 @@ int main(int arg_c, char **arg_v)
setrlimit(RLIMIT_CORE, &cdlim);
#endif

#ifdef DEBUG_CONTEXT
/* Initialise context list */
for (i = 0; i < 16; i++)
Context;
#endif

argc = arg_c;
argv = arg_v;

Expand Down
12 changes: 2 additions & 10 deletions src/mod/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,7 @@ typedef void (*chanout_butfunc)(int, int, const char *, ...) ATTRIBUTE_FORMAT(pr
/* 0 - 3 */
#define nmalloc(x) (((void *(*)())global[0])((x),MODULE_NAME,__FILE__,__LINE__))
#define nfree(x) (global[1]((x),MODULE_NAME,__FILE__,__LINE__))
#ifdef DEBUG_CONTEXT
# define Context (global[2](__FILE__, __LINE__, MODULE_NAME))
#else
# define Context do {} while (0)
#endif
#define Context do {} while (0) /* For backward compatibility only */
#define module_rename ((int (*)(char *, char *))global[3])
/* 4 - 7 */
#define module_register ((int (*)(char *, Function *, int, int))global[4])
Expand Down Expand Up @@ -396,11 +392,7 @@ typedef void (*chanout_butfunc)(int, int, const char *, ...) ATTRIBUTE_FORMAT(pr
#define nrealloc(x,y) (((void *(*)())global[230])((x),(y),MODULE_NAME,__FILE__,__LINE__))
#define xtra_set ((int(*)(struct userrec *,struct user_entry *, void *))global[231])
/* 232 - 235 */
#ifdef DEBUG_CONTEXT
# define ContextNote(note) (global[232](__FILE__, __LINE__, MODULE_NAME, note))
#else
# define ContextNote(note) do {} while (0)
#endif
#define ContextNote(note) do {} while (0) /* For backward compatibility only */
#ifdef DEBUG_ASSERT
# define Assert(expr) do { \
if (!(expr)) \
Expand Down
12 changes: 2 additions & 10 deletions src/modules.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,7 @@ Function global_table[] = {
/* 0 - 3 */
(Function) mod_malloc,
(Function) mod_free,
#ifdef DEBUG_CONTEXT
(Function) eggContext,
#else
(Function) 0,
#endif
(Function) 0, /* was eggContext() */
(Function) module_rename,
/* 4 - 7 */
(Function) module_register,
Expand Down Expand Up @@ -494,11 +490,7 @@ Function global_table[] = {
(Function) mod_realloc,
(Function) xtra_set,
/* 232 - 235 */
#ifdef DEBUG_CONTEXT
(Function) eggContextNote,
#else
(Function) 0,
#endif
(Function) 0, /* was eggContextNote() */
#ifdef DEBUG_ASSERT
(Function) eggAssert,
#else
Expand Down
3 changes: 0 additions & 3 deletions src/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,6 @@ int sockread(char *s, int *len, sock_list *slist, int slistmax, int tclonly)
* dcc functions. Simply ignore it.
* Returns -5 if tcl sockets are busy but not eggdrop sockets.
*/

int sockgets(char *s, int *len)
{
char xx[RECVLINEMAX], *p, *px, *p2;
Expand Down Expand Up @@ -1282,8 +1281,6 @@ int sockgets(char *s, int *len)
}

/* Dump something to a socket
*
* NOTE: Do NOT put Contexts in here if you want DEBUG to be meaningful!!
*/
void tputs(int z, char *s, unsigned int len)
{
Expand Down
2 changes: 0 additions & 2 deletions src/proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,6 @@ int exist_lang_section(char *);
/* main.c */
void fatal(const char *, int);
int expected_memory(void);
void eggContext(const char *, int, const char *);
void eggContextNote(const char *, int, const char *, const char *);
void eggAssert(const char *, int, const char *);
void backup_userfile(void);

Expand Down
27 changes: 8 additions & 19 deletions src/tclhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ static int builtin_chat STDVAR;
static int builtin_dcc STDVAR;
static int builtin_log STDVAR;

#ifdef DEBUG_CONTEXT
char last_bind_called[512] = "";
#endif

/* Allocate and initialise a chunk of memory.
*/
static void *n_malloc_null(int size, const char *file, int line)
Expand Down Expand Up @@ -214,7 +218,6 @@ static cd_tcl_cmd cd_cmd_table[] = {
void init_bind(void)
{
bind_table_list = NULL;
Context;
add_cd_tcl_cmds(cd_cmd_table);
H_unld = add_bind_table("unld", HT_STACKABLE, builtin_char);
H_time = add_bind_table("time", HT_STACKABLE, builtin_5int);
Expand Down Expand Up @@ -242,7 +245,6 @@ void init_bind(void)
H_tls = add_bind_table("tls", HT_STACKABLE, builtin_idx);
#endif
add_builtins(H_dcc, C_dcc);
Context;
}

void kill_bind(void)
Expand Down Expand Up @@ -710,35 +712,22 @@ static int trigger_bind(const char *proc, const char *param, char *mask)
int x;
struct rusage ru1, ru2;
int r = 0;
#ifdef DEBUG_CONTEXT
#define FORMAT "Tcl proc: %s, param: %s"
char *buf;

/* We now try to debug the Tcl_VarEval() call below by remembering both
* the called proc name and it's parameters. This should render us a bit
* less helpless when we see context dumps.
*/
Context;
/* reuse x */
x = snprintf(NULL, 0, FORMAT, proc ? proc : "<null>", param ? param : "<null>");
buf = nmalloc(x + 1);
sprintf(buf, FORMAT, proc ? proc : "<null>", param ? param : "<null>");
ContextNote(buf);
nfree(buf);
#endif /* DEBUG_CONTEXT */

/* Set the lastbind variable before evaluating the proc so that the name
* of the command that triggered the bind will be available to the proc.
* This feature is used by scripts such as userinfo.tcl
*/
Tcl_SetVar(interp, "lastbind", (char *) mask, TCL_GLOBAL_ONLY);
Tcl_SetVar(interp, "lastbind", mask, TCL_GLOBAL_ONLY);

if(proc && proc[0] != '*') { /* proc[0] != '*' excludes internal binds */
#ifdef DEBUG_CONTEXT
snprintf(last_bind_called, sizeof last_bind_called, proc);
#endif
debug1("triggering bind %s", proc);
r = getrusage(RUSAGE_SELF, &ru1);
}
x = Tcl_VarEval(interp, proc, param, NULL);
Context;
if (proc && proc[0] != '*' && !r) {
if (!getrusage(RUSAGE_SELF, &ru2)) {
debug3("triggered bind %s, user %.3fms sys %.3fms", proc,
Expand Down