diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index 12ee116..e55cc4b 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -401,6 +401,8 @@ struct dwfl_arange
struct __libdwfl_pid_arg
{
DIR *dir;
+ Elf *self;
+ int self_fd;
/* It is 0 if not used. */
pid_t tid_attached;
/* Valid only if TID_ATTACHED is not zero. */
diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c
index ae71702..7d69ce0 100644
--- a/libdwfl/linux-pid-attach.c
+++ b/libdwfl/linux-pid-attach.c
@@ -27,6 +27,9 @@
not, see . */
#include "libdwflP.h"
+#include
+#include
+#include
#include
#include
#include
@@ -247,6 +250,8 @@ static void
pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
{
struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
+ elf_end (pid_arg->self);
+ close (pid_arg->self_fd);
closedir (pid_arg->dir);
free (pid_arg);
}
@@ -332,15 +337,32 @@ dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
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;
}
+ i = snprintf (name, sizeof (name), "/proc/%ld/exe", (long) pid);
+ assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
+ int fd = open (name, O_RDONLY);
+ if (fd < 0)
+ {
+ err = errno;
+ goto fail;
+ }
+ Elf *self = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+ if (self == NULL)
+ {
+ /* We need to return an errno, so we should really translate the
+ elf_errno back to an errno, but lets just assume it is ENOMEM. */
+ err = ENOMEM;
+ close (fd);
+ goto fail;
+ }
struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
if (pid_arg == NULL)
{
@@ -349,11 +371,15 @@ dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
goto fail;
}
pid_arg->dir = dir;
+ pid_arg->self = self;
+ pid_arg->self_fd = 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, self, pid, &pid_thread_callbacks,
pid_arg))
{
+ elf_end (self);
+ close (fd);
closedir (dir);
free (pid_arg);
return -1;