#include "main.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "mod/modvals.h"
Go to the source code of this file.
Defines | |
#define | MEMTBLSIZE 25000 |
#define | COMPILING_MEM |
Functions | |
int | expected_memory () |
int | expmem_chanprog () |
int | expmem_misc () |
int | expmem_fileq () |
int | expmem_users () |
int | expmem_dccutil () |
int | expmem_botnet () |
int | expmem_tcl () |
int | expmem_tclhash () |
int | expmem_tclmisc () |
int | expmem_net () |
int | expmem_modules () |
int | expmem_language () |
int | expmem_tcldcc () |
int | expmem_dns () |
void | init_mem () |
void | tell_mem_status (char *nick) |
void | tell_mem_status_dcc (int idx) |
void | debug_mem_to_dcc (int idx) |
char * | n_strdup (const char *s, const char *file, int line) |
void * | n_malloc (int size, const char *file, int line) |
void * | n_realloc (void *ptr, int size, const char *file, int line) |
void | n_free (void *ptr, const char *file, int line) |
Variables | |
module_entry * | module_list |
#define MEMTBLSIZE 25000 |
Definition at line 27 of file mem.c.
Referenced by init_mem(), tell_mem_status(), and tell_mem_status_dcc().
void debug_mem_to_dcc | ( | int | idx | ) |
Definition at line 117 of file mem.c.
References dprintf, egg_strcasecmp, expmem_botnet(), expmem_chanprog(), expmem_dccutil(), expmem_dns(), expmem_language(), expmem_misc(), expmem_modules(), expmem_net(), expmem_tcl(), expmem_tcldcc(), expmem_tclhash(), expmem_tclmisc(), expmem_users(), _module_entry::funcs, MODCALL_EXPMEM, _module_entry::name, _module_entry::next, NULL, and tell_netdebug().
Referenced by cmd_debug().
00118 { 00119 #ifdef DEBUG_MEM 00120 # define MAX_MEM 13 00121 unsigned long exp[MAX_MEM], use[MAX_MEM], l; 00122 int i, j; 00123 char fn[20], sofar[81]; 00124 module_entry *me; 00125 char *p; 00126 00127 exp[0] = expmem_language(); 00128 exp[1] = expmem_chanprog(); 00129 exp[2] = expmem_misc(); 00130 exp[3] = expmem_users(); 00131 exp[4] = expmem_net(); 00132 exp[5] = expmem_dccutil(); 00133 exp[6] = expmem_botnet(); 00134 exp[7] = expmem_tcl(); 00135 exp[8] = expmem_tclhash(); 00136 exp[9] = expmem_tclmisc(); 00137 exp[10] = expmem_modules(1); 00138 exp[11] = expmem_tcldcc(); 00139 exp[12] = expmem_dns(); 00140 00141 for (me = module_list; me; me = me->next) 00142 me->mem_work = 0; 00143 00144 for (i = 0; i < MAX_MEM; i++) 00145 use[i] = 0; 00146 00147 for (i = 0; i < lastused; i++) { 00148 strcpy(fn, memtbl[i].file); 00149 p = strchr(fn, ':'); 00150 if (p) 00151 *p = 0; 00152 l = memtbl[i].size; 00153 if (!strcmp(fn, "language.c")) 00154 use[0] += l; 00155 else if (!strcmp(fn, "chanprog.c")) 00156 use[1] += l; 00157 else if (!strcmp(fn, "misc.c")) 00158 use[2] += l; 00159 else if (!strcmp(fn, "userrec.c")) 00160 use[3] += l; 00161 else if (!strcmp(fn, "net.c")) 00162 use[4] += l; 00163 else if (!strcmp(fn, "dccutil.c")) 00164 use[5] += l; 00165 else if (!strcmp(fn, "botnet.c")) 00166 use[6] += l; 00167 else if (!strcmp(fn, "tcl.c")) 00168 use[7] += l; 00169 else if (!strcmp(fn, "tclhash.c")) 00170 use[8] += l; 00171 else if (!strcmp(fn, "tclmisc.c")) 00172 use[9] += l; 00173 else if (!strcmp(fn, "modules.c")) 00174 use[10] += l; 00175 else if (!strcmp(fn, "tcldcc.c")) 00176 use[11] += l; 00177 else if (!strcmp(fn, "dns.c")) 00178 use[12] += l; 00179 else if (p) { 00180 for (me = module_list; me; me = me->next) 00181 if (!strcmp(fn, me->name)) 00182 me->mem_work += l; 00183 } else 00184 dprintf(idx, "Not logging file %s!\n", fn); 00185 } 00186 00187 for (i = 0; i < MAX_MEM; i++) { 00188 switch (i) { 00189 case 0: 00190 strcpy(fn, "language.c"); 00191 break; 00192 case 1: 00193 strcpy(fn, "chanprog.c"); 00194 break; 00195 case 2: 00196 strcpy(fn, "misc.c"); 00197 break; 00198 case 3: 00199 strcpy(fn, "userrec.c"); 00200 break; 00201 case 4: 00202 strcpy(fn, "net.c"); 00203 break; 00204 case 5: 00205 strcpy(fn, "dccutil.c"); 00206 break; 00207 case 6: 00208 strcpy(fn, "botnet.c"); 00209 break; 00210 case 7: 00211 strcpy(fn, "tcl.c"); 00212 break; 00213 case 8: 00214 strcpy(fn, "tclhash.c"); 00215 break; 00216 case 9: 00217 strcpy(fn, "tclmisc.c"); 00218 break; 00219 case 10: 00220 strcpy(fn, "modules.c"); 00221 break; 00222 case 11: 00223 strcpy(fn, "tcldcc.c"); 00224 break; 00225 case 12: 00226 strcpy(fn, "dns.c"); 00227 break; 00228 } 00229 00230 if (use[i] == exp[i]) 00231 dprintf(idx, "File '%-10s' accounted for %lu/%lu (ok)\n", fn, exp[i], 00232 use[i]); 00233 else { 00234 dprintf(idx, "File '%-10s' accounted for %lu/%lu (debug follows:)\n", 00235 fn, exp[i], use[i]); 00236 strcpy(sofar, " "); 00237 for (j = 0; j < lastused; j++) { 00238 if ((p = strchr(memtbl[j].file, ':'))) 00239 *p = 0; 00240 if (!egg_strcasecmp(memtbl[j].file, fn)) { 00241 if (p) 00242 sprintf(&sofar[strlen(sofar)], "%-10s/%-4d:(%04d) ", 00243 p + 1, memtbl[j].line, memtbl[j].size); 00244 else 00245 sprintf(&sofar[strlen(sofar)], "%-4d:(%04d) ", 00246 memtbl[j].line, memtbl[j].size); 00247 00248 if (strlen(sofar) > 60) { 00249 sofar[strlen(sofar) - 1] = 0; 00250 dprintf(idx, "%s\n", sofar); 00251 strcpy(sofar, " "); 00252 } 00253 } 00254 if (p) 00255 *p = ':'; 00256 } 00257 if (sofar[0]) { 00258 sofar[strlen(sofar) - 1] = 0; 00259 dprintf(idx, "%s\n", sofar); 00260 } 00261 } 00262 } 00263 00264 for (me = module_list; me; me = me->next) { 00265 Function *f = me->funcs; 00266 int expt = 0; 00267 00268 if ((f != NULL) && (f[MODCALL_EXPMEM] != NULL)) 00269 expt = f[MODCALL_EXPMEM] (); 00270 if (me->mem_work == expt) 00271 dprintf(idx, "Module '%-10s' accounted for %lu/%lu (ok)\n", me->name, 00272 expt, me->mem_work); 00273 else { 00274 dprintf(idx, "Module '%-10s' accounted for %lu/%lu (debug follows:)\n", 00275 me->name, expt, me->mem_work); 00276 strcpy(sofar, " "); 00277 for (j = 0; j < lastused; j++) { 00278 strcpy(fn, memtbl[j].file); 00279 if ((p = strchr(fn, ':')) != NULL) { 00280 *p = 0; 00281 if (!egg_strcasecmp(fn, me->name)) { 00282 sprintf(&sofar[strlen(sofar)], "%-10s/%-4d:(%04X) ", p + 1, 00283 memtbl[j].line, memtbl[j].size); 00284 if (strlen(sofar) > 60) { 00285 sofar[strlen(sofar) - 1] = 0; 00286 dprintf(idx, "%s\n", sofar); 00287 strcpy(sofar, " "); 00288 } 00289 *p = ':'; 00290 } 00291 } 00292 } 00293 if (sofar[0]) { 00294 sofar[strlen(sofar) - 1] = 0; 00295 dprintf(idx, "%s\n", sofar); 00296 } 00297 } 00298 } 00299 00300 dprintf(idx, "--- End of debug memory list.\n"); 00301 #else 00302 dprintf(idx, "Compiled without extensive memory debugging (sorry).\n"); 00303 #endif 00304 tell_netdebug(idx); 00305 }
int expected_memory | ( | ) |
Definition at line 202 of file main.c.
References expmem_botnet(), expmem_chanprog(), expmem_dccutil(), expmem_language(), expmem_misc(), expmem_modules(), expmem_net(), expmem_tcl(), expmem_tcldcc(), expmem_tclhash(), expmem_tclmisc(), and expmem_users().
00203 { 00204 int tot; 00205 00206 tot = expmem_chanprog() + expmem_users() + expmem_misc() + expmem_dccutil() + 00207 expmem_botnet() + expmem_tcl() + expmem_tclhash() + expmem_net() + 00208 expmem_modules(0) + expmem_language() + expmem_tcldcc() + 00209 expmem_tclmisc(); 00210 return tot; 00211 }
int expmem_botnet | ( | ) |
Definition at line 49 of file botnet.c.
References dcc_t::bot, from, maxparty, tand_t_struct::next, and parties.
Referenced by debug_mem_to_dcc(), and expected_memory().
00050 { 00051 int size = 0, i; 00052 tand_t *bot; 00053 00054 for (bot = tandbot; bot; bot = bot->next) 00055 size += sizeof(tand_t); 00056 size += (maxparty * sizeof(party_t)); 00057 for (i = 0; i < parties; i++) { 00058 if (party[i].away) 00059 size += strlen(party[i].away) + 1; 00060 if (party[i].from) 00061 size += strlen(party[i].from) + 1; 00062 } 00063 return size; 00064 }
int expmem_chanprog | ( | ) |
Definition at line 216 of file chanprog.c.
References timer_str::cmd, and timer_str::next.
Referenced by debug_mem_to_dcc(), and expected_memory().
00217 { 00218 register int tot = 0; 00219 register tcl_timer_t *t; 00220 00221 for (t = timer; t; t = t->next) 00222 tot += sizeof(tcl_timer_t) + strlen(t->cmd) + 1; 00223 for (t = utimer; t; t = t->next) 00224 tot += sizeof(tcl_timer_t) + strlen(t->cmd) + 1; 00225 return tot; 00226 }
int expmem_dccutil | ( | ) |
Definition at line 97 of file dccutil.c.
References dcc_total, dcc_table::expmem, max_dcc, threaddata::MAXSOCKS, threaddata(), dcc_t::type, and dcc_t::u.
Referenced by debug_mem_to_dcc(), and expected_memory().
00098 { 00099 int tot, i; 00100 00101 tot = sizeof(struct dcc_t) * max_dcc; 00102 tot += sizeof(sock_list) * threaddata()->MAXSOCKS; 00103 00104 for (i = 0; i < dcc_total; i++) { 00105 if (dcc[i].type && dcc[i].type->expmem) 00106 tot += dcc[i].type->expmem(dcc[i].u.other); 00107 } 00108 return tot; 00109 }
int expmem_dns | ( | ) |
Definition at line 515 of file dns.c.
References dnsevent_expmem().
Referenced by debug_mem_to_dcc().
00516 { 00517 return dnsevent_expmem(); 00518 }
int expmem_fileq | ( | ) |
int expmem_language | ( | ) |
Definition at line 563 of file language.c.
References lang_pr::lang, lang_st::lang, lang_pr::next, lang_st::next, lang_t::next, lang_st::section, and lang_t::text.
Referenced by cmd_languagestatus(), debug_mem_to_dcc(), and expected_memory().
00564 { 00565 lang_tab *l; 00566 lang_sec *ls; 00567 lang_pri *lp; 00568 int i, size = 0; 00569 00570 for (i = 0; i < 64; i++) 00571 for (l = langtab[i]; l; l = l->next) { 00572 size += sizeof(lang_tab); 00573 size += (strlen(l->text) + 1); 00574 } 00575 for (ls = langsection; ls; ls = ls->next) { 00576 size += sizeof(lang_sec); 00577 if (ls->section) 00578 size += strlen(ls->section) + 1; 00579 if (ls->lang) 00580 size += strlen(ls->lang) + 1; 00581 } 00582 for (lp = langpriority; lp; lp = lp->next) { 00583 size += sizeof(lang_pri); 00584 if (lp->lang) 00585 size += strlen(lp->lang) + 1; 00586 } 00587 return size; 00588 }
int expmem_misc | ( | ) |
Definition at line 83 of file misc.c.
References help_ref::first, help_list, max_logs, help_list_t::next, and help_ref::next.
00084 { 00085 struct help_ref *current; 00086 struct help_list_t *item; 00087 int tot = 0; 00088 00089 for (current = help_list; current; current = current->next) { 00090 tot += sizeof(struct help_ref) + strlen(current->name) + 1; 00091 00092 for (item = current->first; item; item = item->next) 00093 tot += sizeof(struct help_list_t) + strlen(item->name) + 1; 00094 } 00095 return tot + (max_logs * sizeof(log_t)); 00096 }
int expmem_modules | ( | ) |
int expmem_net | ( | ) |
Definition at line 90 of file net.c.
References threaddata::MAXSOCKS, NULL, SOCK_TCL, SOCK_UNUSED, and threaddata().
00091 { 00092 int i, tot = 0; 00093 struct threaddata *td = threaddata(); 00094 00095 for (i = 0; i < td->MAXSOCKS; i++) { 00096 if (!(td->socklist[i].flags & (SOCK_UNUSED | SOCK_TCL))) { 00097 if (td->socklist[i].handler.sock.inbuf != NULL) 00098 tot += strlen(td->socklist[i].handler.sock.inbuf) + 1; 00099 if (td->socklist[i].handler.sock.outbuf != NULL) 00100 tot += td->socklist[i].handler.sock.outbuflen; 00101 } 00102 } 00103 return tot; 00104 }
int expmem_tcl | ( | ) |
Definition at line 101 of file tcl.c.
References clientdata_stuff, strtot, and utftot.
00102 { 00103 return strtot + utftot + clientdata_stuff; 00104 }
int expmem_tcldcc | ( | ) |
int expmem_tclhash | ( | ) |
Definition at line 195 of file tclhash.c.
00196 { 00197 int tot = 0; 00198 tcl_bind_list_t *tl; 00199 00200 for (tl = bind_table_list; tl; tl = tl->next) 00201 tot += tcl_bind_list_expmem(tl); 00202 return tot; 00203 }
int expmem_users | ( | ) |
Definition at line 98 of file userrec.c.
References chanset_t::bans, userrec::chanrec, userrec::entries, chanset_t::exempts, user_entry_type::expmem, expmem_mask(), global_exempts, global_invites, igrec::igmask, chanuserrec::info, chanset_t::invites, user_entry::list, list_type_expmem(), igrec::msg, user_entry::name, igrec::next, chanset_t::next, user_entry::next, chanuserrec::next, userrec::next, NULL, user_entry::type, user_entry::u, and igrec::user.
00099 { 00100 int tot; 00101 struct userrec *u; 00102 struct chanuserrec *ch; 00103 struct chanset_t *chan; 00104 struct user_entry *ue; 00105 struct igrec *i; 00106 00107 tot = 0; 00108 for (u = userlist; u; u = u->next) { 00109 for (ch = u->chanrec; ch; ch = ch->next) { 00110 tot += sizeof(struct chanuserrec); 00111 00112 if (ch->info != NULL) 00113 tot += strlen(ch->info) + 1; 00114 } 00115 tot += sizeof(struct userrec); 00116 00117 for (ue = u->entries; ue; ue = ue->next) { 00118 tot += sizeof(struct user_entry); 00119 00120 if (ue->name) { 00121 tot += strlen(ue->name) + 1; 00122 tot += list_type_expmem(ue->u.list); 00123 } else 00124 tot += ue->type->expmem(ue); 00125 } 00126 } 00127 /* Account for each channel's masks */ 00128 for (chan = chanset; chan; chan = chan->next) { 00129 00130 /* Account for each channel's ban-list user */ 00131 tot += expmem_mask(chan->bans); 00132 00133 /* Account for each channel's exempt-list user */ 00134 tot += expmem_mask(chan->exempts); 00135 00136 /* Account for each channel's invite-list user */ 00137 tot += expmem_mask(chan->invites); 00138 } 00139 00140 tot += expmem_mask(global_bans); 00141 tot += expmem_mask(global_exempts); 00142 tot += expmem_mask(global_invites); 00143 00144 for (i = global_ign; i; i = i->next) { 00145 tot += sizeof(struct igrec); 00146 00147 tot += strlen(i->igmask) + 1; 00148 if (i->user) 00149 tot += strlen(i->user) + 1; 00150 if (i->msg) 00151 tot += strlen(i->msg) + 1; 00152 } 00153 return tot; 00154 }
void init_mem | ( | ) |
Definition at line 73 of file mem.c.
References MEMTBLSIZE, and NULL.
Referenced by main().
00074 { 00075 #ifdef DEBUG_MEM 00076 int i; 00077 00078 for (i = 0; i < MEMTBLSIZE; i++) 00079 memtbl[i].ptr = NULL; 00080 #endif 00081 }
void n_free | ( | void * | ptr, | |
const char * | file, | |||
int | line | |||
) |
Definition at line 395 of file mem.c.
References free, LOG_MISC, NULL, and putlog.
00396 { 00397 int i = 0; 00398 00399 if (ptr == NULL) { 00400 putlog(LOG_MISC, "*", "*** ATTEMPTING TO FREE NULL PTR: %s (%d)", 00401 file, line); 00402 i = i; 00403 return; 00404 } 00405 #ifdef DEBUG_MEM 00406 /* Give tcl builtins an escape mechanism */ 00407 if (line) { 00408 for (i = 0; (i < lastused) && (memtbl[i].ptr != ptr); i++); 00409 if (i == lastused) { 00410 putlog(LOG_MISC, "*", "*** ATTEMPTING TO FREE NON-MALLOC'D PTR: %s (%d)", 00411 file, line); 00412 return; 00413 } 00414 memused -= memtbl[i].size; 00415 lastused--; 00416 /* We don't want any holes, so if this wasn't the last entry, swap it. */ 00417 if (i != lastused) { 00418 memtbl[i].ptr = memtbl[lastused].ptr; 00419 memtbl[i].size = memtbl[lastused].size; 00420 memtbl[i].line = memtbl[lastused].line; 00421 strcpy(memtbl[i].file, memtbl[lastused].file); 00422 } 00423 } 00424 #endif 00425 free(ptr); 00426 }
void* n_malloc | ( | int | size, | |
const char * | file, | |||
int | line | |||
) |
Definition at line 341 of file mem.c.
References fatal, LOG_MISC, malloc, NULL, and putlog.
Referenced by _get_data_ptr(), _user_malloc(), n_malloc_null(), and n_realloc().
00342 { 00343 void *x; 00344 00345 x = (void *) malloc(size); 00346 if (x == NULL) { 00347 putlog(LOG_MISC, "*", "*** FAILED MALLOC %s (%d) (%d): %s", file, line, 00348 size, strerror(errno)); 00349 fatal("Memory allocation failed", 0); 00350 } 00351 #ifdef DEBUG_MEM 00352 addtomemtbl(x, size, file, line); 00353 #endif 00354 return x; 00355 }
void* n_realloc | ( | void * | ptr, | |
int | size, | |||
const char * | file, | |||
int | line | |||
) |
Definition at line 357 of file mem.c.
References LOG_MISC, n_malloc(), NULL, and putlog.
Referenced by _user_realloc().
00358 { 00359 void *x; 00360 int i = 0; 00361 00362 #ifdef DEBUG_MEM 00363 char *p; 00364 #endif 00365 00366 /* ptr == NULL is valid. Avoiding duplicate code further down */ 00367 if (!ptr) 00368 return n_malloc(size, file, line); 00369 00370 x = (void *) realloc(ptr, size); 00371 if (x == NULL && size > 0) { 00372 i = i; 00373 putlog(LOG_MISC, "*", "*** FAILED REALLOC %s (%d)", file, line); 00374 return NULL; 00375 } 00376 #ifdef DEBUG_MEM 00377 for (i = 0; (i < lastused) && (memtbl[i].ptr != ptr); i++); 00378 if (i == lastused) { 00379 putlog(LOG_MISC, "*", "*** ATTEMPTING TO REALLOC NON-MALLOC'D PTR: %s (%d)", 00380 file, line); 00381 return NULL; 00382 } 00383 memused -= memtbl[i].size; 00384 memtbl[i].ptr = x; 00385 memtbl[i].line = line; 00386 memtbl[i].size = size; 00387 p = strrchr(file, '/'); 00388 strncpy(memtbl[i].file, p ? p + 1 : file, 19); 00389 memtbl[i].file[19] = 0; 00390 memused += size; 00391 #endif 00392 return x; 00393 }
char* n_strdup | ( | const char * | s, | |
const char * | file, | |||
int | line | |||
) |
Definition at line 329 of file mem.c.
References egg_strdup().
00330 { 00331 char *x; 00332 00333 x = egg_strdup(s); 00334 /* compat strdup uses nmalloc itself */ 00335 #if defined(DEBUG_MEM) && defined(HAVE_STRDUP) 00336 addtomemtbl(x, strlen(s)+1, file, line); 00337 #endif 00338 return x; 00339 }
void tell_mem_status | ( | char * | nick | ) |
Definition at line 85 of file mem.c.
References DP_HELP, dprintf, expected_memory, and MEMTBLSIZE.
00086 { 00087 #ifdef DEBUG_MEM 00088 float per; 00089 00090 per = ((lastused * 1.0) / (MEMTBLSIZE * 1.0)) * 100.0; 00091 dprintf(DP_HELP, "NOTICE %s :Memory table usage: %d/%d (%.1f%% full)\n", 00092 nick, lastused, MEMTBLSIZE, per); 00093 #endif 00094 dprintf(DP_HELP, "NOTICE %s :Think I'm using about %dk.\n", nick, 00095 (int) (expected_memory() / 1024)); 00096 }
void tell_mem_status_dcc | ( | int | idx | ) |
Definition at line 98 of file mem.c.
References dprintf, expected_memory, and MEMTBLSIZE.
Referenced by cmd_status(), and core_secondly().
00099 { 00100 #ifdef DEBUG_MEM 00101 int exp; 00102 float per; 00103 00104 exp = expected_memory(); /* in main.c ? */ 00105 per = ((lastused * 1.0) / (MEMTBLSIZE * 1.0)) * 100.0; 00106 dprintf(idx, "Memory table: %d/%d (%.1f%% full)\n", lastused, MEMTBLSIZE, 00107 per); 00108 per = ((exp * 1.0) / (memused * 1.0)) * 100.0; 00109 if (per != 100.0) 00110 dprintf(idx, "Memory fault: only accounting for %d/%ld (%.1f%%)\n", 00111 exp, memused, per); 00112 dprintf(idx, "Memory table itself occupies an additional %dk static\n", 00113 (int) (sizeof(memtbl) / 1024)); 00114 #endif 00115 }