[glib] Clean up process of calling g_debug_init()
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] Clean up process of calling g_debug_init()
- Date: Tue, 4 Oct 2011 19:32:37 +0000 (UTC)
commit 310c3ed4cc733f47b88b44fb03757bd7213a4f9a
Author: Ryan Lortie <desrt desrt ca>
Date: Wed Sep 21 21:20:07 2011 -0400
Clean up process of calling g_debug_init()
Make sure that it calls absolutely nothing that may ever recurse back
into GLib again:
- g_ascii_strcasecmp() is unsafe because it has g_return_if_fail() at
the top. As far as I know, the only ASCII character letter that
would get special treatment here is "i" and that appears in neither
"help" nor "all".
- g_getenv() is very complicated on Windows, so use a simple version
that is sufficient for our purposes.
Now that it's completely safe, we can just call it from g_logv() in the
usual way without all of the hacks.
https://bugzilla.gnome.org/show_bug.cgi?id=660744
glib/gmessages.c | 87 +++++++++++++++++++++--------------------------------
glib/gutils.c | 16 ++++++----
2 files changed, 45 insertions(+), 58 deletions(-)
---
diff --git a/glib/gmessages.c b/glib/gmessages.c
index c583188..1ed1e15 100644
--- a/glib/gmessages.c
+++ b/glib/gmessages.c
@@ -186,46 +186,44 @@ g_messages_prefixed_init (void)
}
}
-static void
-g_debug_init (void)
+static guint
+g_parse_debug_envvar (const gchar *envvar,
+ const GDebugKey *keys,
+ gint n_keys)
{
- typedef enum {
- G_DEBUG_FATAL_WARNINGS = 1 << 0,
- G_DEBUG_FATAL_CRITICALS = 1 << 1
- } GDebugFlag;
- const gchar *val;
- guint flags = 0;
+ const gchar *value;
- g_debug_initialized = TRUE;
+#ifdef OS_WIN32
+ /* "fatal-warnings,fatal-criticals,all,help" is pretty short */
+ gchar buffer[80];
- val = g_getenv ("G_DEBUG");
- if (val != NULL)
- {
- const GDebugKey keys[] = {
- {"fatal_warnings", G_DEBUG_FATAL_WARNINGS},
- {"fatal_criticals", G_DEBUG_FATAL_CRITICALS}
- };
+ if (GetEnvironmentVariable (envvar, buffer, 100) < 100)
+ value = buffer;
+ else
+ return 0;
+#else
+ value = getenv (envvar);
+#endif
- flags = g_parse_debug_string (val, keys, G_N_ELEMENTS (keys));
- }
+ return g_parse_debug_string (value, keys, n_keys);
+}
- if (flags & G_DEBUG_FATAL_WARNINGS)
- {
- GLogLevelFlags fatal_mask;
+static void
+g_debug_init (void)
+{
+ const GDebugKey keys[] = {
+ {"fatal-warnings", G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL },
+ {"fatal-criticals", G_LOG_LEVEL_CRITICAL }
+ };
+ GLogLevelFlags flags;
- fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
- fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
- g_log_set_always_fatal (fatal_mask);
- }
+ flags = g_parse_debug_envvar ("G_DEBUG", keys, G_N_ELEMENTS (keys));
- if (flags & G_DEBUG_FATAL_CRITICALS)
- {
- GLogLevelFlags fatal_mask;
+ g_mutex_lock (&g_messages_lock);
+ g_log_always_fatal |= flags;
+ g_mutex_unlock (&g_messages_lock);
- fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
- fatal_mask |= G_LOG_LEVEL_CRITICAL;
- g_log_set_always_fatal (fatal_mask);
- }
+ g_debug_initialized = TRUE;
}
static GLogDomain*
@@ -500,6 +498,9 @@ g_logv (const gchar *log_domain,
gboolean was_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
gint i;
+ if (!g_debug_initialized)
+ g_debug_init ();
+
log_level &= G_LOG_LEVEL_MASK;
if (!log_level)
return;
@@ -542,24 +543,6 @@ g_logv (const gchar *log_domain,
g_private_set (&g_log_depth, GUINT_TO_POINTER (depth));
- /* had to defer debug initialization until we can keep track of recursion */
- if (!(test_level & G_LOG_FLAG_RECURSION) && !g_debug_initialized)
- {
- GLogLevelFlags orig_test_level = test_level;
-
- g_debug_init ();
- if ((domain_fatal_mask | g_log_always_fatal) & test_level)
- test_level |= G_LOG_FLAG_FATAL;
- if (test_level != orig_test_level)
- {
- /* need a relookup, not nice, but not too bad either */
- g_mutex_lock (&g_messages_lock);
- domain = g_log_find_domain_L (log_domain ? log_domain : "");
- log_func = g_log_domain_get_handler_L (domain, test_level, &data);
- domain = NULL;
- g_mutex_unlock (&g_messages_lock);
- }
- }
if (test_level & G_LOG_FLAG_RECURSION)
{
diff --git a/glib/gutils.c b/glib/gutils.c
index 052126d..fb98e83 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -666,6 +666,7 @@ debug_key_matches (const gchar *key,
const gchar *token,
guint length)
{
+ /* may not call GLib functions: see note in g_parse_debug_string() */
for (; length; length--, key++, token++)
{
char k = (*key == '_') ? '-' : tolower (*key );
@@ -708,17 +709,20 @@ g_parse_debug_string (const gchar *string,
if (string == NULL)
return 0;
- /* this function is used by gmem.c/gslice.c initialization code,
- * so introducing malloc dependencies here would require adaptions
- * of those code portions.
+ /* this function is used during the initialisation of gmessages, gmem
+ * and gslice, so it may not do anything that causes memory to be
+ * allocated or risks messages being emitted.
+ *
+ * this means, more or less, that this code may not call anything
+ * inside GLib.
*/
-
- if (!g_ascii_strcasecmp (string, "all"))
+
+ if (!strcasecmp (string, "all"))
{
for (i=0; i<nkeys; i++)
result |= keys[i].value;
}
- else if (!g_ascii_strcasecmp (string, "help"))
+ else if (!strcasecmp (string, "help"))
{
/* using stdio directly for the reason stated above */
fprintf (stderr, "Supported debug values: ");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]