diff --git a/src/internal.h b/src/internal.h
index fb17b87baa..5b0a2335f5 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -64,6 +64,7 @@
#include "libvirt/virterror.h"
#include "c-strcase.h"
+#include "glibcompat.h"
/* Merely casting to (void) is not sufficient since the
* introduction of the "warn_unused_result" attribute
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0da02bb8bd..206295bef0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1485,6 +1485,11 @@ virSecurityManagerTransactionStart;
virSecurityManagerVerify;
+# util/glibcompat.h
+vir_g_strdup_printf;
+vir_g_strdup_vprintf;
+
+
# util/viralloc.h
virAlloc;
virAllocN;
diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am
index 705b93c93c..d8c8e61c4b 100644
--- a/src/util/Makefile.inc.am
+++ b/src/util/Makefile.inc.am
@@ -3,6 +3,8 @@
# These files are not related to driver APIs. Simply generic
# helper APIs for various purposes
UTIL_SOURCES = \
+ util/glibcompat.c \
+ util/glibcompat.h \
util/viralloc.c \
util/viralloc.h \
util/virarch.c \
diff --git a/src/util/glibcompat.c b/src/util/glibcompat.c
new file mode 100644
index 0000000000..25dedf0ed5
--- /dev/null
+++ b/src/util/glibcompat.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * .
+ */
+
+#include
+
+#include "glibcompat.h"
+
+#undef g_strdup_printf
+#undef g_strdup_vprintf
+
+/* Due to a bug in glib, g_strdup_printf() nor g_strdup_vprintf()
+ * abort on OOM. It's fixed in glib's upstream. Provide our own
+ * implementation until the fix gets distributed. */
+char *
+vir_g_strdup_printf(const char *msg, ...)
+{
+ va_list args;
+ char *ret;
+ va_start(args, msg);
+ ret = g_strdup_vprintf(msg, args);
+ if (!ret)
+ abort();
+ va_end(args);
+ return ret;
+}
+
+
+char *
+vir_g_strdup_vprintf(const char *msg, va_list args)
+{
+ char *ret;
+ ret = g_strdup_vprintf(msg, args);
+ if (!ret)
+ abort();
+ return ret;
+}
diff --git a/src/util/glibcompat.h b/src/util/glibcompat.h
new file mode 100644
index 0000000000..9c5fef09bf
--- /dev/null
+++ b/src/util/glibcompat.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * .
+ */
+
+#pragma once
+
+#include
+
+char *vir_g_strdup_printf(const char *msg, ...)
+ G_GNUC_PRINTF(1, 2);
+char *vir_g_strdup_vprintf(const char *msg, va_list args)
+ G_GNUC_PRINTF(1, 0);
+
+#if !GLIB_CHECK_VERSION(2, 64, 0)
+# define g_strdup_printf vir_g_strdup_printf
+# define g_strdup_vprintf vir_g_strdup_vprintf
+#endif