mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-22 17:08:53 +02:00
Merge branch 'libglib-static-dep-for-tests' into 'main'
Meson: Add libglib_static dependency for use in tests See merge request GNOME/glib!4651
This commit is contained in:
@@ -458,48 +458,6 @@ glib_win32_deinit (gboolean detach_thread)
|
||||
g_crash_handler_win32_deinit ();
|
||||
}
|
||||
|
||||
#ifndef GLIB_STATIC_COMPILATION
|
||||
|
||||
BOOL WINAPI DllMain (HINSTANCE hinstDLL,
|
||||
DWORD fdwReason,
|
||||
LPVOID lpvReserved);
|
||||
|
||||
BOOL WINAPI
|
||||
DllMain (HINSTANCE hinstDLL,
|
||||
DWORD fdwReason,
|
||||
LPVOID lpvReserved)
|
||||
{
|
||||
switch (fdwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
glib_dll = hinstDLL;
|
||||
glib_win32_init ();
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
#ifdef THREADS_WIN32
|
||||
g_thread_win32_thread_detach ();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
glib_win32_deinit (lpvReserved == NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* do nothing */
|
||||
;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifndef G_HAS_CONSTRUCTORS
|
||||
#error static compilation on Windows requires constructor support
|
||||
#endif
|
||||
|
||||
#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
|
||||
#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(glib_priv_constructor)
|
||||
#endif
|
||||
@@ -518,7 +476,7 @@ glib_priv_constructor (void)
|
||||
}
|
||||
|
||||
#ifndef G_HAS_TLS_CALLBACKS
|
||||
#error static compilation on Windows requires TLS callbacks support
|
||||
#error Compilation on Windows requires TLS callbacks support
|
||||
#endif
|
||||
|
||||
G_DEFINE_TLS_CALLBACK (glib_priv_tls_callback)
|
||||
@@ -548,8 +506,6 @@ glib_priv_tls_callback (LPVOID hinstance,
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* GLIB_STATIC_COMPILATION */
|
||||
|
||||
#elif defined(G_HAS_CONSTRUCTORS) /* && !G_PLATFORM_WIN32 */
|
||||
|
||||
#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
|
||||
|
@@ -1,80 +0,0 @@
|
||||
/* gwin32-private.c - private glib functions for gwin32.c
|
||||
*
|
||||
* Copyright 2019 Руслан Ижбулатов
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Copy @cmdline into @debugger, and substitute @pid for `%p`
|
||||
* and @event for `%e`.
|
||||
* If @debugger_size (in wchar_ts) is overflowed, return %FALSE.
|
||||
* Also returns %FALSE when `%` is followed by anything other
|
||||
* than `e` or `p`.
|
||||
*/
|
||||
static gboolean
|
||||
_g_win32_subst_pid_and_event_w (wchar_t *local_debugger,
|
||||
gsize debugger_size,
|
||||
const wchar_t *cmdline,
|
||||
DWORD pid,
|
||||
guintptr event)
|
||||
{
|
||||
gsize i = 0, dbg_i = 0;
|
||||
/* These are integers, and they can't be longer than 20 characters
|
||||
* even when they are 64-bit and in decimal notation.
|
||||
* Use 30 just to be sure.
|
||||
*/
|
||||
#define STR_BUFFER_SIZE 30
|
||||
wchar_t pid_str[STR_BUFFER_SIZE] = {0};
|
||||
gsize pid_str_len;
|
||||
wchar_t event_str[STR_BUFFER_SIZE] = {0};
|
||||
gsize event_str_len;
|
||||
|
||||
_snwprintf_s (pid_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), L"%lu", pid);
|
||||
pid_str[G_N_ELEMENTS (pid_str) - 1] = 0;
|
||||
pid_str_len = wcslen (pid_str);
|
||||
_snwprintf_s (event_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), L"%Iu", event);
|
||||
event_str[G_N_ELEMENTS (pid_str) - 1] = 0;
|
||||
event_str_len = wcslen (event_str);
|
||||
#undef STR_BUFFER_SIZE
|
||||
|
||||
while (cmdline[i] != 0 && dbg_i < debugger_size)
|
||||
{
|
||||
if (cmdline[i] != L'%')
|
||||
local_debugger[dbg_i++] = cmdline[i++];
|
||||
else if (cmdline[i + 1] == L'p')
|
||||
{
|
||||
gsize j = 0;
|
||||
while (j < pid_str_len && dbg_i < debugger_size)
|
||||
local_debugger[dbg_i++] = pid_str[j++];
|
||||
i += 2;
|
||||
}
|
||||
else if (cmdline[i + 1] == L'e')
|
||||
{
|
||||
gsize j = 0;
|
||||
while (j < event_str_len && dbg_i < debugger_size)
|
||||
local_debugger[dbg_i++] = event_str[j++];
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
if (dbg_i < debugger_size)
|
||||
local_debugger[dbg_i] = 0;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
@@ -70,6 +70,8 @@
|
||||
#endif
|
||||
|
||||
#include "glib.h"
|
||||
#include "gwin32.h"
|
||||
#include "gwin32private.h"
|
||||
#include "gthreadprivate.h"
|
||||
#include "glib-init.h"
|
||||
|
||||
@@ -1065,7 +1067,66 @@ static DWORD *exceptions_to_catch = NULL;
|
||||
static HANDLE debugger_wakeup_event = 0;
|
||||
static DWORD debugger_spawn_flags = 0;
|
||||
|
||||
#include "gwin32-private.c"
|
||||
/* Copy @cmdline into @debugger, and substitute @pid for `%p`
|
||||
* and @event for `%e`.
|
||||
* If @debugger_size (in wchar_ts) is overflowed, return %FALSE.
|
||||
* Also returns %FALSE when `%` is followed by anything other
|
||||
* than `e` or `p`.
|
||||
*/
|
||||
bool
|
||||
g_win32_substitute_pid_and_event (wchar_t *local_debugger,
|
||||
gsize debugger_size,
|
||||
const wchar_t *cmdline,
|
||||
DWORD pid,
|
||||
guintptr event)
|
||||
{
|
||||
gsize i = 0, dbg_i = 0;
|
||||
/* These are integers, and they can't be longer than 20 characters
|
||||
* even when they are 64-bit and in decimal notation.
|
||||
* Use 30 just to be sure.
|
||||
*/
|
||||
#define STR_BUFFER_SIZE 30
|
||||
wchar_t pid_str[STR_BUFFER_SIZE] = {0};
|
||||
gsize pid_str_len;
|
||||
wchar_t event_str[STR_BUFFER_SIZE] = {0};
|
||||
gsize event_str_len;
|
||||
|
||||
_snwprintf_s (pid_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), L"%lu", pid);
|
||||
pid_str[G_N_ELEMENTS (pid_str) - 1] = 0;
|
||||
pid_str_len = wcslen (pid_str);
|
||||
_snwprintf_s (event_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), L"%Iu", event);
|
||||
event_str[G_N_ELEMENTS (pid_str) - 1] = 0;
|
||||
event_str_len = wcslen (event_str);
|
||||
#undef STR_BUFFER_SIZE
|
||||
|
||||
while (cmdline[i] != 0 && dbg_i < debugger_size)
|
||||
{
|
||||
if (cmdline[i] != L'%')
|
||||
local_debugger[dbg_i++] = cmdline[i++];
|
||||
else if (cmdline[i + 1] == L'p')
|
||||
{
|
||||
gsize j = 0;
|
||||
while (j < pid_str_len && dbg_i < debugger_size)
|
||||
local_debugger[dbg_i++] = pid_str[j++];
|
||||
i += 2;
|
||||
}
|
||||
else if (cmdline[i + 1] == L'e')
|
||||
{
|
||||
gsize j = 0;
|
||||
while (j < event_str_len && dbg_i < debugger_size)
|
||||
local_debugger[dbg_i++] = event_str[j++];
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
if (dbg_i < debugger_size)
|
||||
local_debugger[dbg_i] = 0;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static char *
|
||||
copy_chars (char *buffer,
|
||||
@@ -1295,9 +1356,9 @@ g_crash_handler_win32_init (void)
|
||||
debugger_wakeup_event = CreateEvent (&sa, FALSE, FALSE, NULL);
|
||||
|
||||
/* Put process ID and event handle into debugger commandline */
|
||||
if (!_g_win32_subst_pid_and_event_w (debugger, G_N_ELEMENTS (debugger),
|
||||
debugger_env, GetCurrentProcessId (),
|
||||
(guintptr) debugger_wakeup_event))
|
||||
if (!g_win32_substitute_pid_and_event (debugger, G_N_ELEMENTS (debugger),
|
||||
debugger_env, GetCurrentProcessId (),
|
||||
(guintptr) debugger_wakeup_event))
|
||||
{
|
||||
CloseHandle (debugger_wakeup_event);
|
||||
debugger_wakeup_event = 0;
|
||||
|
42
glib/gwin32private.h
Normal file
42
glib/gwin32private.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright © 2025 Luca Bacci
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Luca Bacci <luca.bacci@outlook.com>
|
||||
*/
|
||||
|
||||
#ifndef __G_WIN32PRIVATE_H__
|
||||
#define __G_WIN32PRIVATE_H__
|
||||
|
||||
#ifdef G_PLATFORM_WIN32
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
bool
|
||||
g_win32_substitute_pid_and_event (wchar_t *local_debugger,
|
||||
gsize debugger_size,
|
||||
const wchar_t *cmdline,
|
||||
DWORD pid,
|
||||
guintptr event);
|
||||
|
||||
|
||||
#endif /* G_PLATFORM_WIN32 */
|
||||
|
||||
#endif /* __G_WIN32PRIVATE_H__ */
|
@@ -437,6 +437,26 @@ libglib_dep = declare_dependency(
|
||||
# We sadly need to export configinc here because everyone includes <glib/*.h>
|
||||
include_directories : [configinc, glibinc])
|
||||
|
||||
libglib_static_dep = declare_dependency(
|
||||
compile_args: ['-DGLIB_STATIC_COMPILATION'],
|
||||
objects: libglib.extract_all_objects(recursive: true),
|
||||
dependencies: [
|
||||
atomic_dep,
|
||||
gnulib_libm_dependency,
|
||||
libiconv,
|
||||
libintl_deps,
|
||||
libm,
|
||||
librt,
|
||||
libsysprof_capture_dep,
|
||||
pcre2,
|
||||
platform_deps,
|
||||
thread_dep,
|
||||
],
|
||||
link_with: [charset_lib, gnulib_lib],
|
||||
sources: glib_built_headers,
|
||||
include_directories: [configinc, glibinc],
|
||||
)
|
||||
|
||||
pkg.generate(libglib,
|
||||
libraries : [libintl_deps],
|
||||
libraries_private : [win32_ldflags],
|
||||
|
@@ -251,6 +251,7 @@ if host_machine.system() == 'windows'
|
||||
'win32' : {
|
||||
'dependencies' : [wincodecs],
|
||||
},
|
||||
'win32-private' : {},
|
||||
}
|
||||
else
|
||||
glib_tests += {
|
||||
@@ -396,6 +397,7 @@ test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
|
||||
test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
|
||||
|
||||
test_deps = [libm, thread_dep, libglib_dep]
|
||||
test_deps_static = [libm, thread_dep, libglib_static_dep]
|
||||
test_cargs = ['-DG_LOG_DOMAIN="GLib"', '-UG_DISABLE_ASSERT']
|
||||
test_cpp_args = test_cargs
|
||||
|
||||
@@ -448,12 +450,14 @@ foreach test_name, extra_args : glib_tests
|
||||
)
|
||||
endif
|
||||
|
||||
base_deps = test_name.contains('-private') ? test_deps_static : test_deps
|
||||
|
||||
exe = executable(test_name, source,
|
||||
c_args : test_cargs + extra_args.get('c_args', []),
|
||||
cpp_args : test_cpp_args + extra_args.get('cpp_args', []),
|
||||
link_args : extra_args.get('link_args', []),
|
||||
override_options : extra_args.get('override_options', []),
|
||||
dependencies : test_deps + extra_args.get('dependencies', []),
|
||||
dependencies : base_deps + extra_args.get('dependencies', []),
|
||||
link_with : extra_args.get('link_with', []),
|
||||
install_dir: installed_tests_execdir,
|
||||
install_tag: 'tests',
|
||||
|
77
glib/tests/win32-private.c
Normal file
77
glib/tests/win32-private.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright © 2019 Руслан Ижбулатов
|
||||
* Copyright © 2025 Luca Bacci
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gwin32private.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static void
|
||||
test_substitute_pid_and_event (void)
|
||||
{
|
||||
const wchar_t not_enough[] = L"too long when %e and %p are substituted";
|
||||
wchar_t debugger_3[3];
|
||||
wchar_t debugger_not_enough[G_N_ELEMENTS (not_enough)];
|
||||
wchar_t debugger_enough[G_N_ELEMENTS (not_enough) + 1];
|
||||
char *debugger_enough_utf8;
|
||||
wchar_t debugger_big[65535] = {0};
|
||||
char *debugger_big_utf8;
|
||||
gchar *output;
|
||||
guintptr be = (guintptr) 0xFFFFFFFF;
|
||||
DWORD bp = MAXDWORD;
|
||||
|
||||
/* %f is not valid */
|
||||
g_assert_false (g_win32_substitute_pid_and_event (debugger_3, G_N_ELEMENTS (debugger_3),
|
||||
L"%f", 0, 0));
|
||||
|
||||
g_assert_false (g_win32_substitute_pid_and_event (debugger_3, G_N_ELEMENTS (debugger_3),
|
||||
L"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_substitute_pid_and_event (debugger_not_enough, G_N_ELEMENTS (debugger_not_enough),
|
||||
not_enough, 10, 200));
|
||||
|
||||
/* This should fit */
|
||||
g_assert_true (g_win32_substitute_pid_and_event (debugger_enough, G_N_ELEMENTS (debugger_enough),
|
||||
not_enough, 10, 200));
|
||||
debugger_enough_utf8 = g_utf16_to_utf8 (debugger_enough, -1, NULL, NULL, NULL);
|
||||
g_assert_cmpstr (debugger_enough_utf8, ==, "too long when 200 and 10 are substituted");
|
||||
g_free (debugger_enough_utf8);
|
||||
|
||||
g_assert_true (g_win32_substitute_pid_and_event (debugger_big, G_N_ELEMENTS (debugger_big),
|
||||
L"multipl%e big %e %entries and %pids are %provided here", bp, be));
|
||||
debugger_big_utf8 = g_utf16_to_utf8 (debugger_big, -1, NULL, NULL, NULL);
|
||||
output = g_strdup_printf ("multipl%llu big %llu %lluntries and %luids are %lurovided here", (guint64) be, (guint64) be, (guint64) be, bp, bp);
|
||||
g_assert_cmpstr (debugger_big_utf8, ==, output);
|
||||
g_free (debugger_big_utf8);
|
||||
g_free (output);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/win32/substitute-pid-and-event", test_substitute_pid_and_event);
|
||||
|
||||
return g_test_run();
|
||||
}
|
@@ -33,48 +33,6 @@
|
||||
|
||||
static char *argv0 = NULL;
|
||||
|
||||
#include "../gwin32-private.c"
|
||||
|
||||
static void
|
||||
test_subst_pid_and_event (void)
|
||||
{
|
||||
const wchar_t not_enough[] = L"too long when %e and %p are substituted";
|
||||
wchar_t debugger_3[3];
|
||||
wchar_t debugger_not_enough[G_N_ELEMENTS (not_enough)];
|
||||
wchar_t debugger_enough[G_N_ELEMENTS (not_enough) + 1];
|
||||
char *debugger_enough_utf8;
|
||||
wchar_t debugger_big[65535] = {0};
|
||||
char *debugger_big_utf8;
|
||||
gchar *output;
|
||||
guintptr be = (guintptr) 0xFFFFFFFF;
|
||||
DWORD bp = MAXDWORD;
|
||||
|
||||
/* %f is not valid */
|
||||
g_assert_false (_g_win32_subst_pid_and_event_w (debugger_3, G_N_ELEMENTS (debugger_3),
|
||||
L"%f", 0, 0));
|
||||
|
||||
g_assert_false (_g_win32_subst_pid_and_event_w (debugger_3, G_N_ELEMENTS (debugger_3),
|
||||
L"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_w (debugger_not_enough, G_N_ELEMENTS (debugger_not_enough),
|
||||
not_enough, 10, 200));
|
||||
|
||||
/* This should fit */
|
||||
g_assert_true (_g_win32_subst_pid_and_event_w (debugger_enough, G_N_ELEMENTS (debugger_enough),
|
||||
not_enough, 10, 200));
|
||||
debugger_enough_utf8 = g_utf16_to_utf8 (debugger_enough, -1, NULL, NULL, NULL);
|
||||
g_assert_cmpstr (debugger_enough_utf8, ==, "too long when 200 and 10 are substituted");
|
||||
g_free (debugger_enough_utf8);
|
||||
|
||||
g_assert_true (_g_win32_subst_pid_and_event_w (debugger_big, G_N_ELEMENTS (debugger_big),
|
||||
L"multipl%e big %e %entries and %pids are %provided here", bp, be));
|
||||
debugger_big_utf8 = g_utf16_to_utf8 (debugger_big, -1, NULL, NULL, NULL);
|
||||
output = g_strdup_printf ("multipl%llu big %llu %lluntries and %luids are %lurovided here", (guint64) be, (guint64) be, (guint64) be, bp, bp);
|
||||
g_assert_cmpstr (debugger_big_utf8, ==, output);
|
||||
g_free (debugger_big_utf8);
|
||||
g_free (output);
|
||||
}
|
||||
|
||||
/* Crash with access violation */
|
||||
static void
|
||||
test_access_violation (void)
|
||||
@@ -194,8 +152,6 @@ main (int argc,
|
||||
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);
|
||||
|
Reference in New Issue
Block a user