there will be a large amount, so this might not be very useful.
*/
-#if defined (EMACS_BTL) && defined (sun4) && !defined (__lucid)
-/* currently only works in this configuration */
-# define SAVE_STACK
-#endif
-
#ifdef emacs
-#ifdef SAVE_STACK
-#include "cadillac-btl.h"
-#endif
#include <config.h>
#include "lisp.h"
#else
-void *malloc (unsigned long);
+void *malloc (size_t);
#endif
#if !defined(HAVE_LIBMCHECK)
/* System function prototypes don't belong in C source files */
/* extern void free (void *); */
-c_hashtable pointer_table;
+static struct hash_table *pointer_table;
extern void (*__free_hook) (void *);
-extern void *(*__malloc_hook) (unsigned long);
+extern void *(*__malloc_hook) (size_t);
-static void *check_malloc (unsigned long);
+static void *check_malloc (size_t);
-typedef void (*fun_ptr) ();
+typedef void (*fun_ptr) (void);
-#ifdef SAVE_STACK
-#define FREE_QUEUE_LIMIT 1000
-#else
/* free_queue is not too useful without backtrace logging */
#define FREE_QUEUE_LIMIT 1
-#endif
#define TRACE_LIMIT 20
typedef struct {
typedef struct {
void *address;
unsigned long length;
-#ifdef SAVE_STACK
- fun_entry backtrace[TRACE_LIMIT];
-#endif
} free_queue_entry;
-free_queue_entry free_queue[FREE_QUEUE_LIMIT];
+static free_queue_entry free_queue[FREE_QUEUE_LIMIT];
-int current_free;
+static int current_free;
-#ifdef SAVE_STACK
-static void
-init_frame (FRAME *fptr)
-{
- FRAME tmp_frame;
-
-#ifdef sparc
- /* Do the system trap ST_FLUSH_WINDOWS */
- asm ("ta 3");
- asm ("st %sp, [%i0+0]");
- asm ("st %fp, [%i0+4]");
-#endif
-
- fptr->pc = (char *) init_frame;
- tmp_frame = *fptr;
-
- PREVIOUS_FRAME (tmp_frame);
-
- *fptr = tmp_frame;
- return;
-}
-
-#ifdef SAVE_ARGS
-static void *
-frame_arg (FRAME *fptr, int index)
-{
- return ((void *) FRAME_ARG(*fptr, index));
-}
-#endif
-
-static void
-save_backtrace (FRAME *current_frame_ptr, fun_entry *table)
-{
- int i = 0;
-#ifdef SAVE_ARGS
- int j;
-#endif
- FRAME current_frame = *current_frame_ptr;
-
- /* Get up and out of free() */
- PREVIOUS_FRAME (current_frame);
-
- /* now do the basic loop adding data until there is no more */
- while (PREVIOUS_FRAME (current_frame) && i < TRACE_LIMIT)
- {
- table[i].return_pc = (void (*)())FRAME_PC (current_frame);
-#ifdef SAVE_ARGS
- for (j = 0; j < 3; j++)
- table[i].arg[j] = frame_arg (¤t_frame, j);
-#endif
- i++;
- }
- memset (&table[i], 0, sizeof (fun_entry) * (TRACE_LIMIT - i));
-}
-
-free_queue_entry *
-find_backtrace (void *ptr)
-{
- int i;
-
- for (i = 0; i < FREE_QUEUE_LIMIT; i++)
- if (free_queue[i].address == ptr)
- return &free_queue[i];
-
- return 0;
-}
-#endif /* SAVE_STACK */
-
-int strict_free_check;
+static int strict_free_check;
static void
check_free (void *ptr)
{
-#ifdef SAVE_STACK
- FRAME start_frame;
-
- init_frame (&start_frame);
-#endif
-
__free_hook = 0;
__malloc_hook = 0;
if (!pointer_table)
- pointer_table = make_hashtable (max (100, FREE_QUEUE_LIMIT * 2));
+ pointer_table = make_hash_table (max (100, FREE_QUEUE_LIMIT * 2));
if (ptr != 0)
{
long size;
#endif
EMACS_INT present = (EMACS_INT) gethash (ptr, pointer_table,
- (CONST void **) &size);
+ (const void **) &size);
if (!present)
{
#endif
free_queue[current_free].address = ptr;
free_queue[current_free].length = size;
-#ifdef SAVE_STACK
- save_backtrace (&start_frame,
- free_queue[current_free].backtrace);
-#endif
+
current_free++;
if (current_free >= FREE_QUEUE_LIMIT)
current_free = 0;
}
static void *
-check_malloc (unsigned long size)
+check_malloc (size_t size)
{
- unsigned long rounded_up_size;
+ size_t rounded_up_size;
void *result;
__free_hook = 0;
#endif
result = malloc (rounded_up_size);
if (!pointer_table)
- pointer_table = make_hashtable (FREE_QUEUE_LIMIT * 2);
+ pointer_table = make_hash_table (FREE_QUEUE_LIMIT * 2);
puthash (result, (void *)size, pointer_table);
__free_hook = check_free;
__malloc_hook = check_malloc;
return result;
}
-extern void *(*__realloc_hook) (void *, unsigned long);
+extern void *(*__realloc_hook) (void *, size_t);
#ifdef MIN
#undef MIN
/* Don't optimize realloc */
static void *
-check_realloc (void * ptr, unsigned long size)
+check_realloc (void * ptr, size_t size)
{
EMACS_INT present;
- unsigned long old_size;
+ size_t old_size;
void *result = malloc (size);
if (!ptr) return result;
- present = (EMACS_INT) gethash (ptr, pointer_table, (CONST void **) &old_size);
+ present = (EMACS_INT) gethash (ptr, pointer_table, (const void **) &old_size);
if (!present)
{
/* This can only happen by reallocing a pointer that didn't
completely gone in XEmacs */
static void *
-block_input_malloc (unsigned long size);
+block_input_malloc (size_t size);
static void
block_input_free (void* ptr)
}
static void *
-block_input_malloc (unsigned long size)
+block_input_malloc (size_t size)
{
void* result;
__free_hook = 0;
static void *
-block_input_realloc (void* ptr, unsigned long size)
+block_input_realloc (void* ptr, size_t size)
{
void* result;
__free_hook = 0;
}
#else
-void (*__free_hook)() = check_free;
-void *(*__malloc_hook)() = check_malloc;
-void *(*__realloc_hook)() = check_realloc;
+void (*__free_hook)(void *) = check_free;
+void *(*__malloc_hook)(size_t) = check_malloc;
+void *(*__realloc_hook)(void *, size_t) = check_realloc;
#endif
#endif /* !defined(HAVE_LIBMCHECK) */
/* Note: There is no more input blocking in XEmacs */
typedef enum {
block_type, unblock_type, totally_type,
- gcpro1_type, gcpro2_type, gcpro3_type, gcpro4_type, ungcpro_type
+ gcpro1_type, gcpro2_type, gcpro3_type, gcpro4_type, gcpro5_type,
+ ungcpro_type
} blocktype;
struct block_input_history_struct
int line;
blocktype type;
int value;
-#ifdef SAVE_STACK
- fun_entry backtrace[TRACE_LIMIT];
-#endif
};
typedef struct block_input_history_struct block_input_history;
-#endif
+#endif /* DEBUG_INPUT_BLOCKING || DEBUG_GCPRO */
#ifdef DEBUG_INPUT_BLOCKING
note_block (char *file, int line, blocktype type)
{
-#ifdef SAVE_STACK
- FRAME start_frame;
-
- init_frame (&start_frame);
-#endif
-
blhist[blhistptr].file = file;
blhist[blhistptr].line = line;
blhist[blhistptr].type = type;
blhist[blhistptr].value = interrupt_input_blocked;
-#ifdef SAVE_STACK
- save_backtrace (&start_frame,
- blhist[blhistptr].backtrace);
-#endif
-
blhistptr++;
if (blhistptr >= BLHISTLIMIT)
blhistptr = 0;
}
-#endif
+#endif /* DEBUG_INPUT_BLOCKING */
\f
#ifdef DEBUG_GCPRO
static void
log_gcpro (char *file, int line, struct gcpro *value, blocktype type)
{
- FRAME start_frame;
-
if (type == ungcpro_type)
{
if (value == gcprolist) goto OK;
if (value == gcprolist->next->next) goto OK;
if (! gcprolist->next->next) abort ();
if (value == gcprolist->next->next->next) goto OK;
+ if (! gcprolist->next->next->next) abort ();
+ if (value == gcprolist->next->next->next->next) goto OK;
abort ();
OK:;
}
-#ifdef SAVE_STACK
- init_frame (&start_frame);
-#endif
gcprohist[gcprohistptr].file = file;
gcprohist[gcprohistptr].line = line;
gcprohist[gcprohistptr].type = type;
gcprohist[gcprohistptr].value = (int) value;
-#ifdef SAVE_STACK
- save_backtrace (&start_frame, gcprohist[gcprohistptr].backtrace);
-#endif
gcprohistptr++;
if (gcprohistptr >= GCPROHISTLIMIT)
gcprohistptr = 0;
gcprolist = gcpro1->next;
}
+
+/* To be called from the debugger */
+void show_gcprohist (void);
void
show_gcprohist (void)
{
gcprohist[j].type == gcpro2_type ? "GCPRO2" :
gcprohist[j].type == gcpro3_type ? "GCPRO3" :
gcprohist[j].type == gcpro4_type ? "GCPRO4" :
+ gcprohist[j].type == gcpro5_type ? "GCPRO5" :
gcprohist[j].type == ungcpro_type ? "UNGCPRO" : "???"),
gcprohist[j].value);
}
fflush (stdout);
}
-#endif
+#endif /* DEBUG_GCPRO */