1 /* vmlog - high-speed logging for free VMs */
2 /* Copyright (C) 2006 Edwin Steiner <edwin.steiner@gmx.net> */
4 /* This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #define VMLOG_PAD_TO_8
26 /*** constants *******************************************************/
28 /* CAUTION: these are indices into the vmlog_tag_definitions table! */
29 #define VMLOG_TAG_ENTER 0
30 #define VMLOG_TAG_LEAVE 1
31 #define VMLOG_TAG_THROW 2
32 #define VMLOG_TAG_CATCH 3
33 #define VMLOG_TAG_UNWND 4
34 #define VMLOG_TAG_SIGNL 5
35 #define VMLOG_TAG_UNROL 6
36 #define VMLOG_TAG_REROL 7
38 /*** memory management macros ****************************************/
41 #define VMLOG_NEW(type) (type*)malloc(sizeof(type))
45 #define VMLOG_FREE(type,ptr) free(ptr)
48 #ifndef VMLOG_NEW_ARRAY
49 #define VMLOG_NEW_ARRAY(type,n) (type*)malloc(sizeof(type)*(n))
52 #ifndef VMLOG_FREE_ARRAY
53 #define VMLOG_FREE_ARRAY(type,n,ptr) free(ptr)
56 /*** struct typedefs *************************************************/
58 typedef struct vmlog_tag_definition vmlog_tag_definition;
59 typedef struct vmlog_hash_entry vmlog_hash_entry;
60 typedef struct vmlog_hash_table vmlog_hash_table;
61 typedef struct vmlog_string_entry vmlog_string_entry;
62 typedef struct vmlog_log_entry vmlog_log_entry;
63 typedef struct vmlog_thread_log vmlog_thread_log;
64 typedef struct vmlog_file vmlog_file;
65 typedef struct vmlog_frame vmlog_frame;
66 typedef struct vmlog_ringbuf vmlog_ringbuf;
67 typedef struct vmlog_log vmlog_log;
68 typedef struct vmlog_options vmlog_options;
70 /*** integer types ***************************************************/
72 typedef long long vmlog_fofs_t;
73 typedef long long vmlog_seq_t;
74 #define VMLOG_SEQ_FMT "%lld"
75 #define VMLOG_SEQ_FMT_W "%10lld"
77 #define VMLOG_SEQ_MAX LLONG_MAX
79 #define VMLOG_SEQ_MAX 9223372036854775807LL
82 #ifndef VMLOG_HAVE_PTRINT
83 typedef int ptrint; /* XXX */
86 /*** enums ***********************************************************/
94 /*** function types **************************************************/
96 typedef void (*vmlog_hash_entry_destructor)(vmlog_hash_entry *entry);
97 typedef void (*vmlog_log_function)(vmlog_log *vml,void *threadid,
98 const char *name,int namelen);
100 /*** structs *********************************************************/
102 struct vmlog_tag_definition {
108 struct vmlog_hash_entry {
113 vmlog_hash_entry *hashlink;
116 struct vmlog_hash_table {
119 vmlog_hash_entry *table;
122 struct vmlog_string_entry {
125 #if defined(VMLOG_PAD_TO_8)
130 struct vmlog_log_entry {
148 struct vmlog_thread_log {
154 vmlog_log_entry *logbuf;
155 vmlog_log_entry *logbufend;
156 vmlog_log_entry *logbufptr;
164 vmlog_hash_table threadhash;
165 vmlog_hash_table stringhash;
173 struct vmlog_ringbuf {
175 vmlog_log_entry *buf;
176 vmlog_log_entry *bufend;
177 vmlog_log_entry *start;
178 vmlog_log_entry *end;
179 vmlog_log_entry *cur;
183 int debug_availbefore;
184 int debug_availafter;
187 struct vmlog_options {
194 /*** variables *******************************************************/
196 extern vmlog_tag_definition vmlog_tag_definitions[];
198 /*** public functions ************************************************/
200 /* constructor / destructor */
201 vmlog_log * vmlog_log_new(const char *prefix,int truncate);
202 void vmlog_log_free(vmlog_log *vml);
205 void vmlog_log_load_ignorelist(vmlog_log *vml,const char *prefix);
208 void vmlog_log_enter(vmlog_log *vml,void *threadid,const char *name,int namelen);
209 void vmlog_log_leave(vmlog_log *vml,void *threadid,const char *name,int namelen);
210 void vmlog_log_throw(vmlog_log *vml,void *threadid,const char *name,int namelen);
211 void vmlog_log_catch(vmlog_log *vml,void *threadid,const char *name,int namelen);
212 void vmlog_log_unwnd(vmlog_log *vml,void *threadid,const char *name,int namelen);
213 void vmlog_log_signl(vmlog_log *vml,void *threadid,const char *name,int namelen);
214 void vmlog_log_unrol(vmlog_log *vml,void *threadid,const char *name,int namelen);
215 void vmlog_log_rerol(vmlog_log *vml,void *threadid,const char *name,int namelen);
217 /* tag definitions */
218 int vmlog_tag_from_name(const char *name,int namelen);
221 vmlog_thread_log *vmlog_thread_log_new(vmlog_log *vml,void *threadid,int index);
222 void vmlog_thread_log_free(vmlog_thread_log *tlog);
223 vmlog_frame * vmlog_thread_log_enter(vmlog_thread_log *tlog,int index,vmlog_seq_t seq);
224 vmlog_frame * vmlog_thread_log_leave(vmlog_thread_log *tlog,int index,vmlog_seq_t seq);
225 void vmlog_thread_log_append(vmlog_thread_log *tlog,vmlog_log_entry *logent);
227 /* string/index handling */
228 int vmlog_get_string_index(vmlog_log *vml,const char *data,int len);
229 void vmlog_load_stringhash(vmlog_log *vml,const char *prefix);
232 char *vmlog_concat3(const char *a,const char *b,const char *c,int *plen);
233 char *vmlog_concat4len(const char *a,int alen,const char *b,int blen,
234 const char *c,int clen,const char *d,int dlen,int *plen);
236 /* error reporting */
237 void vmlog_set_progname(const char *progname);
238 void vmlog_die(const char *fmt,...);
239 void vmlog_warn(const char *fmt,...);
240 void vmlog_die_usage(const char *usage,int error);
243 void vmlog_file_open(vmlog_file *file,const char *fname,vmlog_fmode fmode);
244 void vmlog_file_close(vmlog_file *file);
245 void vmlog_file_append(vmlog_file *file,const void *data,int len);
246 void * vmlog_file_mmap(const char *fname,int *plen);
247 void vmlog_file_munmap(void *m,int len);
248 void vmlog_file_stat(vmlog_file *file);
249 void vmlog_file_seek(vmlog_file *file,vmlog_fofs_t ofs);
251 /* log entry ring buffer */
252 vmlog_ringbuf * vmlog_ringbuf_new(const char *fname,int bufsize);
253 void vmlog_ringbuf_free(vmlog_ringbuf *ring);
254 void vmlog_ringbuf_seek(vmlog_ringbuf *ring,vmlog_seq_t seq);
255 int vmlog_ringbuf_fill(vmlog_ringbuf *ring,int len);
256 vmlog_log_entry * vmlog_ringbuf_next(vmlog_ringbuf *ring,int prefetch);
257 vmlog_log_entry * vmlog_ringbuf_prev(vmlog_ringbuf *ring,int prefetch);
260 vmlog_options *vmlog_opt_new(void);
261 void vmlog_opt_set_prefix(vmlog_options *opts, const char *arg);
262 void vmlog_opt_set_stringprefix(vmlog_options *opts, const char *arg);
263 void vmlog_opt_set_ignoreprefix(vmlog_options *opts, const char *arg);
264 int vmlog_opt_parse_seq(const char *arg,int len,vmlog_seq_t *seq);
265 int vmlog_opt_parse_range(const char *arg,vmlog_seq_t *start,vmlog_seq_t *end);
266 vmlog_options *vmlog_opt_parse_cmd_line(int *pargc,char **argv);
267 void vmlog_opt_free(vmlog_options *opts);
269 /*** memory allocation helpers ***************************************/
271 /* allocate, check, and zero memory */
272 #define VMLOG_XZNEW(var,type) \
273 do { var = VMLOG_NEW(type); \
274 if (!(var)) vmlog_die("out of memory"); \
275 memset((var),0,sizeof(type)); \
278 /* allocate, check, and zero memory for array */
279 #define VMLOG_XZNEW_ARRAY(var,type,n) \
280 do { var = VMLOG_NEW_ARRAY(type,n); \
281 if (!(var)) vmlog_die("out of memory"); \
282 memset((var),0,(n)*sizeof(type)); \
287 /* vim: noet ts=8 sw=8