The value returned when generating a collation key is an opaque binary
blob that is only meant to be used for byte-wise comparisons; we should
not imply it's a nul-terminated, UTF-8 string.
This is especially true for language bindings that try to convert C
strings returned by GLib into UTF-8 encoded strings.
Ideally, the collation functions should return a byte array, but the
closest thing we have is the OS native encoding type that we use for
paths and environment variables.
See: https://github.com/gtk-rs/gtk-rs-core/issues/1504
When the child process is going to exit on error after fork() but before
exec(), let's close the child_err_report_fd. The practical value of this
is to placate valgrind --track-fds=yes.
The changes made in commit bc59e28bf6b0f70ff345aef80356d0076f44a0e7
(issue #3399) fixed introspection of the GThread API. However, they
introduced a trampoline in every threading function. So with those
changes applied, the disassembly of `g_mutex_lock()` (for example) was:
```
0x7ffff7f038b0 <g_mutex_lock> jmp 0x7ffff7f2f440 <g_mutex_lock_impl>
0x7ffff7f038b5 data16 cs nopw 0x0(%rax,%rax,1)
```
i.e. It jumps straight to the `_impl` function, even with an optimised
build. Since `g_mutex_lock()` (and various other GThread functions) are
frequently run hot paths, this additional `jmp` to a function which has
ended up in a different code page is a slowdown which we’d rather avoid.
So, this commit reworks things to define all the `_impl` functions as
`G_ALWAYS_INLINE static inline` (which typically expands to
`__attribute__((__always_inline__)) static inline`), and to move them
into the same compilation unit as `gthread.c` so that they can be
inlined without the need for link-time optimisation to be enabled.
It makes the code a little less readable, but not much worse than what
commit bc59e28bf6b0f70ff345aef80356d0076f44a0e7 already did. And perhaps
the addition of the `inline` decorations to all the `_impl` functions
will make it a bit clearer what their intended purpose is
(platform-specific implementations).
After applying this commit, the disassembly of `g_mutex_lock()`
successfully contains the inlining for me:
```
=> 0x00007ffff7f03d80 <+0>: xor %eax,%eax
0x00007ffff7f03d82 <+2>: mov $0x1,%edx
0x00007ffff7f03d87 <+7>: lock cmpxchg %edx,(%rdi)
0x00007ffff7f03d8b <+11>: jne 0x7ffff7f03d8e <g_mutex_lock+14>
0x00007ffff7f03d8d <+13>: ret
0x00007ffff7f03d8e <+14>: jmp 0x7ffff7f03610 <g_mutex_lock_slowpath>
```
I considered making a similar change to the other APIs touched in #3399
(GContentType, GAppInfo, GSpawn), but they are all much less performance
critical, so it’s probably not worth making their code more complex for
that sake.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: #3417
And size it to `sysconf (_SC_MINSIGSTKSZ)`, if defined.
This might fix the sigaltstack test on muslc, as suggested by Markus
Wichmann (https://www.openwall.com/lists/musl/2024/05/30/2) and Rich Felker
(https://www.openwall.com/lists/musl/2024/05/29/7) on the musl mailing
list.
The thinking is that the CI machine might have a huge register file
(AVX512 or some other large extension) which doesn’t fit in `MINSIGSTKSZ`.
By sizing the alternate stack to `sysconf (_SC_MINSIGSTKSZ)` we should
be able to avoid that.
Moving it onto the heap should avoid any potential complications or bugs
from having one stack embedded within another.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: #3315
This function type isn't only used by g_hash_table_foreach_remove(), and
what happens to the data when we return TRUE depends on the calling
function.
Includes a port to modern gi-docgen syntax by Emmanuele Bassi.
Signed-off-by: Adrien Plazas <adrien.plazas@codethink.co.uk>
GHashTable optimizes for the "set" case, where key and value are the same.
See g_hash_table_add().
A user cannot see from outside, whether a GHashTable internally is a set
and shares the keys and values array. Adding one key/value pair with
differing key and value, will expand the GHashTable.
In all other cases, the GHashTable API hides this implementation detail
correctly. Except with g_hash_table_steal_extended(), when stealing both the
key and the value.
Fix that. This bug fix is obviously a change in behavior. In practice,
it's unlikely that somebody would notice, because GHashTable contains
opaque pointers and the user must know what the keys/values are and
be aware of their ownership semantics when stealing them. That means,
the change in behavior only affects instances that are internally a set,
of what the user most likely is aware and fills the table with
g_hash_table_add(). Such a user would not steal both the key and
values at the same time. Even if they do, then previously stealing the
value was pointless and would not give them what they wanted. It would
not have meaningfully worked, and since nobody reported a bug about this
yet, it's unlikely somebody noticed.
The more problematic case when the user exhibits the bug is when the
dictionary is unexpected a set internally. Imagine a mapping from numbers
to numbers (e.g. a permutation). If "unexpectedly" the dictionary contains
the identity permutation, steal-extended gives always NULL for the target
number.
The example is far fetched. In practice, it's unlikely that somebody is
gonna notice either way. That is not an argument for fixing anything.
The argument for fixing this, is that the bug breaks the illusion that
the set is only an internal optimization. That is ugly and inconsistent.
Some g++ versions issue an unused-result warning for the g_string_free() macro:
error: ignoring return value of 'gchar* g_string_free_and_steal(GString*)',
declared with attribute warn_unused_result [-Werror=unused-result]
g_string_free(s, TRUE);
This occurs with gcc 6.x / 7.1 / 7.2, and it is fixed in gcc 7.3.
This fixes the annoations for g_mapped_file_get_contents() which looks
like it might transfer ownership (due to being a char*) but does not as
we're pointing into the mmap() region.
The issue of meson 60 have been resolved for some time now, so we can
just use newer TAP syntax safely.
Revert "gtestutils: Use TAP 13 comments syntax for subtests"
This reverts commit e8725407bcd35c1fa8fed92250edf080d5542b3c.
Closes: #2885
Now that we've switched to `gi-docgen`, let's make sure our docs are
getting updated. This commit fixes most of the previous gtk-doc
references so that they now follow gi-docgen syntax.
Some exceptions are functions or types that are referenced, but are
generated by a higher level layer like `Gio`, `GObject` or `Gtk`.
Some callers of `g_ascii_strtoull()` and similar functions assume that
they can use this pattern, similar to what they might do for
Standard C `strtoull()`:
errno = 0;
result = g_ascii_strtoull (nptr, endptr, base);
saved_errno = errno;
if (saved_errno != 0)
g_printerr ("error parsing %s\n", nptr);
This is based on the fact that it is non-trivial to tell whether
`strtoull()` and related functions succeeded (in which case the value
of `errno` is unspecified) or failed (in which case `errno` is valid).
For example, POSIX `strtoul(3)` suggests this pattern:
> Since 0, `ULONG_MAX`, and `ULLONG_MAX` are returned on error and are
> also valid returns on success, an application wishing to check for
> error situations should set `errno` to 0, then call `strtoul()` or
> `strtoull()`, then check `errno`.
However, `g_ascii_strtoull()` does not *only* call a function resembling
`strtoull()` (`strtoull_l()` or its reimplementation
`g_parse_long_long()`): it also calls `get_C_locale()`, which wraps
`newlocale()`. Even if `newlocale()` succeeds (which in practice we
expect and assume that it will), it is valid for it to clobber `errno`.
For example, it might attempt to open a file that only conditionally
exists, which would leave `errno` set to `ENOENT`.
This is difficult to reproduce in practice: I encountered what I
believe to be this bug when compiling GLib-based software for i386 in a
Debian 12 derivative via an Open Build Service instance, but I could
not reproduce the bug in a similar chroot environment locally, and I
also could not reproduce the bug when compiling for x86_64 or for a
Debian 10, 11 or 13 derivative on the same Open Build Service instance.
It also cannot be reproduced via the GTest framework, because
`g_test_init()` indirectly calls `g_ascii_strtoull()`, resulting in
the call to `newlocale()` already having happened by the time we enter
test code.
Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/3418
Signed-off-by: Simon McVittie <smcv@collabora.com>
Move various doc/introspection comments from `gthread-posix.c` (which is
platform-specific) to `gthread.c` (which is not). Having the
introspection annotations and doc comments in a platform-independent
file means that they are seen by the build process on all platforms, and
we don’t end up with unintrospectable APIs on some platforms, or
platform-specific annotation differences.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3399
Using G_STATIC_ASSERT in headers which are introspected currently
requires guarding them behind `#ifndef __GI_SCANNER__` which is really
annoying. We can just define the macros to be noops in a way that the
scanner doesn't trip over them.
Signed-off-by: Sebastian Wick <sebastian.wick@redhat.com>
They are guarded for the GI Scanner right now even though they should be
fine to expose and they are used in macros that are not guarded for the
GI Scanner.
Signed-off-by: Sebastian Wick <sebastian.wick@redhat.com>
* Create a dark-mode variant of each traversal diagram, with the
traversal path colorized `--primary` blue, instead of the original
black.
* Apply the same colorizations to the light-mode diagrams, but
using the light-theme `--primary` blue.
* Add SPDX license/copyright comments to all eight SVG files.
* Add new files to documentation configs in `glib.toml.in`.
* Update documentation comment in `gnode.c` to embed both color
variants via picture tags, instead of markdown image embeds.
* Add alt text to all four images.
* Add additional blank lines to documentation comment, so that
a. First item in bulleted list does not get folded into
preceding intro paragraph
b. Intro paragraph and diagrams are not part of first paragraph
in documentation. (This also gets them out of the top-level
table-of-contents/index list, where they previously appeared
in full.)
* (Accidental change I didn't realize I was making): Convert line
endings in breadth-first diagram from CRLF to LF.
This file doesn’t contain any real implementation, it just call the
`impl` functions from the platform-specific files
`gspawn-{posix,win32}.c`.
It serves as a location for the doc comments, introspection annotations
and API preconditions, and will be built on every platform. In
particular, this means that we get consistent GIR output for the
`g_spawn_*()` APIs regardless of whether GLib was built on Linux or
Windows.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3399
This is the first step towards separating the API documentation and
introspection annotations from the platform-specific implementation, so
we can guarantee that the APIs make it into `GLib-2.0.gir` regardless of
which platform the GIR is built on.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3399
fb58d55187dfe1565d10c0c0ffdbaa85376cf0b8 added weak linking for ASAN,
skipping it for MinGW because weak symbols are broken there.
The same is true for Cygwin, so skip things there too.
This fixes the following build error under MSYS2:
/usr/lib/gcc/x86_64-pc-msys/13.3.0/../../../../x86_64-pc-msys/bin/ld:
glib/msys-glib-2.0-0.dll.p/gutils.c.o:gutils.c:
(.rdata$.refptr.__lsan_enable[.refptr.__lsan_enable]+0x0): undefined reference to `__lsan_enable'
While an index greater than `G_MAXINT` can’t be passed to
`g_ptr_array_insert()`, `-1` can be — and if that’s done with an array
which has more than `G_MAXINT` elements in it, the new element will be
inserted part-way through the array rather than being appended.
Spotted by building with `-Wsign-conversion`.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3405
The latter only accepts a `gint` as the number of elements in the array,
which means that its use in `GArray` (and related array implementations)
truncates at least half the potential array size.
So, introduce a replacement for it which uses `size_t` for the number of
elements. This is inline with what `qsort()` (or `qsort_r()`) actually
does. Unfortunately we can’t directly use `qsort_r()` because it’s not
guaranteed to be a stable sort.
This fixes some `-Wsign-conversion` warnings (when building GLib with
that enabled).
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3405
Commit 9dad94e7q ensured `test_data` is freed when a test is skipped,
but didn't ensure that when a whole test suite is skipped.
We are assuming the ownership of `test_data` is passed to GTestCase
with `g_test_add_data_func_full()` so free `test_data` always when
freeing a test case.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
gmacros.h casts functions to GDestroyNotify, which prevents enabling the
following hardening options in applications: -fsanitize=address
-fsanitize=cfi-icall (without -fsanitize-cfi-icall-generalize-pointers),
and -Wcast-function-type-strict.
Define another inline function that warps the original function into
GDestroyNotify.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>