hjl / source-git / glibc

Forked from source-git/glibc 3 years ago
Clone

Blame elf/tst-nodelete-dlclose-dso.c

Packit 6c4009
/* Bug 11941: Improper assert map->l_init_called in dlclose.
Packit 6c4009
   Copyright (C) 2016-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
/* This is the primary DSO that is loaded by the appliation.  This DSO
Packit 6c4009
   then loads a plugin with RTLD_NODELETE.  This plugin depends on this
Packit 6c4009
   DSO.  This dependency chain means that at application shutdown the
Packit 6c4009
   plugin will be destructed first.  Thus by the time this DSO is
Packit 6c4009
   destructed we will be calling dlclose on an object that has already
Packit 6c4009
   been destructed.  It is allowed to call dlclose in this way and
Packit 6c4009
   should not assert.  */
Packit 6c4009
#include <stdio.h>
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <dlfcn.h>
Packit 6c4009
Packit 6c4009
/* Plugin to load.  */
Packit 6c4009
static void *plugin_lib = NULL;
Packit 6c4009
/* Plugin function.  */
Packit 6c4009
static void (*plugin_func) (void);
Packit 6c4009
#define LIB_PLUGIN "tst-nodelete-dlclose-plugin.so"
Packit 6c4009
Packit 6c4009
/* This function is never called but the plugin references it.
Packit 6c4009
   We do this to avoid any future --as-needed from removing the
Packit 6c4009
   plugin's DT_NEEDED on this DSO (required for the test).  */
Packit 6c4009
void
Packit 6c4009
primary_reference (void)
Packit 6c4009
{
Packit 6c4009
  printf ("INFO: Called primary_reference function.\n");
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
primary (void)
Packit 6c4009
{
Packit 6c4009
  char *error;
Packit 6c4009
Packit 6c4009
  plugin_lib = dlopen (LIB_PLUGIN, RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);
Packit 6c4009
  if (plugin_lib == NULL)
Packit 6c4009
    {
Packit 6c4009
      printf ("ERROR: Unable to load plugin library.\n");
Packit 6c4009
      exit (EXIT_FAILURE);
Packit 6c4009
    }
Packit 6c4009
  dlerror ();
Packit 6c4009
Packit 6c4009
  plugin_func = (void (*) (void)) dlsym (plugin_lib, "plugin_func");
Packit 6c4009
  error = dlerror ();
Packit 6c4009
  if (error != NULL)
Packit 6c4009
    {
Packit 6c4009
      printf ("ERROR: Unable to find symbol with error \"%s\".",
Packit 6c4009
	      error);
Packit 6c4009
      exit (EXIT_FAILURE);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  return;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
__attribute__ ((destructor))
Packit 6c4009
static void
Packit 6c4009
primary_dtor (void)
Packit 6c4009
{
Packit 6c4009
  int ret;
Packit 6c4009
Packit 6c4009
  printf ("INFO: Calling primary destructor.\n");
Packit 6c4009
Packit 6c4009
  /* The destructor runs in the test driver also, which
Packit 6c4009
     hasn't called primary, in that case do nothing.  */
Packit 6c4009
  if (plugin_lib == NULL)
Packit 6c4009
    return;
Packit 6c4009
Packit 6c4009
  ret = dlclose (plugin_lib);
Packit 6c4009
  if (ret != 0)
Packit 6c4009
    {
Packit 6c4009
      printf ("ERROR: Calling dlclose failed with \"%s\"\n",
Packit 6c4009
	      dlerror ());
Packit 6c4009
      exit (EXIT_FAILURE);
Packit 6c4009
    }
Packit 6c4009
}