Skip to content

Commit

Permalink
Enhance crash reporting
Browse files Browse the repository at this point in the history
Patch by: michaelortmann
  • Loading branch information
michaelortmann authored Jan 7, 2024
1 parent 2c41e37 commit bf2c80b
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 119 deletions.
8 changes: 0 additions & 8 deletions src/eggdrop.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,14 +240,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 @@ -166,11 +166,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 @@ -255,31 +251,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 @@ -288,10 +278,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 @@ -347,14 +337,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 @@ -439,40 +422,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 @@ -604,8 +559,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 @@ -1026,12 +979,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 @@ -186,11 +186,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 @@ -495,11 +491,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[READMAX + 2], *p, *px, *p2;
Expand Down Expand Up @@ -1283,8 +1282,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 @@ -188,8 +188,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);
int expmem_modules(int);
Expand Down
27 changes: 8 additions & 19 deletions src/tclhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,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 @@ -215,7 +219,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 @@ -243,7 +246,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 @@ -726,35 +728,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

0 comments on commit bf2c80b

Please sign in to comment.