/* Get Dwarf Frame state for target live PID process.
- Copyright (C) 2013, 2014 Red Hat, Inc.
+ Copyright (C) 2013, 2014, 2015 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
the GNU Lesser General Public License along with this program. If
not, see <http://www.gnu.org/licenses/>. */
+#include "libelfP.h"
#include "libdwflP.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <dirent.h>
pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
{
struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
+ elf_end (pid_arg->elf);
+ close (pid_arg->elf_fd);
closedir (pid_arg->dir);
free (pid_arg);
}
goto fail;
}
- char dirname[64];
- int i = snprintf (dirname, sizeof (dirname), "/proc/%ld/task", (long) pid);
- assert (i > 0 && i < (ssize_t) sizeof (dirname) - 1);
- DIR *dir = opendir (dirname);
+ char name[64];
+ int i = snprintf (name, sizeof (name), "/proc/%ld/task", (long) pid);
+ assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
+ DIR *dir = opendir (name);
if (dir == NULL)
{
err = errno;
goto fail;
}
+
+ Elf *elf;
+ i = snprintf (name, sizeof (name), "/proc/%ld/exe", (long) pid);
+ assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
+ int elf_fd = open (name, O_RDONLY);
+ if (elf_fd >= 0)
+ {
+ elf = elf_begin (elf_fd, ELF_C_READ_MMAP, NULL);
+ if (elf == NULL)
+ {
+ /* Just ignore, dwfl_attach_state will fall back to trying
+ to associate the Dwfl with one of the existing DWfl_Module
+ ELF images (to know the machine/class backend to use). */
+ close (elf_fd);
+ elf_fd = -1;
+ }
+ }
+ else
+ elf = NULL;
struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
if (pid_arg == NULL)
{
+ elf_end (elf);
+ close (elf_fd);
closedir (dir);
err = ENOMEM;
goto fail;
}
pid_arg->dir = dir;
+ pid_arg->elf = elf;
+ pid_arg->elf_fd = elf_fd;
pid_arg->tid_attached = 0;
pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
- if (! INTUSE(dwfl_attach_state) (dwfl, NULL, pid, &pid_thread_callbacks,
+ if (! INTUSE(dwfl_attach_state) (dwfl, elf, pid, &pid_thread_callbacks,
pid_arg))
{
+ elf_end (elf);
+ close (elf_fd);
closedir (dir);
free (pid_arg);
return -1;