1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- *
3 * Author: Michael Zucchi <notzed@ximian.com>
5 * Copyright 2004 Novell Inc. (www.novell.com)
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU Lesser General Public
9 * License as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
27 #include <libedataserver/e-data-server-util.h>
29 #include "camel-debug.h"
31 int camel_verbose_debug;
33 static GHashTable *debug_table = NULL;
39 * Init camel debug. Maintain legacy CAMEL_VERBOSE_DEBUG as well as the
40 * new CAMEL_DEBUG based environment variable interfaces.
42 * CAMEL_VERBOSE_DEBUG is set to a number to turn debug on.
44 * CAMEL_DEBUG is set to a comma separated list of modules to debug.
45 * The modules can contain module-specific specifiers after a ':', or
46 * just act as a wildcard for the module or even specifier. e.g. 'imap'
47 * for imap debug, or 'imap:folder' for imap folder debug. Additionaly,
48 * ':folder' can be used for a wildcard for any folder operations.
50 void camel_debug_init(void)
54 d = getenv("CAMEL_VERBOSE_DEBUG");
56 camel_verbose_debug = atoi(d);
58 d = g_strdup(getenv("CAMEL_DEBUG"));
62 debug_table = g_hash_table_new(g_str_hash, g_str_equal);
65 while (*p && *p != ',')
69 g_hash_table_insert(debug_table, d, d);
73 if (g_hash_table_lookup(debug_table, "all"))
74 camel_verbose_debug = 1;
82 * Check to see if a debug mode is activated. @mode takes one of two forms,
83 * a fully qualified 'module:target', or a wildcard 'module' name. It
84 * returns a boolean to indicate if the module or module and target is
85 * currently activated for debug output.
89 gboolean camel_debug(const char *mode)
91 if (camel_verbose_debug)
98 if (g_hash_table_lookup(debug_table, mode))
101 /* Check for fully qualified debug */
102 colon = strchr(mode, ':');
104 fallback = g_alloca(strlen(mode)+1);
105 strcpy(fallback, mode);
106 colon = (colon-mode) + fallback;
107 /* Now check 'module[:*]' */
109 if (g_hash_table_lookup(debug_table, fallback))
111 /* Now check ':subsystem' */
113 if (g_hash_table_lookup(debug_table, colon))
121 static pthread_mutex_t debug_lock = PTHREAD_MUTEX_INITIALIZER;
126 * Start debug output for a given mode, used to make sure debug output
127 * is output atomically and not interspersed with unrelated stuff.
129 * Return value: Returns true if mode is set, and in which case, you must
130 * call debug_end when finished any screen output.
133 camel_debug_start(const char *mode)
135 if (camel_debug(mode)) {
136 pthread_mutex_lock(&debug_lock);
137 printf("Thread %" G_GINT64_MODIFIER "x >\n", e_util_pthread_id(pthread_self()));
147 * Call this when you're done with your debug output. If and only if
148 * you called camel_debug_start, and if it returns TRUE.
151 camel_debug_end(void)
153 printf("< %" G_GINT64_MODIFIER "x >\n", e_util_pthread_id(pthread_self()));
154 pthread_mutex_unlock(&debug_lock);
158 #include <sys/debugreg.h>
161 i386_length_and_rw_bits (int len, enum target_hw_bp_type type)
173 case hw_read: /* x86 doesn't support data-read watchpoints */
178 case hw_io_access: /* not yet supported */
183 internal_error (__FILE__, __LINE__, "\
184 Invalid hw breakpoint type %d in i386_length_and_rw_bits.\n", (int)type);
190 return (DR_LEN_1 | rw);
192 return (DR_LEN_2 | rw);
194 return (DR_LEN_4 | rw);
196 if (TARGET_HAS_DR_LEN_8)
197 return (DR_LEN_8 | rw);
199 internal_error (__FILE__, __LINE__, "\
200 Invalid hw breakpoint length %d in i386_length_and_rw_bits.\n", len);
204 #define I386_DR_SET_RW_LEN(i,rwlen) \
206 dr_control_mirror &= ~(0x0f << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE*(i))); \
207 dr_control_mirror |= ((rwlen) << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE*(i))); \
210 #define I386_DR_LOCAL_ENABLE(i) \
211 dr_control_mirror |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (i)))
214 #define set_dr(regnum, val) \
215 __asm__("movl %0,%%db" #regnum \
219 #define get_dr(regnum, val) \
220 __asm__("movl %%db" #regnum ", %0" \
223 /* fine idea, but it doesn't work, crashes in get_dr :-/ */
225 camel_debug_hwatch(int wp, void *addr)
229 g_assert(wp <= DR_LASTADDR);
230 g_assert(sizeof(addr) == 4);
233 /* set watch mode + size */
234 rw = DR_RW_WRITE | DR_LEN_4;
235 control &= ~(((1<<DR_CONTROL_SIZE)-1) << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE * wp));
236 control |= rw << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE*wp);
237 /* set watch enable */
238 control |= ( 1<< (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * wp));
239 control |= DR_LOCAL_SLOWDOWN;
240 control &= ~DR_CONTROL_RESERVED;