[glib: 2/3] W32 VEH: Add tests
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 2/3] W32 VEH: Add tests
- Date: Wed, 6 Mar 2019 11:59:10 +0000 (UTC)
commit 66f4c104ba4b807032eeb62393801c25b1c88c50
Author: Руслан Ижбулатов <lrn1986 gmail com>
Date: Sat Feb 2 11:13:29 2019 +0000
W32 VEH: Add tests
One test is for _g_win32_subst_pid_and_event().
Two tests for crashing with different exceptions (access violation
and illegal instruction).
And one test for running a debugger.
glib/tests/meson.build | 3 +
glib/tests/win32.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 176 insertions(+)
---
diff --git a/glib/tests/meson.build b/glib/tests/meson.build
index d54fc41fa..2b3f902ab 100644
--- a/glib/tests/meson.build
+++ b/glib/tests/meson.build
@@ -140,6 +140,9 @@ if host_machine.system() == 'windows'
},
}
endif
+ glib_tests += {
+ 'win32' : {},
+ }
else
glib_tests += {
'include' : {},
diff --git a/glib/tests/win32.c b/glib/tests/win32.c
new file mode 100644
index 000000000..d4b1fc523
--- /dev/null
+++ b/glib/tests/win32.c
@@ -0,0 +1,173 @@
+/* Unit test for VEH on Windows
+ * Copyright (C) 2019 Руслан Ижбулатов
+ *
+ * This work is provided "as is"; redistribution and modification
+ * in whole or in part, in any medium, physical or electronic is
+ * permitted without restriction.
+ *
+ * This work 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.
+ *
+ * In no event shall the authors or contributors be liable for any
+ * direct, indirect, incidental, special, exemplary, or consequential
+ * damages (including, but not limited to, procurement of substitute
+ * goods or services; loss of use, data, or profits; or business
+ * interruption) however caused and on any theory of liability, whether
+ * in contract, strict liability, or tort (including negligence or
+ * otherwise) arising in any way out of the use of this software, even
+ * if advised of the possibility of such damage.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <gprintf.h>
+#include <stdio.h>
+#include <windows.h>
+
+static char *argv0 = NULL;
+
+#include "../gwin32-private.c"
+
+static void
+test_subst_pid_and_event (void)
+{
+ const gchar not_enough[] = "too long when %e and %p are substituted";
+ gchar debugger_3[3];
+ gchar debugger_not_enough[G_N_ELEMENTS (not_enough)];
+ gchar debugger_enough[G_N_ELEMENTS (not_enough) + 1];
+ gchar debugger_big[65535] = {0};
+ gchar *output;
+ DWORD be = 0xFFFFFFFF;
+ guintptr bp = (guintptr) G_MAXSIZE;
+
+ /* %f is not valid */
+ g_assert_false (_g_win32_subst_pid_and_event (debugger_3, G_N_ELEMENTS (debugger_3),
+ "%f", 0, 0));
+
+ g_assert_false (_g_win32_subst_pid_and_event (debugger_3, G_N_ELEMENTS (debugger_3),
+ "string longer than 10", 0, 0));
+ /* 200 is longer than %e, so the string doesn't fit by 1 byte */
+ g_assert_false (_g_win32_subst_pid_and_event (debugger_not_enough, G_N_ELEMENTS (debugger_not_enough),
+ "too long when %e and %p are substituted", 10, 200));
+
+ /* This should fit */
+ g_assert_true (_g_win32_subst_pid_and_event (debugger_enough, G_N_ELEMENTS (debugger_enough),
+ "too long when %e and %p are substituted", 10, 200));
+ g_assert_cmpstr (debugger_enough, ==, "too long when 200 and 10 are substituted");
+
+ g_assert_true (_g_win32_subst_pid_and_event (debugger_big, G_N_ELEMENTS (debugger_big),
+ "multipl%e big %e %entries and %pids are %provided here",
bp, be));
+ output = g_strdup_printf ("multipl%lu big %lu %luntries and %lluids are %llurovided here", be, be, be,
(guint64) bp, (guint64) bp);
+ g_assert_cmpstr (debugger_big, ==, output);
+ g_free (output);
+}
+
+/* Crash with access violation */
+static void
+test_access_violation (void)
+{
+ int *integer = NULL;
+ /* Use SEM_NOGPFAULTERRORBOX to prevent an error dialog
+ * from being shown.
+ */
+ DWORD dwMode = SetErrorMode (SEM_NOGPFAULTERRORBOX);
+ SetErrorMode (dwMode | SEM_NOGPFAULTERRORBOX);
+ *integer = 1;
+ SetErrorMode (dwMode);
+}
+
+/* Crash with illegal instruction */
+static void
+test_illegal_instruction (void)
+{
+ DWORD dwMode = SetErrorMode (SEM_NOGPFAULTERRORBOX);
+ SetErrorMode (dwMode | SEM_NOGPFAULTERRORBOX);
+ RaiseException (EXCEPTION_ILLEGAL_INSTRUCTION, 0, 0, NULL);
+ SetErrorMode (dwMode);
+}
+
+static void
+test_veh_crash_access_violation (void)
+{
+ g_unsetenv ("G_DEBUGGER");
+ /* Run a test that crashes */
+ g_test_trap_subprocess ("/win32/subprocess/access_violation", 0, 0);
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("Exception code=0xc0000005*");
+}
+
+static void
+test_veh_crash_illegal_instruction (void)
+{
+ g_unsetenv ("G_DEBUGGER");
+ /* Run a test that crashes */
+ g_test_trap_subprocess ("/win32/subprocess/illegal_instruction", 0, 0);
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("Exception code=0xc000001d*");
+}
+
+static void
+test_veh_debug (void)
+{
+ /* Run a test that crashes and runs a debugger */
+ g_test_trap_subprocess ("/win32/subprocess/debugee", 0, 0);
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("Exception code=0xc0000005*Debugger invoked, attaching to*");
+}
+
+static void
+test_veh_debugee (void)
+{
+ /* Set up a debugger to be run on crash */
+ gchar *command = g_strdup_printf ("%s %s", argv0, "%p %e");
+ g_setenv ("G_DEBUGGER", command, TRUE);
+ /* Because the "debugger" here is not really a debugger,
+ * it can't write into stderr of this process, unless
+ * we allow it to inherit our stderr.
+ */
+ g_setenv ("G_DEBUGGER_OLD_CONSOLE", "1", TRUE);
+ g_free (command);
+ /* Crash */
+ test_access_violation ();
+}
+
+static void
+veh_debugger (int argc, char *argv[])
+{
+ char *end;
+ DWORD pid = strtoul (argv[1], &end, 10);
+ guintptr event = (guintptr) _strtoui64 (argv[2], &end, 10);
+ /* Unfreeze the debugee and announce ourselves */
+ SetEvent ((HANDLE) event);
+ CloseHandle ((HANDLE) event);
+ g_fprintf (stderr, "Debugger invoked, attaching to %lu and signalling %" G_GUINTPTR_FORMAT, pid, event);
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ argv0 = argv[0];
+
+ g_test_init (&argc, &argv, NULL);
+
+ if (argc > 2)
+ {
+ veh_debugger (argc, argv);
+ return 0;
+ }
+
+ g_test_add_func ("/win32/substitute-pid-and-event", test_subst_pid_and_event);
+
+ g_test_add_func ("/win32/veh/access_violation", test_veh_crash_access_violation);
+ g_test_add_func ("/win32/veh/illegal_instruction", test_veh_crash_illegal_instruction);
+ g_test_add_func ("/win32/veh/debug", test_veh_debug);
+
+ g_test_add_func ("/win32/subprocess/debugee", test_veh_debugee);
+ g_test_add_func ("/win32/subprocess/access_violation", test_access_violation);
+ g_test_add_func ("/win32/subprocess/illegal_instruction", test_illegal_instruction);
+
+ return g_test_run();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]