[glib: 1/2] gslice: Inline win32 implementation of g_getenv() to avoid deadlock
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 1/2] gslice: Inline win32 implementation of g_getenv() to avoid deadlock
- Date: Fri, 16 Oct 2020 11:22:03 +0000 (UTC)
commit b538cb0c8c829ba76d4a04be0c198e5d3b7c311c
Author: Philip Withnall <pwithnall endlessos org>
Date: Thu Oct 15 10:20:10 2020 +0100
gslice: Inline win32 implementation of g_getenv() to avoid deadlock
The win32 implementation of `g_getenv()` uses GSlice (from within
GQuark), which results in a deadlock when examining the `G_SLICE`
environment variable.
Fix that by inlining a basic implementation of `g_getenv()` at that call
site.
Signed-off-by: Philip Withnall <pwithnall endlessos org>
Fixes: #2225
glib/gslice.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
---
diff --git a/glib/gslice.c b/glib/gslice.c
index e6f278539..589619080 100644
--- a/glib/gslice.c
+++ b/glib/gslice.c
@@ -361,10 +361,52 @@ static void
slice_config_init (SliceConfig *config)
{
const gchar *val;
+ gchar *val_allocated = NULL;
*config = slice_config;
+ /* Note that the empty string (`G_SLICE=""`) is treated differently from the
+ * envvar being unset. In the latter case, we also check whether running under
+ * valgrind. */
+#ifndef G_OS_WIN32
val = g_getenv ("G_SLICE");
+#else
+ /* The win32 implementation of g_getenv() has to do UTF-8 ↔ UTF-16 conversions
+ * which use the slice allocator, leading to deadlock. Use a simple in-place
+ * implementation here instead.
+ *
+ * Ignore references to other environment variables: only support values which
+ * are a combination of always-malloc and debug-blocks. */
+ {
+
+ wchar_t wvalue[128]; /* at least big enough for `always-malloc,debug-blocks` */
+ int len;
+
+ len = GetEnvironmentVariableW (L"G_SLICE", wvalue, G_N_ELEMENTS (wvalue));
+
+ if (len == 0)
+ {
+ if (GetLastError () == ERROR_ENVVAR_NOT_FOUND)
+ val = NULL;
+ else
+ val = "";
+ }
+ else if (len >= G_N_ELEMENTS (wvalue))
+ {
+ /* @wvalue isn’t big enough. Give up. */
+ g_warning ("Unsupported G_SLICE value");
+ val = NULL;
+ }
+ else
+ {
+ /* it’s safe to use g_utf16_to_utf8() here as it only allocates using
+ * malloc() rather than GSlice */
+ val = val_allocated = g_utf16_to_utf8 (wvalue, -1, NULL, NULL, NULL);
+ }
+
+ }
+#endif /* G_OS_WIN32 */
+
if (val != NULL)
{
gint flags;
@@ -392,6 +434,8 @@ slice_config_init (SliceConfig *config)
config->always_malloc = TRUE;
#endif
}
+
+ g_free (val_allocated);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]