cvs commit: apachen/src/main alloc.c
dgaudet 98/01/26 18:37:52 Modified:src/main alloc.c Log: more pool debugging -- copy_table() and overlay_tables() have implicit assumptions about the pool relationships of their arguments. There are actually some bugs in the core code I'll fix in a few minutes. Revision ChangesPath 1.70 +24 -0 apachen/src/main/alloc.c Index: alloc.c === RCS file: /export/home/cvs/apachen/src/main/alloc.c,v retrieving revision 1.69 retrieving revision 1.70 diff -u -r1.69 -r1.70 --- alloc.c 1998/01/26 19:50:10 1.69 +++ alloc.c 1998/01/27 02:37:51 1.70 @@ -873,6 +873,15 @@ { table *new = palloc(p, sizeof(table)); +#ifdef POOL_DEBUG +/* we don't copy keys and values, so it's necessary that t-a.pool + * have a life span at least as long as p + */ +if (!pool_is_ancestor(t-a.pool, p)) { + fprintf(stderr, copy_table: t's pool is not an ancestor of p\n); + abort(); +} +#endif make_array_core(new-a, p, t-a.nalloc, sizeof(table_entry)); memcpy(new-a.elts, t-a.elts, t-a.nelts * sizeof(table_entry)); new-a.nelts = t-a.nelts; @@ -1083,6 +1092,21 @@ API_EXPORT(table *) overlay_tables(pool *p, const table *overlay, const table *base) { table *res; + +#ifdef POOL_DEBUG +/* we don't copy keys and values, so it's necessary that + * overlay-a.pool and base-a.pool have a life span at least + * as long as p + */ +if (!pool_is_ancestor(overlay-a.pool, p)) { + fprintf(stderr, overlay_tables: overlay's pool is not an ancestor of p\n); + abort(); +} +if (!pool_is_ancestor(base-a.pool, p)) { + fprintf(stderr, overlay_tables: base's pool is not an ancestor of p\n); + abort(); +} +#endif res = palloc(p, sizeof(table)); /* behave like append_arrays */
cvs commit: apachen/src/main alloc.c
dgaudet 97/12/30 11:56:12 Modified:src/main alloc.c Log: another off-by-1 Revision ChangesPath 1.65 +1 -1 apachen/src/main/alloc.c Index: alloc.c === RCS file: /export/home/cvs/apachen/src/main/alloc.c,v retrieving revision 1.64 retrieving revision 1.65 diff -u -r1.64 -r1.65 --- alloc.c 1997/12/30 15:10:44 1.64 +++ alloc.c 1997/12/30 19:56:11 1.65 @@ -536,7 +536,7 @@ if (s == NULL) return NULL; res = palloc(a, n + 1); -ap_cpystrn(res, s, n); +ap_cpystrn(res, s, n + 1); return res; }
cvs commit: apachen/src/main alloc.c
ben 97/12/29 09:51:59 Modified:src CHANGES src/main alloc.c Log: Make table_{set,unset}() deal correctly with multiple occurrences of the same key. PR: 1604 Submitted by: Stephen Scheck [EMAIL PROTECTED], Ben Reviewed by: Ben Laurie Revision ChangesPath 1.551 +4 -0 apachen/src/CHANGES Index: CHANGES === RCS file: /export/home/cvs/apachen/src/CHANGES,v retrieving revision 1.550 retrieving revision 1.551 diff -u -r1.550 -r1.551 --- CHANGES 1997/12/28 04:50:59 1.550 +++ CHANGES 1997/12/29 17:51:51 1.551 @@ -1,5 +1,9 @@ Changes with Apache 1.3b4 + *) table_set() and table_unset() did not deal correctly with + multiple occurrences of the same key. [Stephen Scheck + [EMAIL PROTECTED], Ben Laurie] PR#1604 + *) Correct handling of quotation marks in AuthName realm names; as a byproduct, a new function: ap_escape_quotes(). [Ken Coar] PR#1195 1.63 +5 -2 apachen/src/main/alloc.c Index: alloc.c === RCS file: /export/home/cvs/apachen/src/main/alloc.c,v retrieving revision 1.62 retrieving revision 1.63 diff -u -r1.62 -r1.63 --- alloc.c 1997/12/26 23:25:46 1.62 +++ alloc.c 1997/12/29 17:51:57 1.63 @@ -732,11 +732,12 @@ table_entry *elts = (table_entry *) t-elts; int done = 0; -for (i = 0; i t-nelts; ++i) +for (i = 0; i t-nelts; ) if (!strcasecmp(elts[i].key, key)) { if (!done) { elts[i].val = pstrdup(t-pool, val); done = 1; + ++i; } else { /* delete an extraneous element */ for (j = i, k = i + 1; k t-nelts; ++j, ++k) { @@ -746,6 +747,7 @@ --t-nelts; } } + else ++i; if (!done) { elts = (table_entry *) push_array(t); @@ -759,7 +761,7 @@ register int i, j, k; table_entry *elts = (table_entry *) t-elts; -for (i = 0; i t-nelts; ++i) +for (i = 0; i t-nelts; ) if (!strcasecmp(elts[i].key, key)) { /* found an element to skip over @@ -773,6 +775,7 @@ } --t-nelts; } + else ++i; } API_EXPORT(void) table_merge(table *t, const char *key, const char *val)
cvs commit: apachen/src/main alloc.c
dgaudet 97/12/26 15:25:47 Modified:.STATUS src CHANGES src/main alloc.c Log: Interim (slow) fix for p-sub_pool critical sections in alloc.c. Affects win32 only. Submitted by: Ben Hyde Reviewed by: Dean Gaudet, Jim Jagielski Revision ChangesPath 1.35 +1 -9 apachen/STATUS Index: STATUS === RCS file: /export/home/cvs/apachen/STATUS,v retrieving revision 1.34 retrieving revision 1.35 diff -u -r1.34 -r1.35 --- STATUS1997/12/26 23:22:07 1.34 +++ STATUS1997/12/26 23:25:43 1.35 @@ -57,6 +57,7 @@ * Dean's [PATCH] fix Rasmus' chunking error * [PATCH] PR#1366: fix result of send_fd_length * Ben Hyde's [PATCH] Finish suite of mutex ops for non-threaded platforms +* Ben Hyde's [PATCH] Serialize the update to pool.sub_* in destroy_pool (take 2) Available: @@ -83,15 +84,6 @@ * Martin's [PATCH] 36kB: Make apache compile run on an EBCDIC mainframe [EMAIL PROTECTED] Status: Martin +1, Dean +1 - -* Ben Hyde's [PATCH] Serialize the update to pool.sub_* in destroy_pool - (take 2) - [EMAIL PROTECTED] - Status: Dean +1, Jim +1 - -* Dean's [PATCH] child_timeouts set wrong - [EMAIL PROTECTED] - Status: Jim +1, Dean +1 * Marc's [PATCH] PR#1543: suexec logging exec failures [EMAIL PROTECTED] 1.547 +3 -0 apachen/src/CHANGES Index: CHANGES === RCS file: /export/home/cvs/apachen/src/CHANGES,v retrieving revision 1.546 retrieving revision 1.547 diff -u -r1.546 -r1.547 --- CHANGES 1997/12/26 23:22:09 1.546 +++ CHANGES 1997/12/26 23:25:44 1.547 @@ -1,4 +1,7 @@ Changes with Apache 1.3b4 + + *) Interim (slow) fix for p-sub_pool critical sections in + alloc.c (affects win32 only). [Ben Hyde] *) non-WIN32 was missing destroy_mutex definition. [Ben Hyde] 1.62 +9 -3 apachen/src/main/alloc.c Index: alloc.c === RCS file: /export/home/cvs/apachen/src/main/alloc.c,v retrieving revision 1.61 retrieving revision 1.62 diff -u -r1.61 -r1.62 --- alloc.c 1997/12/14 20:48:54 1.61 +++ alloc.c 1997/12/26 23:25:46 1.62 @@ -376,11 +376,13 @@ { block_alarms(); +(void) acquire_mutex(alloc_mutex); +{ while (a-sub_pools) destroy_pool(a-sub_pools); - -a-sub_pools = NULL; - +} +(void) release_mutex(alloc_mutex); +/* Don't hold the mutex during cleanups. */ run_cleanups(a-cleanups); a-cleanups = NULL; free_proc_chain(a-subprocesses); @@ -413,6 +415,8 @@ block_alarms(); clear_pool(a); +(void) acquire_mutex(alloc_mutex); +{ if (a-parent) { if (a-parent-sub_pools == a) a-parent-sub_pools = a-sub_next; @@ -421,6 +425,8 @@ if (a-sub_next) a-sub_next-sub_prev = a-sub_prev; } +} +(void) release_mutex(alloc_mutex); free_blocks(a-first); unblock_alarms();
cvs commit: apachen/src/main alloc.c
ben 97/12/07 13:28:49 Modified:src CHANGES src/main alloc.c Log: Cure filehandle leak in Win32 CGI. PR: 1523 Submitted by: Peter Tillemans [EMAIL PROTECTED] Revision ChangesPath 1.523 +2 -0 apachen/src/CHANGES Index: CHANGES === RCS file: /export/home/cvs/apachen/src/CHANGES,v retrieving revision 1.522 retrieving revision 1.523 diff -u -r1.522 -r1.523 --- CHANGES 1997/11/25 22:00:40 1.522 +++ CHANGES 1997/12/07 21:28:46 1.523 @@ -1,5 +1,7 @@ Changes with Apache 1.3b4 + *) WIN32: Cure file leak in CGIs. [Peter Tillemans [EMAIL PROTECTED]] PR#1523 + *) proxy_ftp: the directory listings generated by the proxy ftp module now have a title in which the path components are clickable and allow quick navigation to the clicked-on directory on the currently listed 1.59 +9 -0 apachen/src/main/alloc.c Index: alloc.c === RCS file: /export/home/cvs/apachen/src/main/alloc.c,v retrieving revision 1.58 retrieving revision 1.59 diff -u -r1.58 -r1.59 --- alloc.c 1997/11/12 23:22:05 1.58 +++ alloc.c 1997/12/07 21:28:48 1.59 @@ -1318,11 +1318,20 @@ /* restore the original stdin, stdout and stderr */ if (pipe_in) + { dup2(hStdIn, fileno(stdin)); + close(hStdIn); + } if (pipe_out) + { dup2(hStdOut, fileno(stdout)); + close(hStdOut); + } if (pipe_err) + { dup2(hStdErr, fileno(stderr)); + close(hStdErr); + } if (pid) { note_subprocess(p, pid, kill_how);
cvs commit: apachen/src/main alloc.c
ben 97/12/07 13:33:19 Modified:src/main alloc.c Log: Arg! Oh God! Get the formatting right before righteous bolts smite me. Revision ChangesPath 1.60 +6 -9 apachen/src/main/alloc.c Index: alloc.c === RCS file: /export/home/cvs/apachen/src/main/alloc.c,v retrieving revision 1.59 retrieving revision 1.60 diff -u -r1.59 -r1.60 --- alloc.c 1997/12/07 21:28:48 1.59 +++ alloc.c 1997/12/07 21:33:18 1.60 @@ -1317,21 +1317,18 @@ } /* restore the original stdin, stdout and stderr */ - if (pipe_in) - { + if (pipe_in) { dup2(hStdIn, fileno(stdin)); close(hStdIn); - } - if (pipe_out) - { +} + if (pipe_out) { dup2(hStdOut, fileno(stdout)); close(hStdOut); - } - if (pipe_err) - { + } + if (pipe_err) { dup2(hStdErr, fileno(stderr)); close(hStdErr); - } + } if (pid) { note_subprocess(p, pid, kill_how);
Re: cvs commit: apachen/src/main alloc.c
On 7 Dec 1997 [EMAIL PROTECTED] wrote: ben 97/12/07 13:28:49 Modified:src CHANGES src/main alloc.c Log: Cure filehandle leak in Win32 CGI. PR: 1523 Submitted by: Peter Tillemans [EMAIL PROTECTED] Revision ChangesPath 1.523 +2 -0 apachen/src/CHANGES I think there are another couple of PRs complaining about this somewhere. They should be closed too. I, however, am another one of those odd people studying for finals.
cvs commit: apachen/src/main alloc.c alloc.h http_main.c
dgaudet 97/11/12 15:22:09 Modified:src CHANGES src/main alloc.c alloc.h http_main.c Log: Create the pchild pool which is created before child_init and destroyed after child_exit. This fixes a bug with reliable piped logs. Reviewed by: Jim Jagielski, Roy Fielding Revision ChangesPath 1.507 +8 -0 apachen/src/CHANGES Index: CHANGES === RCS file: /export/home/cvs/apachen/src/CHANGES,v retrieving revision 1.506 retrieving revision 1.507 diff -u -r1.506 -r1.507 --- CHANGES 1997/11/12 21:37:43 1.506 +++ CHANGES 1997/11/12 23:22:03 1.507 @@ -1,5 +1,13 @@ Changes with Apache 1.3b3 + *) It was necessary to distinguish between resources which are + allocated in the parent, for cleanup in the parent, and resources + which are allocated in each child, for cleanup in each child. + A new pool was created which is passed to the module child_init + and child_exit functions; modules are free to register per-child + cleanups there. This fixes a bug with reliable piped logs. + [Dean Gaudet] + *) mod_autoindex wasn't displaying the ReadmeName file at the bottom unless it was also doing FancyIndexes, but it displayed the HeaderName file at the top under all circumstances. It now shows 1.58 +5 -0 apachen/src/main/alloc.c Index: alloc.c === RCS file: /export/home/cvs/apachen/src/main/alloc.c,v retrieving revision 1.57 retrieving revision 1.58 diff -u -r1.57 -r1.58 --- alloc.c 1997/11/06 21:54:07 1.57 +++ alloc.c 1997/11/12 23:22:05 1.58 @@ -936,6 +936,11 @@ #endif /* ndef WIN32 */ } +API_EXPORT(void) null_cleanup(void *data) +{ +/* do nothing cleanup routine */ +} + /* * * Files and file descriptors; these are just an application of the 1.37 +4 -0 apachen/src/main/alloc.h Index: alloc.h === RCS file: /export/home/cvs/apachen/src/main/alloc.h,v retrieving revision 1.36 retrieving revision 1.37 diff -u -r1.36 -r1.37 --- alloc.h 1997/10/26 21:14:16 1.36 +++ alloc.h 1997/11/12 23:22:06 1.37 @@ -194,6 +194,10 @@ API_EXPORT(void) kill_cleanup(pool *p, void *data, void (*plain_cleanup) (void *)); API_EXPORT(void) run_cleanup(pool *p, void *data, void (*cleanup) (void *)); +/* A do-nothing cleanup, for register_cleanup; it's faster to do + * things this way than to test for NULL. */ +API_EXPORT(void) null_cleanup(void *data); + /* The time between when a resource is actually allocated, and when it * its cleanup is registered is a critical section, during which the * resource could leak if we got interrupted or timed out. So, anything 1.249 +55 -61apachen/src/main/http_main.c Index: http_main.c === RCS file: /export/home/cvs/apachen/src/main/http_main.c,v retrieving revision 1.248 retrieving revision 1.249 diff -u -r1.248 -r1.249 --- http_main.c 1997/11/11 22:50:13 1.248 +++ http_main.c 1997/11/12 23:22:07 1.249 @@ -240,8 +240,9 @@ static other_child_rec *other_children; #endif -pool *pconf; /* Pool for config stuff */ -pool *ptrans;/* Pool for per-transaction stuff */ +static pool *pconf; /* Pool for config stuff */ +static pool *ptrans; /* Pool for per-transaction stuff */ +static pool *pchild; /* Pool for httpd child stuff */ int APACHE_TLS my_pid; /* it seems silly to call getpid all the time */ #ifndef MULTITHREAD @@ -278,8 +279,6 @@ static ulock_t uslock = NULL; -#define accept_mutex_cleanup() - #define accept_mutex_child_init(x) static void accept_mutex_init(pool *p) @@ -351,7 +350,7 @@ static sigset_t accept_block_mask; static sigset_t accept_previous_mask; -static void accept_mutex_child_cleanup(void *data) +static void accept_mutex_child_cleanup(void *foo) { if (accept_mutex != (void *)(caddr_t)-1 have_accept_mutex) { @@ -359,7 +358,12 @@ } } -static void accept_mutex_cleanup(void) +static void accept_mutex_child_init(pool *p) +{ +register_cleanup(p, NULL, accept_mutex_child_cleanup, null_cleanup); +} + +static void accept_mutex_cleanup(void *foo) { if (accept_mutex != (void *)(caddr_t)-1 munmap((caddr_t) accept_mutex, sizeof(*accept_mutex))) { @@ -368,8 +372,6 @@ accept_mutex = (void *)(caddr_t)-1; } -#define accept_mutex_child_init(x) - static void accept_mutex_init(pool
cvs commit: apachen/src/main alloc.c util_script.c
ben 97/10/20 05:09:00 Modified:src/main alloc.c util_script.c Log: Fix CGI under Win95 (plus some error checking). This needs doing more carefully. Revision ChangesPath 1.52 +18 -10apachen/src/main/alloc.c Index: alloc.c === RCS file: /export/home/cvs/apachen/src/main/alloc.c,v retrieving revision 1.51 retrieving revision 1.52 diff -u -r1.51 -r1.52 --- alloc.c 1997/10/15 00:25:14 1.51 +++ alloc.c 1997/10/20 12:08:58 1.52 @@ -60,6 +60,7 @@ #include httpd.h #include multithread.h +#include http_log.h #include stdarg.h @@ -1217,9 +1218,9 @@ } #ifdef WIN32 -#define enc_pipe(fds) _pipe(fds, 512, O_TEXT | O_NOINHERIT) +#define os_pipe(fds) _pipe(fds, 512, O_BINARY | O_NOINHERIT) #else -#define enc_pipe(fds) pipe(fds) +#define os_pipe(fds) pipe(fds) #endif /* WIN32 */ /* for fdopen, to get binary mode */ @@ -1239,11 +1240,11 @@ int err_fds[2]; int save_errno; -if (pipe_in enc_pipe(in_fds) 0) { +if (pipe_in os_pipe(in_fds) 0) { return 0; } -if (pipe_out enc_pipe(out_fds) 0) { +if (pipe_out os_pipe(out_fds) 0) { save_errno = errno; if (pipe_in) { close(in_fds[0]); @@ -1253,7 +1254,7 @@ return 0; } -if (pipe_err enc_pipe(err_fds) 0) { +if (pipe_err os_pipe(err_fds) 0) { save_errno = errno; if (pipe_in) { close(in_fds[0]); @@ -1281,22 +1282,27 @@ /* Now do the right thing with your pipes */ if (pipe_in) { hStdIn = dup(fileno(stdin)); - dup2(in_fds[0], fileno(stdin)); + if(dup2(in_fds[0], fileno(stdin))) + aplog_error(APLOG_MARK, APLOG_ERR, NULL, dup2(stdin) failed); close(in_fds[0]); } if (pipe_out) { hStdOut = dup(fileno(stdout)); - dup2(out_fds[1], fileno(stdout)); + close(fileno(stdout)); + if(dup2(out_fds[1], fileno(stdout))) + aplog_error(APLOG_MARK, APLOG_ERR, NULL, dup2(stdout) failed); close(out_fds[1]); } if (pipe_err) { hStdErr = dup(fileno(stderr)); - dup2(err_fds[1], fileno(stderr)); + if(dup2(err_fds[1], fileno(stderr))) + aplog_error(APLOG_MARK, APLOG_ERR, NULL, dup2(stdin) failed); close(err_fds[1]); } pid = (*func) (data); - if (!pid) { + if (pid == -1) { + /* If we are going to save it, we ought to do something with it later, right? - Ben */ save_errno = errno; close(in_fds[1]); close(out_fds[0]); @@ -1311,7 +1317,9 @@ if (pipe_err) dup2(hStdErr, fileno(stderr)); - if (pid) { + if(pid == -1) + aplog_error(APLOG_MARK, APLOG_ERR, NULL, spawn failed); + else { note_subprocess(p, pid, kill_how); if (pipe_in) { *pipe_in = in_fds[1]; 1.79 +6 -0 apachen/src/main/util_script.c Index: util_script.c === RCS file: /export/home/cvs/apachen/src/main/util_script.c,v retrieving revision 1.78 retrieving revision 1.79 diff -u -r1.78 -r1.79 --- util_script.c 1997/10/15 23:37:47 1.78 +++ util_script.c 1997/10/20 12:08:59 1.79 @@ -668,6 +668,7 @@ int i, sz; char *dot; char *exename; + char *s; int is_exe = 0; interpreter[0] = 0; @@ -732,6 +733,11 @@ } } + /* FIXME: Probably ought to do this in another buffer - Ben */ + /* This really annoys me - Win95 (and not NT) spawn[vl]e don't like '/'! - Ben */ + for(s=r-filename ; *s ; ++s) + if(*s == '/') + *s='\\'; if ((!r-args) || (!r-args[0]) || (ind(r-args, '=') = 0)) { if (is_exe || is_binary) {
cvs commit: apachen/src/main alloc.c
pcs 97/10/20 13:02:21 Modified:src/main alloc.c Log: Prevent unnecessary premature end of headers errors on Win32 by correctly spotting if a spawned CGI fails, and if so, using the normal Unix logging to note it. Specifically make the Win32 error return value from spawn*() of -1 onto the Unix error value of 0 within the Win32 code. Revision ChangesPath 1.53 +4 -5 apachen/src/main/alloc.c Index: alloc.c === RCS file: /export/home/cvs/apachen/src/main/alloc.c,v retrieving revision 1.52 retrieving revision 1.53 diff -u -r1.52 -r1.53 --- alloc.c 1997/10/20 12:08:58 1.52 +++ alloc.c 1997/10/20 20:02:20 1.53 @@ -1301,8 +1301,9 @@ } pid = (*func) (data); - if (pid == -1) { - /* If we are going to save it, we ought to do something with it later, right? - Ben */ +if (pid == -1) pid = 0; // map Win32 error code onto Unix default + +if (!pid) { save_errno = errno; close(in_fds[1]); close(out_fds[0]); @@ -1317,9 +1318,7 @@ if (pipe_err) dup2(hStdErr, fileno(stderr)); - if(pid == -1) - aplog_error(APLOG_MARK, APLOG_ERR, NULL, spawn failed); - else { +if (pid) { note_subprocess(p, pid, kill_how); if (pipe_in) { *pipe_in = in_fds[1];
cvs commit: apachen/src/main alloc.c
pcs 97/10/20 13:31:59 Modified:src/main alloc.c Log: Remove C++ comment Revision ChangesPath 1.54 +1 -1 apachen/src/main/alloc.c Index: alloc.c === RCS file: /export/home/cvs/apachen/src/main/alloc.c,v retrieving revision 1.53 retrieving revision 1.54 diff -u -r1.53 -r1.54 --- alloc.c 1997/10/20 20:02:20 1.53 +++ alloc.c 1997/10/20 20:31:58 1.54 @@ -1301,7 +1301,7 @@ } pid = (*func) (data); -if (pid == -1) pid = 0; // map Win32 error code onto Unix default +if (pid == -1) pid = 0; /* map Win32 error code onto Unix default */ if (!pid) { save_errno = errno;
cvs commit: apachen/src/main alloc.c
dgaudet 97/10/14 17:19:36 Modified:src/main alloc.c Log: Add in alloc debugging code which can be used standalone to detect some uninitialized read, and use-after-free errors. It can also be combined with debuggers like efence and Purify. By default nothing should change. This change introduces one change to the non-debugging code: -blok = new_block(0); +blok = new_block(POOL_HDR_BYTES); This is during make_sub_pool. Technically speaking, this fixes a bug; the bug was that make_sub_pool was assuming that BLOCK_MINALLOC POOL_HDR_BYTES. Not an unreasonable assumption ... but the debugging code sets BLOCK_MINALLOC to 0. Reviewed by: Jim Jagielski, Rob Hartill, Martin Kraemer Revision ChangesPath 1.50 +109 -5apachen/src/main/alloc.c Index: alloc.c === RCS file: /export/home/cvs/apachen/src/main/alloc.c,v retrieving revision 1.49 retrieving revision 1.50 diff -u -r1.49 -r1.50 --- alloc.c 1997/10/05 02:06:36 1.49 +++ alloc.c 1997/10/15 00:19:35 1.50 @@ -63,6 +63,37 @@ #include stdarg.h +/* debugging support, define this to enable code which helps detect re-use + * of freed memory and other such nonsense. + * + * The theory is simple. The FILL_BYTE (0xa5) is written over all malloc'd + * memory as we receive it, and is written over everything that we free up + * during a clear_pool. We check that blocks on the free list always + * have the FILL_BYTE in them, and we check during palloc() that the bytes + * still have FILL_BYTE in them. If you ever see garbage URLs or whatnot + * containing lots of 0xa5s then you know something used data that's been + * freed. + */ +/* #define ALLOC_DEBUG */ + +/* debugging support, if defined all allocations will be done with + * malloc and free()d appropriately at the end. This is intended to be + * used with something like Electric Fence or Purify to help detect + * memory problems. Note that if you're using efence then you should also + * add in ALLOC_DEBUG. But don't add in ALLOC_DEBUG if you're using Purify + * because ALLOC_DEBUG would hide all the uninitialized read errors that + * Purify can diagnose. + */ +/* #define ALLOC_USE_MALLOC */ + +#ifdef ALLOC_USE_MALLOC +#undef BLOCK_MINFREE +#undef BLOCK_MINALLOC +#define BLOCK_MINFREE0 +#define BLOCK_MINALLOC 0 +#endif + + /* * * Managing free storage blocks... @@ -98,6 +129,28 @@ mutex *alloc_mutex = NULL; mutex *spawn_mutex = NULL; +#ifdef ALLOC_DEBUG +#define FILL_BYTE((char)(0xa5)) + +#define debug_fill(ptr,size) ((void)memset((ptr), FILL_BYTE, (size))) + +static ap_inline void debug_verify_filled(const char *ptr, +const char *endp, const char *error_msg) +{ +for (; ptr endp; ++ptr) { + if (*ptr != FILL_BYTE) { + fputs(error_msg, stderr); + abort(); + exit(1); + } +} +} + +#else +#define debug_fill(a,b) +#define debug_verify_filled(a,b,c) +#endif + /* Get a completely new block from the system pool. Note that we rely on malloc() to provide aligned memory. */ @@ -111,6 +164,7 @@ fprintf(stderr, Ouch! malloc failed in malloc_block()\n); exit(1); } +debug_fill(blok, size + sizeof(union block_hdr)); blok-h.next = NULL; blok-h.first_avail = (char *) (blok + 1); blok-h.endp = size + blok-h.first_avail; @@ -138,6 +192,14 @@ void free_blocks(union block_hdr *blok) { +#ifdef ALLOC_USE_MALLOC +union block_hdr *next; + +for (; blok; blok = next) { + next = blok-h.next; + free(blok); +} +#else /* First, put new blocks at the head of the free list --- * we'll eventually bash the 'next' pointer of the last block * in the chain to point to the free blocks we already had. @@ -161,21 +223,22 @@ while (blok-h.next != NULL) { chk_on_blk_list(blok, old_free_list); blok-h.first_avail = (char *) (blok + 1); + debug_fill(blok-h.first_avail, blok-h.endp - blok-h.first_avail); blok = blok-h.next; } chk_on_blk_list(blok, old_free_list); blok-h.first_avail = (char *) (blok + 1); +debug_fill(blok-h.first_avail, blok-h.endp - blok-h.first_avail); /* Finally, reset next pointer to get the old free blocks back */ blok-h.next = old_free_list; (void) release_mutex(alloc_mutex); +#endif } - - /* Get a new block, from our own free list if possible, from the system * if necessary. Must be called with alarms blocked. */ @@ -193,6 +256,8 @@ if (min_size + BLOCK_MINFREE = blok-h.endp - blok-h.first_avail) { *lastptr = blok-h.next;
cvs commit: apachen/src/main alloc.c http_main.c
dgaudet 97/10/04 19:06:39 Modified:src/main alloc.c http_main.c Log: Fix Ouch! Freeing free block error. Beef up sigsegv/bus handler to also deal with sigabort/sigabrt and not get into an infinite loop. Reviewed by: Rob Hartill Revision ChangesPath 1.49 +1 -0 apachen/src/main/alloc.c Index: alloc.c === RCS file: /export/home/cvs/apachen/src/main/alloc.c,v retrieving revision 1.48 retrieving revision 1.49 diff -u -r1.48 -r1.49 --- alloc.c 1997/09/14 11:36:33 1.48 +++ alloc.c 1997/10/05 02:06:36 1.49 @@ -127,6 +127,7 @@ while (free_blk) { if (free_blk == blok) { fprintf(stderr, Ouch! Freeing free block\n); + abort(); exit(1); } free_blk = free_blk-h.next; 1.230 +54 -18apachen/src/main/http_main.c Index: http_main.c === RCS file: /export/home/cvs/apachen/src/main/http_main.c,v retrieving revision 1.229 retrieving revision 1.230 diff -u -r1.229 -r1.230 --- http_main.c 1997/10/05 02:02:38 1.229 +++ http_main.c 1997/10/05 02:06:37 1.230 @@ -769,6 +769,7 @@ --alarms_blocked; if (alarms_blocked == 0) { if (exit_after_unblock) { + exit_after_unblock = 0; child_exit_modules(pconf, server_conf); destroy_pool(pconf); exit(0); @@ -1911,26 +1912,46 @@ } -void bus_error(int sig) +/* handle all varieties of core dumping signals */ +void sig_coredump(int sig) { char emsg[256]; +const char *s; -ap_snprintf(emsg, sizeof(emsg), - httpd: caught SIGBUS, attempting to dump core in %s, - coredump_dir); -aplog_error(APLOG_MARK, APLOG_INFO, server_conf, emsg); -chdir(coredump_dir); -abort(); -exit(1); -} +/* Must protect against a nested signal, otherwise we could end up in + * an infinite loop. + */ +signal(SIGSEGV, SIG_DFL); +#ifdef SIGBUS +signal(SIGBUS, SIG_DFL); +#endif +#ifdef SIGABORT +signal(SIGABORT, SIG_DFL); +#endif +#ifdef SIGABRT +signal(SIGABRT, SIG_DFL); +#endif -void seg_fault(int sig) -{ -char emsg[256]; +s = SIGSEGV; +#ifdef SIGBUS +if (sig == SIGBUS) { + s = SIGBUS; +} +#endif +#ifdef SIGABORT +if (sig == SIGABORT) { + s = SIGABORT; +} +#endif +#ifdef SIGABRT +if (sig == SIGABRT) { + s = SIGABRT; +} +#endif ap_snprintf(emsg, sizeof(emsg), - httpd: caught SIGSEGV, attempting to dump core in %s, - coredump_dir); + httpd: caught %s, attempting to dump core in %s, + s, coredump_dir); aplog_error(APLOG_MARK, APLOG_INFO, server_conf, emsg); chdir(coredump_dir); abort(); @@ -1997,12 +2018,21 @@ sa.sa_flags = 0; if (!one_process) { - sa.sa_handler = seg_fault; + sa.sa_handler = sig_coredump; if (sigaction(SIGSEGV, sa, NULL) 0) aplog_error(APLOG_MARK, APLOG_WARNING, server_conf, sigaction(SIGSEGV)); - sa.sa_handler = bus_error; +#ifdef SIGBUS if (sigaction(SIGBUS, sa, NULL) 0) aplog_error(APLOG_MARK, APLOG_WARNING, server_conf, sigaction(SIGBUS)); +#endif +#ifdef SIGABORT + if (sigaction(SIGABORT, sa, NULL) 0) + aplog_error(APLOG_MARK, APLOG_WARNING, server_conf, sigaction(SIGABORT)); +#endif +#ifdef SIGABRT + if (sigaction(SIGABRT, sa, NULL) 0) + aplog_error(APLOG_MARK, APLOG_WARNING, server_conf, sigaction(SIGABRT)); +#endif } sa.sa_handler = sig_term; if (sigaction(SIGTERM, sa, NULL) 0) @@ -2018,10 +2048,16 @@ aplog_error(APLOG_MARK, APLOG_WARNING, server_conf, sigaction(SIGUSR1)); #else if (!one_process) { - signal(SIGSEGV, seg_fault); + signal(SIGSEGV, sig_coredump); #ifdef SIGBUS - signal(SIGBUS, bus_error); + signal(SIGBUS, sig_coredump); #endif /* SIGBUS */ +#ifdef SIGABORT + signal(SIGABORT, sig_coredump); +#endif /* SIGABORT */ +#ifdef SIGABRT + signal(SIGABRT, sig_coredump); +#endif /* SIGABRT */ } signal(SIGTERM, sig_term);
cvs commit: apachen/src/main alloc.c alloc.h
dgaudet 97/09/14 04:36:34 Modified:src INDENT src/main alloc.c alloc.h Log: indent Revision ChangesPath 1.8 +2 -2 apachen/src/INDENT Index: INDENT === RCS file: /export/home/cvs/apachen/src/INDENT,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- INDENT1997/09/14 11:13:51 1.7 +++ INDENT1997/09/14 11:36:32 1.8 @@ -3,8 +3,8 @@ If a file has already been indent'd, or doesn't need it, mark it as DONE ./main: STATUS - alloc.c RESERVED by Dean - alloc.h RESERVED by Dean + alloc.c DONE by Dean + alloc.h DONE by Dean buff.cDONE by Dean buff.hDONE by Dean conf.h 1.48 +854 -808 apachen/src/main/alloc.c Index: alloc.c === RCS file: /export/home/cvs/apachen/src/main/alloc.c,v retrieving revision 1.47 retrieving revision 1.48 diff -u -r1.47 -r1.48 --- alloc.c 1997/08/20 01:22:50 1.47 +++ alloc.c 1997/09/14 11:36:33 1.48 @@ -68,32 +68,30 @@ * Managing free storage blocks... */ -union align -{ - /* Types which are likely to have the longest RELEVANT alignment - * restrictions... - */ - - char *cp; - void (*f)(void); - long l; - FILE *fp; - double d; +union align { +/* Types which are likely to have the longest RELEVANT alignment + * restrictions... + */ + +char *cp; +void (*f) (void); +long l; +FILE *fp; +double d; }; #define CLICK_SZ (sizeof(union align)) -union block_hdr -{ - union align a; - - /* Actual header... */ - - struct { -char *endp; -union block_hdr *next; -char *first_avail; - } h; +union block_hdr { +union align a; + +/* Actual header... */ + +struct { + char *endp; + union block_hdr *next; + char *first_avail; +} h; }; union block_hdr *block_freelist = NULL; @@ -102,75 +100,76 @@ /* Get a completely new block from the system pool. Note that we rely on -malloc() to provide aligned memory. */ + malloc() to provide aligned memory. */ -union block_hdr *malloc_block (int size) +union block_hdr *malloc_block(int size) { - union block_hdr *blok = -(union block_hdr *)malloc(size + sizeof(union block_hdr)); +union block_hdr *blok = +(union block_hdr *) malloc(size + sizeof(union block_hdr)); + +if (blok == NULL) { + fprintf(stderr, Ouch! malloc failed in malloc_block()\n); + exit(1); +} +blok-h.next = NULL; +blok-h.first_avail = (char *) (blok + 1); +blok-h.endp = size + blok-h.first_avail; - if (blok == NULL) { - fprintf (stderr, Ouch! malloc failed in malloc_block()\n); - exit (1); - } - blok-h.next = NULL; - blok-h.first_avail = (char *)(blok + 1); - blok-h.endp = size + blok-h.first_avail; - - return blok; +return blok; } -void chk_on_blk_list (union block_hdr *blok, union block_hdr *free_blk) +void chk_on_blk_list(union block_hdr *blok, union block_hdr *free_blk) { - /* Debugging code. Left in for the moment. */ - - while (free_blk) { -if (free_blk == blok) { - fprintf (stderr, Ouch! Freeing free block\n); - exit (1); +/* Debugging code. Left in for the moment. */ + +while (free_blk) { + if (free_blk == blok) { + fprintf(stderr, Ouch! Freeing free block\n); + exit(1); + } + free_blk = free_blk-h.next; } -free_blk = free_blk-h.next; - } } /* Free a chain of blocks --- must be called with alarms blocked. */ -void free_blocks (union block_hdr *blok) +void free_blocks(union block_hdr *blok) { - /* First, put new blocks at the head of the free list --- - * we'll eventually bash the 'next' pointer of the last block - * in the chain to point to the free blocks we already had. - */ - - union block_hdr *old_free_list; - - if (blok == NULL) return; /* Sanity check --- freeing empty pool? */ - - (void)acquire_mutex(alloc_mutex); - old_free_list = block_freelist; - block_freelist = blok; - - /* - * Next, adjust first_avail pointers of each block --- have to do it - * sooner or later, and it simplifies the search in new_block to do it - * now. - */ - - while (blok-h.next != NULL) { -chk_on_blk_list (blok, old_free_list); -blok-h.first_avail = (char *)(blok + 1); -blok = blok-h.next; - } +/* First, put new blocks at the head of the free list --- + * we'll