mirror of
https://github.com/edu4rdshl/gnome-shell.git
synced 2026-07-17 23:24:51 +00:00
Get uninstalled libraries from environment in preference to ELF headers
Introspecting the dynamic headers is low-level and full of implementation
details.
It seems that gnome-shell was assuming the address of the string table is
given by taking the DT_STRTAB dynamic symbol table's value (d_un.d_val)
and casting it to an absolute pointer. However, in some environments
(apparently including Debian mips64el) the DT_STRTAB dynamic symbol
table's d_un.d_val can be merely an offset relative to the base address
of the executable in memory. The base address would have to be parsed from
a different ELF header, which as far as I know is not part of _DYNAMIC.
Rather than trying to look up the Shell executable's base address using
dlinfo() or similar, during unit testing it seems easier to pass in the
uninstalled library search path in the environment, along with other
uninstalled paths that we are going to need anyway.
The reason given for not using GI_TYPELIB_PATH in commit 9bc89b82
"main: Prepend RPATH or RUNPATH paths to gir search paths" was that
g_irepository_prepend_library_path() takes precedence, but we can easily
define our own environment variable that takes even higher precedence.
If it's set, we might as well also bypass the PKGLIBDIR, since while
running uninstalled we *only* want to use the uninstalled libraries.
When not running unit tests, it's desirable to make
`./build/src/gnome-shell` something you can run directly, so continue
to parse the ELF headers - but only on x86_64, where we're reasonably
confident that it works and any regressions with a newer glibc will
be noticed promptly.
Resolves: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6877
Bug-Debian: https://bugs.debian.org/1042980
Signed-off-by: Simon McVittie <smcv@debian.org>
This commit is contained in:
parent
3c175bce05
commit
a0f8774a70
2 changed files with 36 additions and 7 deletions
39
src/main.c
39
src/main.c
|
|
@ -129,10 +129,16 @@ shell_dbus_init (gboolean replace)
|
|||
g_object_unref (session);
|
||||
}
|
||||
|
||||
#ifdef HAVE_EXE_INTROSPECTION
|
||||
static void
|
||||
maybe_add_rpath_introspection_paths (void)
|
||||
{
|
||||
/* We're reasonably confident that this works reliably on x86_64, but
|
||||
* on other architectures it can go wrong: for example it seems that
|
||||
* on mips*el, the DT_STRTAB is an offset relative to the base address
|
||||
* of the executable, rather than a ready-to-use pointer.
|
||||
*
|
||||
* Other architectures can be added here, but please test them first. */
|
||||
#if defined(HAVE_EXE_INTROSPECTION) && defined(__x86_64__)
|
||||
ElfW (Dyn) *dyn;
|
||||
ElfW (Dyn) *rpath = NULL;
|
||||
ElfW (Dyn) *runpath = NULL;
|
||||
|
|
@ -194,15 +200,15 @@ maybe_add_rpath_introspection_paths (void)
|
|||
g_irepository_prepend_search_path (rpath_dir->str);
|
||||
g_irepository_prepend_library_path (rpath_dir->str);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_EXE_INTROSPECTION */
|
||||
}
|
||||
|
||||
static void
|
||||
shell_introspection_init (void)
|
||||
{
|
||||
const char *env;
|
||||
|
||||
g_irepository_prepend_search_path (MUTTER_TYPELIB_DIR);
|
||||
g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
|
||||
|
||||
/* We need to explicitly add the directories where the private libraries are
|
||||
* installed to the GIR's library path, so that they can be found at runtime
|
||||
|
|
@ -210,11 +216,30 @@ shell_introspection_init (void)
|
|||
* for some linkers (e.g. gold) and in some distros (e.g. Debian).
|
||||
*/
|
||||
g_irepository_prepend_library_path (MUTTER_TYPELIB_DIR);
|
||||
g_irepository_prepend_library_path (GNOME_SHELL_PKGLIBDIR);
|
||||
|
||||
#ifdef HAVE_EXE_INTROSPECTION
|
||||
maybe_add_rpath_introspection_paths ();
|
||||
#endif
|
||||
env = g_getenv ("GNOME_SHELL_TEST_LIBRARY_PATH");
|
||||
|
||||
if (env != NULL)
|
||||
{
|
||||
g_auto (GStrv) paths = NULL;
|
||||
char **str;
|
||||
|
||||
paths = g_strsplit (env, ":", -1);
|
||||
|
||||
for (str = paths; *str; str++)
|
||||
{
|
||||
g_debug ("Prepending '%s' to introspection library search path",
|
||||
*str);
|
||||
g_irepository_prepend_search_path (*str);
|
||||
g_irepository_prepend_library_path (*str);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
|
||||
g_irepository_prepend_library_path (GNOME_SHELL_PKGLIBDIR);
|
||||
maybe_add_rpath_introspection_paths ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -61,6 +61,10 @@ shell_testenv.set('GNOME_SHELL_DATADIR', data_builddir)
|
|||
shell_testenv.set('GNOME_SHELL_BUILDDIR', src_builddir)
|
||||
shell_testenv.set('GNOME_SHELL_SESSION_MODE', 'user')
|
||||
shell_testenv.set('SHELL_BACKGROUND_IMAGE', '@0@'.format(background_file))
|
||||
shell_testenv.set('GNOME_SHELL_TEST_LIBRARY_PATH', ':'.join([
|
||||
src_builddir,
|
||||
src_builddir / 'st',
|
||||
]))
|
||||
shell_testenv.append('GI_TYPELIB_PATH', gvc_typelib_path, separator: ':')
|
||||
shell_testenv.append('LD_LIBRARY_PATH', libgvc_path, separator: ':')
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue