After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 774645 - TSAN patches
TSAN patches
Status: RESOLVED OBSOLETE
Product: glib
Classification: Platform
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2016-11-17 20:46 UTC by Colin Walters
Modified: 2018-05-24 19:15 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
[TSAN] gobject: Change assertions to read values via atomics (1.91 KB, patch)
2016-11-17 20:46 UTC, Colin Walters
none Details | Review
[TSAN] gobject: Change assertions to read values via atomics (1.99 KB, patch)
2016-11-17 22:22 UTC, Colin Walters
needs-work Details | Review
[TSAN] gthread: Rework to avoid holding a mutex half the time (5.53 KB, patch)
2016-11-17 22:22 UTC, Colin Walters
needs-work Details | Review

Description Colin Walters 2016-11-17 20:46:32 UTC
I'm trying to use `-fsanitize=thread` for OSTree, and some of
these issues seem to go into GLib.  Also, the sanitizers work better if
the userspace libraries are built with them too.

This fix is similar to
https://github.com/ostreedev/ostree/pull/582/commits/b6814bb37cacd7a36715cf91766eb760b1b33c66

Mixing atomic and non-atomic reads trips TSAN, so let's change the
assertions to operate on the local values returned from atomic
read/writes.

Without this change I couldn't even *build* GLib with TSAN, since we
use gresources during compilation, which uses GSubprocess, which hits
this code.
Comment 1 Colin Walters 2016-11-17 20:46:40 UTC
Created attachment 340185 [details] [review]
[TSAN] gobject: Change assertions to read values via atomics
Comment 2 Colin Walters 2016-11-17 22:22:04 UTC
Created attachment 340193 [details] [review]
[TSAN] gobject: Change assertions to read values via atomics

I'm trying to use `-fsanitize=thread` for OSTree, and some of
these issues seem to go into GLib.  Also, the sanitizers work better if
the userspace libraries are built with them too.

This fix is similar to
https://github.com/ostreedev/ostree/pull/582/commits/b6814bb37cacd7a36715cf91766eb760b1b33c66

Mixing atomic and non-atomic reads trips TSAN, so let's change the
assertions to operate on the local values returned from atomic
read/writes.

Without this change I couldn't even *build* GLib with TSAN, since we
use gresources during compilation, which uses GSubprocess, which hits
this code.
Comment 3 Colin Walters 2016-11-17 22:22:09 UTC
Created attachment 340194 [details] [review]
[TSAN] gthread: Rework to avoid holding a mutex half the time

This code was a persistent source of `-fsanitize=thread` errors
when I was trying to use it on OSTree.

The problem is that while I think this code is functionally correct,
we hold a mutex during the writes, but not the reads, and TSAN (IMO
correctly) flags that.

Reading this, I don't see a reason we need a mutex at all.  At the
cost of some small code duplication between posix/win32, we can just
pass the data we need down into each implementation.  This ends up
being notably cleaner I think than the awkward "lock/unlock to
serialize" dance.
Comment 4 Colin Walters 2016-11-17 22:23:04 UTC
Note the first patch changes the behavior for "too many unreferences" from "spew to stderr" to "abort".  If someone cares we can change it.
Comment 5 Philip Withnall 2017-10-11 10:14:03 UTC
Review of attachment 340193 [details] [review]:

Looks good to me.
Comment 6 Philip Withnall 2017-10-11 10:16:39 UTC
Review of attachment 340193 [details] [review]:

::: gobject/gobject.c
@@ +3175,3 @@
       /* decrement the last reference */
       old_ref = g_atomic_int_add (&object->ref_count, -1);
+      g_assert (old_ref > 0);

Actually, no, let’s keep this as a g_return_if_fail() (in this new location). This code path is unfortunately hit too often for it to be sensible to abort here. Many buggy programs continue to work fine after we bail out of a double-unref call, since it’s typically only ever a double-unref and not a triple-unref, and when we bail out the program has already cleared its final pointer to the double-unreffed object.
Comment 7 Philip Withnall 2017-10-11 10:22:42 UTC
Review of attachment 340194 [details] [review]:

Looks good to me apart from a few nitpicks. A nice cleanup.

::: glib/gthread-posix.c
@@ +1145,2 @@
                      gulong        stack_size,
+                     const char    *name,

Nitpick: Argument alignment.

::: glib/gthread.c
@@ -770,3 @@
-   */
-  G_LOCK (g_thread_new);
-  G_UNLOCK (g_thread_new);

You can also delete the
  G_LOCK_DEFINE_STATIC (g_thread_new);
now, right?

::: glib/gthreadprivate.h
@@ +42,2 @@
                                                  gulong        stack_size,
+                                                 const char    *name,

Nitpick: Argument alignment.
Comment 8 GNOME Infrastructure Team 2018-05-24 19:15:41 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glib/issues/1224.