This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] elf: Remove pldd (BZ#18035)



On 10/04/2019 17:17, Carlos O'Donell wrote:
> On 4/10/19 3:04 PM, Adhemerval Zanella wrote:
>> As reported in bugzilla itself and on man-pages [1] it has been
>> broken since 2.19.  Also, its design tie glibc internal definition
>> by duplicate struct layouts and dynamic loader objects.
> 
> I have a sustained objection to removing pldd.
> 
> Have we looked into why it's broken?

I will take a second look, but my wildly guess is most likely some
internal linker interface has drift from pldd internal definitions
and when it tries to poke on process memory it reads invalid memory.

> 
> I'm happy to add a test-in-container runtime test for it so we can
> see breakage when it happens.
> 
> It matches the same Solaris tool pldd, and is a useful utility.

I agree it is useful, but the same functionally can be provided with
different tools and/or kernel facilities.  The advantage I see that
pldd might have it is suppose to poke on internal glibc data structures
and get the loaded dynamic shared objects without relying on additional
kernel information.

> 
> We probably haven't seen a problem because enterprise uses might have
> patched pldd to fix it, or RHEL7 which is on 2.17 still has a working
> version.

The Ubuntu version I have installed all show the same issue (14.04, 16.04,
and 18.04).

> 
>> Also, as noted by man-pages the same behavior can be obtained with
>>
>>    $ gdb -ex "set confirm off" -ex "set height 0" -ex "info shared" \
>>                         -ex "quit" -p $pid | grep '^0x.*0x'
> 
> That relies on a debugger on the target system and it might be a problem
> on production systems.

This is just an example on how to obtain the same information.

> 
>>
>> Or with external tools as 'lsof'.  An alternative way to show the
>> dynamic shared objects liked into a process on Linux would be to
>> use the /proc/<pid>/maps instead as following example:
>>
>> ---
>>
>> import sys, os
>>
>> def main(argv):
>>    with open('/proc/' + argv[0] + '/maps', 'r') as maps:
>>      segs = {}
>>      st = os.stat('/proc/' + argv[0] + '/exe')
>>      for line in maps:
>>        fields = line.split()
>>        if len(fields) < 5:
>>          continue
>>        major,minor = fields[3].split(':')
>>        dev = os.makedev(int(major), int(minor))
>>        inode = int(fields[4])
>>        if dev == 0 or inode == 0:
>>          continue
>>        # Skip the map entry if the device + inode pair match that of the exe.
>>        if dev == st.st_dev or inode == st.st_ino:
>>          continue
>>
>>        # Check if file is accessible.
>>        try:
>>          segst = os.stat(fields[5])
>>        except OSError:
>>          continue
>>
>>        # Print only executable segments.
>>        if 'x' in fields[1]:
>>          print(fields[5])
>>
>> if __name__ == '__main__':
>>    main(sys.argv[1:])
> 
> This requires python in base runtime, and might not be on a production
> container instance.

Ok, the question I have is whether we want to make pldd still poke the loader
internal data structures directly using /proc/<pid>/mem plus ptrace or if we
can use a simplified version by parsing /proc/<pid>/maps (as lsof does).

For latter, why we can't use use lsof instead? Do we really need to provide
a similar tool (but will less features)?

> 
>> ---
>>
>> Checked on x86_64-linux-gnu.
>>
>>     * elf/pldd-xx.c: Remove file.
>>     * elf/pldd.c: Likewise.
>>     * sysdeps/unix/sysv/linux/Makefile [$(subdir) == elf] (pldd): Remove
>>     rule.
> 
> What's wrong with fixing pldd?
> 
>> [1] http://man7.org/linux/man-pages/man1/pldd.1.html
>> ---
>>   elf/pldd-xx.c                    | 251 ----------------------
>>   elf/pldd.c                       | 344 -------------------------------
>>   sysdeps/unix/sysv/linux/Makefile |   4 -
>>   3 files changed, 599 deletions(-)
>>   delete mode 100644 elf/pldd-xx.c
>>   delete mode 100644 elf/pldd.c
>>
>> diff --git a/elf/pldd-xx.c b/elf/pldd-xx.c
>> deleted file mode 100644
>> index 547f840ee1..0000000000
>> --- a/elf/pldd-xx.c
>> +++ /dev/null
>> @@ -1,251 +0,0 @@
>> -/* Copyright (C) 2011-2019 Free Software Foundation, Inc.
>> -   This file is part of the GNU C Library.
>> -   Contributed by Ulrich Drepper <drepper@gmail.com>, 2011.
>> -
>> -   The GNU C Library is free software; you can redistribute it and/or
>> -   modify it under the terms of the GNU Lesser General Public
>> -   License as published by the Free Software Foundation; either
>> -   version 2.1 of the License, or (at your option) any later version.
>> -
>> -   The GNU C Library is distributed in the hope that it will be useful,
>> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
>> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> -   Lesser General Public License for more details.
>> -
>> -   You should have received a copy of the GNU Lesser General Public
>> -   License along with the GNU C Library; if not, see
>> -   <http://www.gnu.org/licenses/>.  */
>> -
>> -#define E(name) E_(name, CLASS)
>> -#define E_(name, cl) E__(name, cl)
>> -#define E__(name, cl) name##cl
>> -#define EW(type) EW_(Elf, CLASS, type)
>> -#define EW_(e, w, t) EW__(e, w, _##t)
>> -#define EW__(e, w, t) e##w##t
>> -
>> -#define pldd_assert(name, exp) \
>> -  typedef int __assert_##name[((exp) != 0) - 1]
>> -
>> -
>> -struct E(link_map)
>> -{
>> -  EW(Addr) l_addr;
>> -  EW(Addr) l_name;
>> -  EW(Addr) l_ld;
>> -  EW(Addr) l_next;
>> -  EW(Addr) l_prev;
>> -  EW(Addr) l_real;
>> -  Lmid_t l_ns;
>> -  EW(Addr) l_libname;
>> -};
>> -#if CLASS == __ELF_NATIVE_CLASS
>> -pldd_assert (l_addr, (offsetof (struct link_map, l_addr)
>> -            == offsetof (struct E(link_map), l_addr)));
>> -pldd_assert (l_name, (offsetof (struct link_map, l_name)
>> -            == offsetof (struct E(link_map), l_name)));
>> -pldd_assert (l_next, (offsetof (struct link_map, l_next)
>> -            == offsetof (struct E(link_map), l_next)));
>> -#endif
>> -
>> -
>> -struct E(libname_list)
>> -{
>> -  EW(Addr) name;
>> -  EW(Addr) next;
>> -};
>> -#if CLASS == __ELF_NATIVE_CLASS
>> -pldd_assert (name, (offsetof (struct libname_list, name)
>> -              == offsetof (struct E(libname_list), name)));
>> -pldd_assert (next, (offsetof (struct libname_list, next)
>> -              == offsetof (struct E(libname_list), next)));
>> -#endif
>> -
>> -struct E(r_debug)
>> -{
>> -  int r_version;
>> -#if CLASS == 64
>> -  int pad;
>> -#endif
>> -  EW(Addr) r_map;
>> -};
>> -#if CLASS == __ELF_NATIVE_CLASS
>> -pldd_assert (r_version, (offsetof (struct r_debug, r_version)
>> -               == offsetof (struct E(r_debug), r_version)));
>> -pldd_assert (r_map, (offsetof (struct r_debug, r_map)
>> -               == offsetof (struct E(r_debug), r_map)));
>> -#endif
>> -
>> -
>> -static int
>> -
>> -E(find_maps) (pid_t pid, void *auxv, size_t auxv_size)
>> -{
>> -  EW(Addr) phdr = 0;
>> -  unsigned int phnum = 0;
>> -  unsigned int phent = 0;
>> -
>> -  EW(auxv_t) *auxvXX = (EW(auxv_t) *) auxv;
>> -  for (int i = 0; i < auxv_size / sizeof (EW(auxv_t)); ++i)
>> -    switch (auxvXX[i].a_type)
>> -      {
>> -      case AT_PHDR:
>> -    phdr = auxvXX[i].a_un.a_val;
>> -    break;
>> -      case AT_PHNUM:
>> -    phnum = auxvXX[i].a_un.a_val;
>> -    break;
>> -      case AT_PHENT:
>> -    phent = auxvXX[i].a_un.a_val;
>> -    break;
>> -      default:
>> -    break;
>> -      }
>> -
>> -  if (phdr == 0 || phnum == 0 || phent == 0)
>> -    error (EXIT_FAILURE, 0, gettext ("cannot find program header of process"));
>> -
>> -  EW(Phdr) *p = alloca (phnum * phent);
>> -  if (pread64 (memfd, p, phnum * phent, phdr) != phnum * phent)
>> -    {
>> -      error (0, 0, gettext ("cannot read program header"));
>> -      return EXIT_FAILURE;
>> -    }
>> -
>> -  /* Determine the load offset.  We need this for interpreting the
>> -     other program header entries so we do this in a separate loop.
>> -     Fortunately it is the first time unless someone does something
>> -     stupid when linking the application.  */
>> -  EW(Addr) offset = 0;
>> -  for (unsigned int i = 0; i < phnum; ++i)
>> -    if (p[i].p_type == PT_PHDR)
>> -      {
>> -    offset = phdr - p[i].p_vaddr;
>> -    break;
>> -      }
>> -
>> -  EW(Addr) list = 0;
>> -  char *interp = NULL;
>> -  for (unsigned int i = 0; i < phnum; ++i)
>> -    if (p[i].p_type == PT_DYNAMIC)
>> -      {
>> -    EW(Dyn) *dyn = xmalloc (p[i].p_filesz);
>> -    if (pread64 (memfd, dyn, p[i].p_filesz, offset + p[i].p_vaddr)
>> -        != p[i].p_filesz)
>> -      {
>> -        error (0, 0, gettext ("cannot read dynamic section"));
>> -        return EXIT_FAILURE;
>> -      }
>> -
>> -    /* Search for the DT_DEBUG entry.  */
>> -    for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j)
>> -      if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0)
>> -        {
>> -          struct E(r_debug) r;
>> -          if (pread64 (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr)
>> -          != sizeof (r))
>> -        {
>> -          error (0, 0, gettext ("cannot read r_debug"));
>> -          return EXIT_FAILURE;
>> -        }
>> -
>> -          if (r.r_map != 0)
>> -        {
>> -          list = r.r_map;
>> -          break;
>> -        }
>> -        }
>> -
>> -    free (dyn);
>> -    break;
>> -      }
>> -    else if (p[i].p_type == PT_INTERP)
>> -      {
>> -    interp = alloca (p[i].p_filesz);
>> -    if (pread64 (memfd, interp, p[i].p_filesz, offset + p[i].p_vaddr)
>> -        != p[i].p_filesz)
>> -      {
>> -        error (0, 0, gettext ("cannot read program interpreter"));
>> -        return EXIT_FAILURE;
>> -      }
>> -      }
>> -
>> -  if (list == 0)
>> -    {
>> -      if (interp == NULL)
>> -    {
>> -      // XXX check whether the executable itself is the loader
>> -      return EXIT_FAILURE;
>> -    }
>> -
>> -      // XXX perhaps try finding ld.so and _r_debug in it
>> -
>> -      return EXIT_FAILURE;
>> -    }
>> -
>> -  /* Print the PID and program name first.  */
>> -  printf ("%lu:\t%s\n", (unsigned long int) pid, exe);
>> -
>> -  /* Iterate over the list of objects and print the information.  */
>> -  struct scratch_buffer tmpbuf;
>> -  scratch_buffer_init (&tmpbuf);
>> -  int status = 0;
>> -  do
>> -    {
>> -      struct E(link_map) m;
>> -      if (pread64 (memfd, &m, sizeof (m), list) != sizeof (m))
>> -    {
>> -      error (0, 0, gettext ("cannot read link map"));
>> -      status = EXIT_FAILURE;
>> -      goto out;
>> -    }
>> -
>> -      EW(Addr) name_offset = m.l_name;
>> -    again:
>> -      while (1)
>> -    {
>> -      ssize_t n = pread64 (memfd, tmpbuf.data, tmpbuf.length, name_offset);
>> -      if (n == -1)
>> -        {
>> -          error (0, 0, gettext ("cannot read object name"));
>> -          status = EXIT_FAILURE;
>> -          goto out;
>> -        }
>> -
>> -      if (memchr (tmpbuf.data, '\0', n) != NULL)
>> -        break;
>> -
>> -      if (!scratch_buffer_grow (&tmpbuf))
>> -        {
>> -          error (0, 0, gettext ("cannot allocate buffer for object name"));
>> -          status = EXIT_FAILURE;
>> -          goto out;
>> -        }
>> -    }
>> -
>> -      if (((char *)tmpbuf.data)[0] == '\0' && name_offset == m.l_name
>> -      && m.l_libname != 0)
>> -    {
>> -      /* Try the l_libname element.  */
>> -      struct E(libname_list) ln;
>> -      if (pread64 (memfd, &ln, sizeof (ln), m.l_libname) == sizeof (ln))
>> -        {
>> -          name_offset = ln.name;
>> -          goto again;
>> -        }
>> -    }
>> -
>> -      /* Skip over the executable.  */
>> -      if (((char *)tmpbuf.data)[0] != '\0')
>> -    printf ("%s\n", (char *)tmpbuf.data);
>> -
>> -      list = m.l_next;
>> -    }
>> -  while (list != 0);
>> -
>> - out:
>> -  scratch_buffer_free (&tmpbuf);
>> -  return status;
>> -}
>> -
>> -
>> -#undef CLASS
>> diff --git a/elf/pldd.c b/elf/pldd.c
>> deleted file mode 100644
>> index f3fac4e487..0000000000
>> --- a/elf/pldd.c
>> +++ /dev/null
>> @@ -1,344 +0,0 @@
>> -/* List dynamic shared objects linked into given process.
>> -   Copyright (C) 2011-2019 Free Software Foundation, Inc.
>> -   This file is part of the GNU C Library.
>> -   Contributed by Ulrich Drepper <drepper@gmail.com>, 2011.
>> -
>> -   The GNU C Library is free software; you can redistribute it and/or
>> -   modify it under the terms of the GNU Lesser General Public
>> -   License as published by the Free Software Foundation; either
>> -   version 2.1 of the License, or (at your option) any later version.
>> -
>> -   The GNU C Library is distributed in the hope that it will be useful,
>> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
>> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> -   Lesser General Public License for more details.
>> -
>> -   You should have received a copy of the GNU Lesser General Public
>> -   License along with the GNU C Library; if not, see
>> -   <http://www.gnu.org/licenses/>.  */
>> -
>> -#include <alloca.h>
>> -#include <argp.h>
>> -#include <assert.h>
>> -#include <dirent.h>
>> -#include <elf.h>
>> -#include <errno.h>
>> -#include <error.h>
>> -#include <fcntl.h>
>> -#include <libintl.h>
>> -#include <link.h>
>> -#include <stddef.h>
>> -#include <stdio.h>
>> -#include <stdlib.h>
>> -#include <string.h>
>> -#include <unistd.h>
>> -#include <sys/ptrace.h>
>> -#include <sys/stat.h>
>> -#include <sys/wait.h>
>> -#include <scratch_buffer.h>
>> -
>> -#include <ldsodefs.h>
>> -#include <version.h>
>> -
>> -/* Global variables.  */
>> -extern char *program_invocation_short_name;
>> -#define PACKAGE _libc_intl_domainname
>> -
>> -/* External functions.  */
>> -#include <programs/xmalloc.h>
>> -
>> -/* Name and version of program.  */
>> -static void print_version (FILE *stream, struct argp_state *state);
>> -void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
>> -
>> -/* Function to print some extra text in the help message.  */
>> -static char *more_help (int key, const char *text, void *input);
>> -
>> -/* Definitions of arguments for argp functions.  */
>> -static const struct argp_option options[] =
>> -{
>> -  { NULL, 0, NULL, 0, NULL }
>> -};
>> -
>> -/* Short description of program.  */
>> -static const char doc[] = N_("\
>> -List dynamic shared objects loaded into process.");
>> -
>> -/* Strings for arguments in help texts.  */
>> -static const char args_doc[] = N_("PID");
>> -
>> -/* Prototype for option handler.  */
>> -static error_t parse_opt (int key, char *arg, struct argp_state *state);
>> -
>> -/* Data structure to communicate with argp functions.  */
>> -static struct argp argp =
>> -{
>> -  options, parse_opt, args_doc, doc, NULL, more_help, NULL
>> -};
>> -
>> -// File descriptor of /proc/*/mem file.
>> -static int memfd;
>> -
>> -/* Name of the executable  */
>> -static char *exe;
>> -
>> -/* Local functions.  */
>> -static int get_process_info (int dfd, long int pid);
>> -static void wait_for_ptrace_stop (long int pid);
>> -
>> -
>> -int
>> -main (int argc, char *argv[])
>> -{
>> -  /* Parse and process arguments.  */
>> -  int remaining;
>> -  argp_parse (&argp, argc, argv, 0, &remaining, NULL);
>> -
>> -  if (remaining != argc - 1)
>> -    {
>> -      fprintf (stderr,
>> -           gettext ("Exactly one parameter with process ID required.\n"));
>> -      argp_help (&argp, stderr, ARGP_HELP_SEE, program_invocation_short_name);
>> -      return 1;
>> -    }
>> -
>> -  assert (sizeof (pid_t) == sizeof (int)
>> -      || sizeof (pid_t) == sizeof (long int));
>> -  char *endp;
>> -  errno = 0;
>> -  long int pid = strtol (argv[remaining], &endp, 10);
>> -  if (pid < 0 || (pid == ULONG_MAX && errno == ERANGE) || *endp != '\0'
>> -      || (sizeof (pid_t) < sizeof (pid) && pid > INT_MAX))
>> -    error (EXIT_FAILURE, 0, gettext ("invalid process ID '%s'"),
>> -       argv[remaining]);
>> -
>> -  /* Determine the program name.  */
>> -  char buf[7 + 3 * sizeof (pid)];
>> -  snprintf (buf, sizeof (buf), "/proc/%lu", pid);
>> -  int dfd = open (buf, O_RDONLY | O_DIRECTORY);
>> -  if (dfd == -1)
>> -    error (EXIT_FAILURE, errno, gettext ("cannot open %s"), buf);
>> -
>> -  struct scratch_buffer exebuf;
>> -  scratch_buffer_init (&exebuf);
>> -  ssize_t nexe;
>> -  while ((nexe = readlinkat (dfd, "exe",
>> -                 exebuf.data, exebuf.length)) == exebuf.length)
>> -    {
>> -      if (!scratch_buffer_grow (&exebuf))
>> -    {
>> -      nexe = -1;
>> -      break;
>> -    }
>> -    }
>> -  if (nexe == -1)
>> -    exe = (char *) "<program name undetermined>";
>> -  else
>> -    {
>> -      exe = exebuf.data;
>> -      exe[nexe] = '\0';
>> -    }
>> -
>> -  /* Stop all threads since otherwise the list of loaded modules might
>> -     change while we are reading it.  */
>> -  struct thread_list
>> -  {
>> -    pid_t tid;
>> -    struct thread_list *next;
>> -  } *thread_list = NULL;
>> -
>> -  int taskfd = openat (dfd, "task", O_RDONLY | O_DIRECTORY | O_CLOEXEC);
>> -  if (taskfd == 1)
>> -    error (EXIT_FAILURE, errno, gettext ("cannot open %s/task"), buf);
>> -  DIR *dir = fdopendir (taskfd);
>> -  if (dir == NULL)
>> -    error (EXIT_FAILURE, errno, gettext ("cannot prepare reading %s/task"),
>> -       buf);
>> -
>> -  struct dirent64 *d;
>> -  while ((d = readdir64 (dir)) != NULL)
>> -    {
>> -      if (! isdigit (d->d_name[0]))
>> -    continue;
>> -
>> -      errno = 0;
>> -      long int tid = strtol (d->d_name, &endp, 10);
>> -      if (tid < 0 || (tid == ULONG_MAX && errno == ERANGE) || *endp != '\0'
>> -      || (sizeof (pid_t) < sizeof (pid) && tid > INT_MAX))
>> -    error (EXIT_FAILURE, 0, gettext ("invalid thread ID '%s'"),
>> -           d->d_name);
>> -
>> -      if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0)
>> -    {
>> -      /* There might be a race between reading the directory and
>> -         threads terminating.  Ignore errors attaching to unknown
>> -         threads unless this is the main thread.  */
>> -      if (errno == ESRCH && tid != pid)
>> -        continue;
>> -
>> -      error (EXIT_FAILURE, errno, gettext ("cannot attach to process %lu"),
>> -         tid);
>> -    }
>> -
>> -      wait_for_ptrace_stop (tid);
>> -
>> -      struct thread_list *newp = alloca (sizeof (*newp));
>> -      newp->tid = tid;
>> -      newp->next = thread_list;
>> -      thread_list = newp;
>> -    }
>> -
>> -  closedir (dir);
>> -
>> -  int status = get_process_info (dfd, pid);
>> -
>> -  assert (thread_list != NULL);
>> -  do
>> -    {
>> -      ptrace (PTRACE_DETACH, thread_list->tid, NULL, NULL);
>> -      thread_list = thread_list->next;
>> -    }
>> -  while (thread_list != NULL);
>> -
>> -  close (dfd);
>> -
>> -  return status;
>> -}
>> -
>> -
>> -/* Wait for PID to enter ptrace-stop state after being attached.  */
>> -static void
>> -wait_for_ptrace_stop (long int pid)
>> -{
>> -  int status;
>> -
>> -  /* While waiting for SIGSTOP being delivered to the tracee we have to
>> -     reinject any other pending signal.  Ignore all other errors.  */
>> -  while (waitpid (pid, &status, __WALL) == pid && WIFSTOPPED (status))
>> -    {
>> -      /* The STOP signal should not be delivered to the tracee.  */
>> -      if (WSTOPSIG (status) == SIGSTOP)
>> -    return;
>> -      if (ptrace (PTRACE_CONT, pid, NULL,
>> -          (void *) (uintptr_t) WSTOPSIG (status)))
>> -    /* The only possible error is that the process died.  */
>> -    return;
>> -    }
>> -}
>> -
>> -
>> -/* Handle program arguments.  */
>> -static error_t
>> -parse_opt (int key, char *arg, struct argp_state *state)
>> -{
>> -  switch (key)
>> -    {
>> -    default:
>> -      return ARGP_ERR_UNKNOWN;
>> -    }
>> -  return 0;
>> -}
>> -
>> -
>> -/* Print bug-reporting information in the help message.  */
>> -static char *
>> -more_help (int key, const char *text, void *input)
>> -{
>> -  char *tp = NULL;
>> -  switch (key)
>> -    {
>> -    case ARGP_KEY_HELP_EXTRA:
>> -      /* We print some extra information.  */
>> -      if (asprintf (&tp, gettext ("\
>> -For bug reporting instructions, please see:\n\
>> -%s.\n"), REPORT_BUGS_TO) < 0)
>> -    return NULL;
>> -      return tp;
>> -    default:
>> -      break;
>> -    }
>> -  return (char *) text;
>> -}
>> -
>> -/* Print the version information.  */
>> -static void
>> -print_version (FILE *stream, struct argp_state *state)
>> -{
>> -  fprintf (stream, "pldd %s%s\n", PKGVERSION, VERSION);
>> -  fprintf (stream, gettext ("\
>> -Copyright (C) %s Free Software Foundation, Inc.\n\
>> -This is free software; see the source for copying conditions.  There is NO\n\
>> -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
>> -"), "2019");
>> -  fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
>> -}
>> -
>> -
>> -#define CLASS 32
>> -#include "pldd-xx.c"
>> -#define CLASS 64
>> -#include "pldd-xx.c"
>> -
>> -
>> -static int
>> -get_process_info (int dfd, long int pid)
>> -{
>> -  memfd = openat (dfd, "mem", O_RDONLY);
>> -  if (memfd == -1)
>> -    goto no_info;
>> -
>> -  int fd = openat (dfd, "exe", O_RDONLY);
>> -  if (fd == -1)
>> -    {
>> -    no_info:
>> -      error (0, errno, gettext ("cannot get information about process %lu"),
>> -         pid);
>> -      return EXIT_FAILURE;
>> -    }
>> -
>> -  char e_ident[EI_NIDENT];
>> -  if (read (fd, e_ident, EI_NIDENT) != EI_NIDENT)
>> -    goto no_info;
>> -
>> -  close (fd);
>> -
>> -  if (memcmp (e_ident, ELFMAG, SELFMAG) != 0)
>> -    {
>> -      error (0, 0, gettext ("process %lu is no ELF program"), pid);
>> -      return EXIT_FAILURE;
>> -    }
>> -
>> -  fd = openat (dfd, "auxv", O_RDONLY);
>> -  if (fd == -1)
>> -    goto no_info;
>> -
>> -  size_t auxv_size = 0;
>> -  void *auxv = NULL;
>> -  while (1)
>> -    {
>> -      auxv_size += 512;
>> -      auxv = xrealloc (auxv, auxv_size);
>> -
>> -      ssize_t n = pread (fd, auxv, auxv_size, 0);
>> -      if (n < 0)
>> -    goto no_info;
>> -      if (n < auxv_size)
>> -    {
>> -      auxv_size = n;
>> -      break;
>> -    }
>> -    }
>> -
>> -  close (fd);
>> -
>> -  int retval;
>> -  if (e_ident[EI_CLASS] == ELFCLASS32)
>> -    retval = find_maps32 (pid, auxv, auxv_size);
>> -  else
>> -    retval = find_maps64 (pid, auxv, auxv_size);
>> -
>> -  free (auxv);
>> -  close (memfd);
>> -
>> -  return retval;
>> -}
>> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
>> index 52ac6ad484..e799473b17 100644
>> --- a/sysdeps/unix/sysv/linux/Makefile
>> +++ b/sysdeps/unix/sysv/linux/Makefile
>> @@ -212,10 +212,6 @@ sysdep-rtld-routines += dl-brk dl-sbrk dl-getcwd dl-openat64 dl-opendir \
>>               dl-fxstatat64
>>     libof-lddlibc4 = lddlibc4
>> -
>> -others += pldd
>> -install-bin += pldd
>> -$(objpfx)pldd: $(objpfx)xmalloc.o
>>   endif
>>     ifeq ($(subdir),rt)
>>
> 
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]