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 638941 - registry scan/loading race and inconsistency
registry scan/loading race and inconsistency
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
git master
Other Linux
: Normal blocker
: 0.10.32
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2011-01-07 21:36 UTC by Edward Hervey
Modified: 2011-01-10 10:42 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
rm test-registry.reg && rm pipelines/gio && GST_DEBUG=2,check:5,*LOAD*:5,*REG*:5 make check -j5 > log-plugin2 2>&1 (341.25 KB, application/x-bzip)
2011-01-07 21:36 UTC, Edward Hervey
  Details
registry: Don't replace valid existing plugins by blacklisted ones (1.98 KB, patch)
2011-01-08 13:55 UTC, Edward Hervey
committed Details | Review

Description Edward Hervey 2011-01-07 21:36:52 UTC
Created attachment 177785 [details]
rm test-registry.reg && rm pipelines/gio && GST_DEBUG=2,check:5,*LOAD*:5,*REG*:5 make check -j5 > log-plugin2 2>&1

When running the unit tests in -base, the gio test sometimes fails with the following error :
Running suite(s): gio
0%: Checks: 1, Failures: 1, Errors: 0
pipelines/gio.c:96:F:general:test_memory_stream:0: Assertion 'src != NULL' failed
FAIL: pipelines/gio

What's actually happening is that it actually attempted to load the libgstgio from /usr/lib, which was blacklisted and therefore had zero features. And obviously... it couldn't create a giostreamsrc element since that plugin doesn't have one.

The local source libgstgio.so does exist, is valid, has all the features.

This only happens with the subprocess scanning.

This is one is tricky... so bare with me for the explanations (debug logs attached).

The registry scan (to create/update test-registry.reg) does the following:
* The parent process scans the various paths for potential .so
 * It checks if a potential .so isn't already register
 * If there isn't already a registered plugin with the same basename (libgstFOO.so) it sends it to the child process to be scanned
   * CHILD : processes the incoming .so, checks it against a potential whitelist, and eventually returns the information back to the parent process
 * The parent process receives plugin info from the child process and calls gst_registry_add_plugin()
  * If a plugin with the same basename isn't already present it adds it
  * If a plugin with the same basename is already present it replaces it with the new one

Where the race happens:

* parent scans potential .so in local source (including the local libgstgio.so) and sends it to child
  * CHILD : eventually sends it back (stress-word : eventually)
* parent scans system-wide paths for potential .so (including libgstgio.so).
  => The problem is that the child might have not sent back the result from scanning the local libgstgio.so at that time. And therefore the parent process thinks libgstgio.so is a new plugin and sends it to the child process to scan
  * CHILD : sends back the results from scanning the local libgstgio.so
   * PARENT : adds it to registry
  * CHILD : scans system-wide libgstgio.so, but since we have a whitelist and it's not in it it is marked as blacklisted and no features are added to it and sends it back to the parent
   * PARENT : adds system-wide libgstgio.so to registry. There already is an existing libgstgio.so .... and it therefore replaces it by the new (system-wide, blacklisted, 0 features) libgstgio.so
    => FAILURE ENSUES

How to solve this:
in gst_registry_add_plugin, if there's already an existing same-basename plugin... check if either the new or existing plugin is blacklisted and make a *smart* choice on whether to replace the existing plugin by the new one or ignore the new one.
Comment 1 Edward Hervey 2011-01-07 21:39:58 UTC
Actually, my proposed fix needs to be fine-tuned, because you could very well end up in the situation where a plugin (with the same exact location) was modified and isn't working anymore.

So we shouldn't just check the basename, but actually the full path.
Comment 2 Edward Hervey 2011-01-08 13:55:15 UTC
Created attachment 177822 [details] [review]
registry: Don't replace valid existing plugins by blacklisted ones

Only replace existing plugins by blacklisted ones if they correspond
to the exact same plugin. If they're not the same, keep the existing
valid one.

Fixes #638941
Comment 3 Edward Hervey 2011-01-10 10:42:14 UTC
commit 8edee55a3a2241ef4d83df6ec405bc4ba6ba42f0
Author: Edward Hervey <bilboed@bilboed.com>
Date:   Sat Jan 8 14:52:27 2011 +0100

    registry: Don't replace valid existing plugins by blacklisted ones
    
    Only replace existing plugins by blacklisted ones if they correspond
    to the exact same plugin. If they're not the same, keep the existing
    valid one.
    
    Fixes #638941