Blame tests/dwfl-proc-attach.c

Packit Service 97d2fb
/* Test dwfl_linux_proc_attach works without any modules.
Packit Service 97d2fb
   Copyright (C) 2015 Red Hat, Inc.
Packit Service 97d2fb
   This file is part of elfutils.
Packit Service 97d2fb
Packit Service 97d2fb
   This file is free software; you can redistribute it and/or modify
Packit Service 97d2fb
   it under the terms of the GNU General Public License as published by
Packit Service 97d2fb
   the Free Software Foundation; either version 3 of the License, or
Packit Service 97d2fb
   (at your option) any later version.
Packit Service 97d2fb
Packit Service 97d2fb
   elfutils is distributed in the hope that it will be useful, but
Packit Service 97d2fb
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 97d2fb
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 97d2fb
   GNU General Public License for more details.
Packit Service 97d2fb
Packit Service 97d2fb
   You should have received a copy of the GNU General Public License
Packit Service 97d2fb
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit Service 97d2fb
Packit Service 97d2fb
#include <config.h>
Packit Service 97d2fb
#include <inttypes.h>
Packit Service 97d2fb
#include <stdio.h>
Packit Service 97d2fb
#include <stdlib.h>
Packit Service 97d2fb
#include <errno.h>
Packit Service 97d2fb
#include <unistd.h>
Packit Service 97d2fb
#ifdef __linux__
Packit Service 97d2fb
#include <sys/types.h>
Packit Service 97d2fb
#include <sys/stat.h>
Packit Service 97d2fb
#include <sys/user.h>
Packit Service 97d2fb
#include <fcntl.h>
Packit Service 97d2fb
#include <string.h>
Packit Service 97d2fb
#include ELFUTILS_HEADER(dwfl)
Packit Service 97d2fb
#include <pthread.h>
Packit Service 97d2fb
#endif
Packit Service 97d2fb
#include "system.h"
Packit Service 97d2fb
Packit Service 97d2fb
#ifndef __linux__
Packit Service 97d2fb
int
Packit Service 97d2fb
main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)))
Packit Service 97d2fb
{
Packit Service 97d2fb
  printf ("dwfl_linux_proc_attach unsupported.\n");
Packit Service 97d2fb
  return 77;
Packit Service 97d2fb
}
Packit Service 97d2fb
#else /* __linux__ */
Packit Service 97d2fb
Packit Service 97d2fb
static pthread_t thread1;
Packit Service 97d2fb
static pthread_t thread2;
Packit Service 97d2fb
Packit Service 97d2fb
static void *
Packit Service 97d2fb
sleeper (void* d __attribute__ ((unused)))
Packit Service 97d2fb
{
Packit Service 97d2fb
  sleep (60);
Packit Service 97d2fb
  return NULL;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
static char *debuginfo_path = NULL;
Packit Service 97d2fb
Packit Service 97d2fb
static const Dwfl_Callbacks proc_callbacks =
Packit Service 97d2fb
  {
Packit Service 97d2fb
    .find_elf = dwfl_linux_proc_find_elf,
Packit Service 97d2fb
    .find_debuginfo = dwfl_standard_find_debuginfo,
Packit Service 97d2fb
    .debuginfo_path = &debuginfo_path,
Packit Service 97d2fb
  };
Packit Service 97d2fb
Packit Service 97d2fb
static int
Packit Service 97d2fb
thread_callback (Dwfl_Thread *thread, void *thread_arg)
Packit Service 97d2fb
{
Packit Service 97d2fb
  int *threads = (int *) thread_arg;
Packit Service 97d2fb
  pid_t tid = dwfl_thread_tid (thread);
Packit Service 97d2fb
  printf ("thread tid: %d\n", tid);
Packit Service 97d2fb
  (*threads)++;
Packit Service 97d2fb
Packit Service 97d2fb
  return DWARF_CB_OK;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
int
Packit Service 97d2fb
main (int argc __attribute__ ((unused)),
Packit Service 97d2fb
      char **argv __attribute__ ((unused)))
Packit Service 97d2fb
{
Packit Service 97d2fb
  /* Create two extra threads to iterate through.  */
Packit Service 97d2fb
  int err;
Packit Service 97d2fb
  if ((err = pthread_create (&thread1, NULL, sleeper, NULL)) != 0)
Packit Service 97d2fb
    error (-1, err, "Couldn't create thread1");
Packit Service 97d2fb
  if ((err = pthread_create (&thread2, NULL, sleeper, NULL)) != 0)
Packit Service 97d2fb
    error (-1, err, "Couldn't create thread2");
Packit Service 97d2fb
Packit Service 97d2fb
  Dwfl *dwfl = dwfl_begin (&proc_callbacks);
Packit Service 97d2fb
  if (dwfl == NULL)
Packit Service 97d2fb
    error (-1, 0, "dwfl_begin: %s", dwfl_errmsg (-1));
Packit Service 97d2fb
Packit Service 97d2fb
  pid_t pid = getpid ();
Packit Service 97d2fb
  /* This used to fail, since we don't have any modules yet.  */
Packit Service 97d2fb
  if (dwfl_linux_proc_attach (dwfl, pid, false) < 0)
Packit Service 97d2fb
    error (-1, 0, "dwfl_linux_proc_attach pid %d: %s", pid,
Packit Service 97d2fb
	   dwfl_errmsg (-1));
Packit Service 97d2fb
Packit Service 97d2fb
  /* Did we see all 3 threads?  */
Packit Service 97d2fb
  int threads = 0;
Packit Service 97d2fb
  if (dwfl_getthreads (dwfl, thread_callback, &threads) != DWARF_CB_OK)
Packit Service 97d2fb
    error (-1, 0, "dwfl_getthreads failed: %s", dwfl_errmsg (-1));
Packit Service 97d2fb
Packit Service 97d2fb
  dwfl_end (dwfl);
Packit Service 97d2fb
Packit Service 97d2fb
  pthread_cancel (thread1);
Packit Service 97d2fb
  pthread_cancel (thread2);
Packit Service 97d2fb
  pthread_join (thread1, NULL);
Packit Service 97d2fb
  pthread_join (thread2, NULL);
Packit Service 97d2fb
Packit Service 97d2fb
  return (threads == 3) ? 0 : -1;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
/* HACK. This is a simple workaround for a combination of old glibc
Packit Service 97d2fb
   and valgrind. libdw will try to dlopen libdebuginfod this causes
Packit Service 97d2fb
   some unsuppressable memory leak warnings when the process is
Packit Service 97d2fb
   multi-threaded under valgrind because of some bad backtraces.
Packit Service 97d2fb
   So simply override dlopen and always return NULL so libdebuginfod
Packit Service 97d2fb
   (and libcurl) are never loaded.  This test doesn't rely on
Packit Service 97d2fb
   libdebuginfod anyway.  */
Packit Service 97d2fb
void *dlopen (void)
Packit Service 97d2fb
{
Packit Service 97d2fb
  return NULL;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
#endif /* __linux__ */