Round-tripping pointers via gsize is not guaranteed to work (the C standard
only requires this for (u)inptr_t) and in fact breaks on CHERI-enabled
systems such as Arm Morello where pointers are 128-bits but size_t is 64.
This means the current casts would strip the high bits of the pointer and
return a non-dereferenceable value. Fix this by casting the operand that
holds the pointer to guintptr instead of gsize.
Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/2842
This should not result in any functional changes, but will eventually
allow glib to be functional on CHERI-enabled systems such as Morello.
Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/2842
If you take a release build (--buildtype=release) previously of GLib,
functions such as g_type_create_instance() would call out to
g_type_test_flags() which you can see by disassembling and looking for the
call instruction to <g_type_test_flags> via the library ABI.
Now that the previous commit allows checking abstract and deprecated flags
it makes sense to let the compiler optimize those checks into a single
pass. This is only possible if the functions themselves are inlined.
Additionally, any time we have the same TypeNode we would want to be able
to reuse that node rather than re-locate it.
Every call to g_type_create_instance() currently will incur a RWLock at
least once, but usually twice to test for both G_TYPE_FLAG_ABSTRACT and
G_TYPE_FLAG_DEPRECATED.
Additionally, each call to g_type_instance_free() also checks for these.
That results in a synchronization of GTypeInstance creation across all
threads as well as being a huge amount of overhead when creating instances
like GskRenderNode.
With this patch in place, the next two biggest issues are
g_type_class_ref() and g_type_test_flags() not getting inlined within
gtype.c in release builds. We can address that separately though.
Sysprof shows that the RWLock, with this patch in place, falls off the
profiles.
The introspection parser isn't good enough to expand the shift symbol,
which means G_TYPE_FUNDAMENTAL_MAX is evaluated as (255 << 0).
We can use the `(value)` annotation to force the symbol value in the
introspection data.
See: GNOME/gobject-introspection#473
When building for CHERI with additional warning flags, implicitly
converting uintptr_t to an integer type that can't store a pointer
results in a compiler warnings. Silence two of these by adding
explicit casts.
This patch is based upon Garrett Regier's work from 2015 to provide
some reliability and predictability to how disposal handles weak
reference state.
A primary problem is that GWeakRef and GWeakNotify state is shared and
therefore you cannot rely on GWeakRef status due to a GWeakNotify
calling into second-degree code.
It's important to ensure that both weak pointer locations and GWeakRef
will do the proper thing before user callbacks are executed during
disposal. Otherwise, user callbacks cannot rely on the status of their
weak pointers. That would be mostly okay but becomes an issue when
second degree objects are then disposed before any notification of
dependent object disposal.
Consider objects A and B.
`A` contains a reference to `B` and `B` contains a `GWeakRef` to `A`.
When `A` is disposed, `B` may be disposed as a consequence but has not
yet been notified that `A` has been disposed. It's `GWeakRef` may also
cause liveness issues if `GWeakNotify` on `A` result in tertiary code
running which wants to interact with `B`.
This example is analagous to how `GtkTextView` and `GtkTextBuffer` work
in text editing applications.
To provide application and libraries the ability to handle this using
already existing API, `GWeakRef` is separated into it's own GData quark
so that weak locations and `GWeakRef` are cleared before user code is
executed as a consequence of `GData` cleanup.
# Conflicts:
# gobject/tests/signals.c
There’s no reason that anyone can think of that this should be
disallowed. It’s useful for language runtimes like GJS to be able to
find out the allocation size of dynamic GObjects.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #623
UAC will terminate this test program from running in 32-bit x86 builds as
it believes that it will alter Windows. In order to make this run, we
create a manifest file for 32-bit Windows builds in order to tell UAC
that this program should not need admin privileges.
This will allow the entire test suite for GLib to run on 32-bit Windows
builds.
Add to script the new functions added in
commit 2368187e and commit e5ee6e14 which are:
signal_emitv_unlocked()
signal_emit_valist_unlocked()
so that the "<emit signal 'blabla'>" line keeps
showing after them.
The compiler annotations are mainly useful for people using the symbols
directly.
To avoid getting compiler warnings for the GTypeValueTable definition
itself, we need to wrap the structure with
G_GNUC_BEGIN_IGNORE_DEPRECATIONS and G_GNUC_END_IGNORE_DEPRECATIONS.
The introspection scanner cannot deal very well with function pointers
into a plain structure. In order to document the various function
pointers in GTypeValueTable we need to create typed callbacks, and
use them to replace the anonymous function pointers inside the
structure. This not only allows us to properly document the function
pointers, but it also allows us to annotate the arguments and return
value of those function pointers.
See also: https://gitlab.gnome.org/GNOME/gobject-introspection/-/merge_requests/400#note_1721707
For now, the function parse_trigraph() defined in gobject/glib-mkenums
script was not taking double-quotes characters into account:
>>> parse_trigraph('name="eek, a comma"')
{'name': '"eek', 'a': None}
This patch take double-quotes characters into account:
>>> parse_trigraph('name="eek, a comma"')
{'name': 'eek, a comma'}
Closes issue #65
Normally we don't really have emission hooks around, so try to allocate
only tiny array to contain a few of them and in case we exceed that limit,
we go back to use allocated ones.
We used to call this function as unlocked, with a node value that
could be invalid at the point of the call, so let's ensure that when
we call such function it's defined, and then reduce the access to the
signal node members when we're unlocked or after a lock/unlock operation
that may have changed it.
As per this, add more tests handling multiple signal hooks cases that we
did not cover before.
In g_signal_emit_valist() we used to access to param types array and
n_params values after unlocking the mutex, and this might have lead to
making such values unreliable for the current call.
So let's keep them around until we're done with the function call
Since we're locking and unlocking once we've found the signal ID, we
might have performed calls to g_signal_emit_valist() with a signal id
that was already been removed, and thus failing later.
This is not really an issue as inside g_signal_emit_valist() we were
re-checking for the signal id, but we can make this more reliable so
that the first thread that acquires the lock can also be sure to emit.
This is a minor style change to better differentiate
signal name by enclosing it in single quotes.
Before:
<emit signal event on instance 0xf14e60 [GdkWaylandToplevel]>
After:
<emit signal 'event' on instance 0xf14e60 [GdkWaylandToplevel]>
- Commit f02ec2f2de added a gsignal fastpath where g_closure_invoke_va()
is directly called from g_signal_emit_valist() skipping signal_emit_unlocked_R()
altogether which it's the function used by gobject_gdb.py to detect
signal emission.
So we update gobject_gdb.py to also detect signals which use this
g_closure_invoke_va() fastpath.
- We also update the existent code to detect marshallers to also
include these:
surface_event_marshaller()
gdk_surface_event_marshallerv()
g_type_class_meta_marshal()
g_type_class_meta_marshalv()
This allow us that for signal emissions which use those marshallers
to keep showing the signal handler frame just after the
<emit signal blabla> line.
commit bfbe7127d5 which did a code refactor in
gobject_gdb.py introduced a bug by failing to
return the signal name when a signal had no
'detail', this was preventing pretty printing
name for signals with no 'detail'.
GTK lost it's '+' suffix back in 2019, according to
<https://mail.gnome.org/archives/gtk-devel-list/2019-February/msg00000.html>
This commit can be re-generated with:
git grep -l GTK+ \
| grep -v -e ^NEWS -e ^glib/tests/collate.c \
| xargs sed -i 's/GTK+/GTK/g'
Most of the changes are in comments and documentation.
While x86_64 has enough precision in long double to do a round trip
from guint64 to long double and back, this is platform-specific, and
is a disservice to users trying to debug failing unit tests on other
architectures where it loses precision for g_assert_cmp{int,uint,hex}.
See also https://bugzilla.gnome.org/show_bug.cgi?id=788385 which
mentions having to add casts to specifically silence the compiler on
platforms where the precision loss occurs.
Meanwhile, g_assert_cmpuint() does an unsigned comparison, but outputs
signed values if the comparison fails, which is confusing.
Fix both issues by introducing a new g_assertion_message_cmpint()
function with a new 'u' numtype. For backwards compatibility, the
macros still call into the older g_assertion_message_cmpnum() when not
targetting 2.78, and that function still works when passed 'i' and 'x'
types even though code compiled for 2.78 and later will never invoke
it with numtype anything other than 'f'. Note that g_assert_cmpmem
can also take advantage of the new code, even though in practice,
comparison between two size_t values representing array lengths that
can actually be compiled is unlikely to have ever hit the precision
loss. The macros in signals.c test code does not have to worry about
versioning, since it is not part of the glib library proper.
Closes#2997
Signed-off-by: Eric Blake <eblake@redhat.com>
Most of the document was about traps, which have not existed since
commit 58cdf0b474, 10 years ago.
The rest of the document was about `GOBJECT_DEBUG`, and that information
would be more easily findable in the full GObject documentation — so
move it there and update it a bit.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Calling g_signal_handlers_block/unblock/disconnect_matched with only G_SIGNAL_MATCH_ID
do not match any handlers and return 0.
Fixes: #2980
Signed-off-by: Przemyslaw Gorszkowski <pgorszkowski@igalia.com>
The use of ‘OR’ in the existing documentation suggests that the matching
is disjunctive, but it’s actually conjunctive. Clarify that in the
documentation and add a test.
Spotted while reviewing
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3376.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
The documentation previously implicitly said in a few places that
interfaces are classed, but reading through the implementation of
`GType`, I don’t think they are. If they were, the registration of the
fundamental `G_TYPE_INTERFACE` in `gobject_init()` would specify
`G_TYPE_FLAG_CLASSED`. It only specifies `G_TYPE_FLAG_DERIVABLE`.
I think this makes sense, because you can’t subclass an interface.
Subclassing is a key property of being classed.
Tweak the `GType` tutorial to remove that implicit statement, and expand
the documentation for `G_TYPE_IS_CLASSED`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #252
‘returns TRUE on success’ is misleading for a lot of these macros, as
they are checking whether a type has a certain property. Such a check
could be successful but return `FALSE`, by the normal meaning of the
word ‘success’.
Instead, reword the docs to spell out when `TRUE` will be returned.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
They just listed built files. Since the move to Meson, these are all
kept in a separate build directory, not the source tree, so don’t need
to be ignored.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
They take too long and time out, and are not particularly useful to run
under valgrind because they aren’t designed to test code coverage.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Since commit 45b5a6c0 GSlice is just a wrapper to g_malloc0/g_free, so
there's no point to use a different implementation for UNIXes vs
windows.
This reverts commit 3b7af4dd5d.
We have to ensure that the memory location is sufficiently aligned to
store any object. This unbreaks the code for CHERI where using gsize
results in values that are only aligned to 8 bytes, but we need 16 byte
alignment for pointers. This is fully API/ABI compatible since amount
of padding before the actual allocation does not change for existing
architectures, only for CHERI.
Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/2842
In all these cases we don't really care about running the test file,
while building and basic execution it is relevant.
Also they don't support TAP at all.
Meson supports tap protocol results parsing, allowing us to track better
the tests that are running (and the ones that are actually skipped) without
manually parsing the test output.
However this also implies that using the verbose mode for a test doesn't
show its output by default (unless there are failures).
This reverts commit da7a31a052. The renaming of parameters implicitly introduced "closure" annotations in the documentation which are wrong on callbacks.
The gobject-introspection build goes through the GLib types when
generating the introspection data for GLib, but it does not include
glib-object.h, otherwise all GObject symbols would end up inside the
GLib namespace. This means we need to import the gobject-visibility.h
header inside glib-types.h. Since the header is guarded by a once
pragma, it doesn't really affect any legitimate user of the C API.
We cannot use `gvisibility_h` for different visibility header files; you
never know when you're going to refer to the variable again, and
projects might end up needing to retrieve the variable contents—like,
for instance, gobject-introspection using glib as a subproject.
This can cause a `NULL` dereference on the next line if there is no
`TypeNode` for `iface_type`, for example if `iface_type ==
G_TYPE_INVALID`.
Unlikely, but possible since this API is public.
Spotted by Coverity.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Coverity CID: #1501602
We can get a "-Wcast-align", if the target type that we cast to ("ct") has a
larger alignment than GTypeInstance.
That can happen on i686 architecture, if the GObject type has larger
alignment than the parent struct (or GObject). Since on i686, embeding
a "long long" or a "long double" in a struct still does not increase
the alignment beyond 4 bytes, this usually only happens when using the
__attribute__() to increase the alignment (or to have a field that has
the alignment increased).
It can happen on x86_64 when having a "long double" field.
The compiler warning is hard to avoid but not very useful, because it purely
operates on the pointer types at compile time. G_TYPE_CHECK_INSTANCE_CAST()
instead asserts (in non-optimized mode) that the pointer really points
to the expected GTypeInstance (and if that's the case, then the alignment
should be suitable already).
This is like in commit ed553e8e30 ('gtype: Eliminate -Wcast-align warnings
with G_TYPE_CHECK_INSTANCE_CAST'). But also fix the optimized code path.
With the unpatched G_TYPE_CHECK_INSTANCE_CAST() macro, the unit test would
now show the problem (with gcc-9.3.1-2.fc30.i686 or
gcc-12.2.1-4.fc37.x86_64):
$ export G_DISABLE_CAST_CHECKS=1
$ export CFLAGS='-Wcast-align=strict'
$ meson build
$ ninja -C build
...
In file included from ../gobject/gobject.h:26,
from ../gobject/gbinding.h:31,
from ../glib/glib-object.h:24,
from ../gobject/tests/objects-refcount1.c:2:
../gobject/tests/objects-refcount1.c: In function ‘my_test_dispose’:
../gobject/gtype.h:2523:42: warning: cast increases required alignment of target type [-Wcast-align]
2523 | # define _G_TYPE_CIC(ip, gt, ct) ((ct*) ip)
| ^
../gobject/gtype.h:517:66: note: in expansion of macro ‘_G_TYPE_CIC’
517 | #define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (_G_TYPE_CIC ((instance), (g_type), c_type))
| ^~~~~~~~~~~
../gobject/tests/objects-refcount1.c:9:37: note: in expansion of macro ‘G_TYPE_CHECK_INSTANCE_CAST’
9 | #define MY_TEST(test) (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
../gobject/tests/objects-refcount1.c:96:10: note: in expansion of macro ‘MY_TEST’
96 | test = MY_TEST (object);
| ^~~~~~~
Instead of a plain reference count check failure that is really hard to
understand, let's be explicit, and warn that manipulating an object's
notification queue during its finalization is not allowed.
When an object is revitalized and a notify callbacks increased the reference
counter of the object, we are calling the toggle notifier twice, while it
should only happen if also the actual reference count value is 1 (after
having been decremented from 2).
If an object gets revitalized during the dispose vfunc, we need to call
toggle refs notifiers only if we had 2 references and if the object has
the toggle references enabled.
This may change in case an object notifier handler changes this status,
so do this check only after we've called the notifiers so that in case
toggle notifications are enabled afterwards we still call the handlers.
We were reading if an object has toggle references even if this was not
really relevant for the current object state, as we only need to notify
when going from 2 to 1 references, so first ensure that this is the case
and then check if we have toggle references enabled in the object.
This is a micro-optimization, for the way flags are defined, but still
an operation we can avoid in most cases.
Even though the check is likely to be relevant if the object is finalized,
it may still give some indication if called while an instance has just lost
the last reference.
So use `g_return_if_fail` for consistency with the rest of the code.
They return floating references, so that should be reflected in the
introspection annotations.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>