1
/* debug-buffer.c -- Trace recording
2
Copyright (C) 1997 John Harper <john@dcs.warwick.ac.uk>
3
$Id: debug-buffer.c,v 1.15 2000/01/07 14:41:38 john Exp $
5
This file is part of Jade.
7
Jade is free software; you can redistribute it and/or modify it
8
under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
12
Jade is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with Jade; see the file COPYING. If not, write to
19
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
33
struct debug_buf *next;
40
#define DB_SIZE(n) (sizeof(struct debug_buf) + (n) - 1)
42
static struct debug_buf *db_chain;
45
rep_db_alloc(char *name, int size)
47
struct debug_buf *db = rep_alloc(DB_SIZE(size));
50
perror("create_debug_buf");
56
db->wrapped = rep_FALSE;
64
rep_db_free(void *_db)
66
struct debug_buf *db = _db;
67
struct debug_buf **x = &db_chain;
81
rep_db_vprintf(void *_db, char *fmt, va_list args)
85
struct debug_buf *db = _db;
88
vsnprintf(buf, sizeof(buf), fmt, args);
90
vsprintf(buf, fmt, args);
93
if(length > db->size - db->ptr)
95
int before = db->size - db->ptr;
96
int after = MIN(length - before, db->size - before);
97
memcpy(db->data + db->ptr, buf, before);
98
memcpy(db->data, buf + before, after);
100
db->wrapped = rep_TRUE;
104
memcpy(db->data + db->ptr, buf, length);
110
rep_db_printf(void *_db, char *fmt, ...)
114
rep_db_vprintf(_db, fmt, args);
119
rep_db_print_backtrace(void *_db, char *fun)
121
#if defined(__GNUC__) && ! defined(BROKEN_ALPHA_GCC)
126
void *stack[BT_BASE+BT_DEPTH];
129
/* It seems that in Linux/egcs-1.1 __builtin_return_address()
130
will segfault when reaching the top of the stack frame.
131
The work-around is to see if we can get the frame address,
132
if so it should be safe to go for the return address. */
133
# define STACK_PROBE(i) \
135
if(i == BT_BASE || stack[i-1] != 0) \
137
void *frame = __builtin_frame_address(i); \
139
stack[i] = __builtin_return_address(i); \
147
/* Should be from BT_BASE to BT_BASE+BT_DEPTH-1 */
148
STACK_PROBE(1); STACK_PROBE(2); STACK_PROBE(3); STACK_PROBE(4);
149
STACK_PROBE(5); STACK_PROBE(6); STACK_PROBE(7); STACK_PROBE(8);
151
rep_db_printf(_db, "\nBacktrace in `%s':\n", fun);
152
for(i = BT_BASE; i < BT_BASE+BT_DEPTH && stack[i] != 0; i++)
154
#ifdef DB_RESOLVE_SYMBOLS
156
rep_db_printf(_db, "\t(nil)\n");
161
if(rep_find_c_symbol(stack[i], &name, &addr))
163
rep_db_printf(_db, "\t<%s+%d>\n", name,
164
((char *)stack[i]) - ((char *)addr));
167
rep_db_printf(_db, "\t0x%08lx\n", stack[i]);
170
rep_db_printf(_db, "\t0x%08lx\n", stack[i]);
177
rep_db_return_address(void)
179
#if defined(__GNUC__) && ! defined(BROKEN_ALPHA_GCC)
180
return __builtin_return_address(1);
187
rep_db_spew(void *_db)
189
struct debug_buf *db = _db;
191
if(db->wrapped || db->ptr > 0)
193
fprintf(stderr, "\nstruct debug_buf %s:\n", db->name);
196
fwrite(db->data + db->ptr, 1, db->size - db->ptr, stderr);
197
fwrite(db->data, 1, db->ptr, stderr);
200
fwrite(db->data, 1, db->ptr, stderr);
205
rep_db_spew_all(void)
207
struct debug_buf *db = db_chain;
218
struct debug_buf *db = db_chain;
223
struct debug_buf *next = db->next;