Hi,

jankratochvil/deleted
https://bugzilla.redhat.com/show_bug.cgi?id=1130781#c3

Implemented the fix suggested there.


Thanks,
Jan
--- Begin Message ---
Formerly shared libraries did not get resolved properly:
        #2  0x00007fc4d86c56d6
        #3  0x0000000000400938 main

Fixed elfutils produce:
        #2  0x00007f61094876d6 libfunc
        #3  0x0000000000400938 main

Signed-off-by: Jan Kratochvil <jan.kratoch...@redhat.com>
---
 libdwfl/ChangeLog              |  6 +++++
 libdwfl/dwfl_module_getdwarf.c | 11 +++++-----
 tests/ChangeLog                |  9 ++++++++
 tests/Makefile.am              | 10 ++++++---
 tests/deleted-lib.c            | 27 +++++++++++++++++++++++
 tests/deleted.c                | 50 ++++++++++++++++++++++++++++++++++++++++++
 tests/run-deleted.sh           | 40 +++++++++++++++++++++++++++++++++
 7 files changed, 145 insertions(+), 8 deletions(-)
 create mode 100644 tests/deleted-lib.c
 create mode 100644 tests/deleted.c
 create mode 100755 tests/run-deleted.sh

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index c644ffe..3de772e 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,9 @@
+2014-08-28  Jan Kratochvil  <jan.kratoch...@redhat.com>
+
+       * dwfl_module_getdwarf.c (find_offsets): Add parameter main_bias, use
+       it.
+       (find_dynsym): Pass the new parameter main_bias.
+
 2014-08-14  Mark Wielaard  <m...@redhat.com>
 
        * linux-kernel-modules.c (check-suffix): Also TRY .ko.xz.
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index 7259984..e705f57 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -621,7 +621,7 @@ load_symtab (struct dwfl_file *file, struct dwfl_file 
**symfile,
 /* Translate addresses into file offsets.
    OFFS[*] start out zero and remain zero if unresolved.  */
 static void
-find_offsets (Elf *elf, size_t phnum, size_t n,
+find_offsets (Elf *elf, GElf_Addr main_bias, size_t phnum, size_t n,
              GElf_Addr addrs[n], GElf_Off offs[n])
 {
   size_t unsolved = n;
@@ -632,10 +632,10 @@ find_offsets (Elf *elf, size_t phnum, size_t n,
       if (phdr != NULL && phdr->p_type == PT_LOAD && phdr->p_memsz > 0)
        for (size_t j = 0; j < n; ++j)
          if (offs[j] == 0
-             && addrs[j] >= phdr->p_vaddr
-             && addrs[j] - phdr->p_vaddr < phdr->p_filesz)
+             && addrs[j] >= phdr->p_vaddr + main_bias
+             && addrs[j] - (phdr->p_vaddr + main_bias) < phdr->p_filesz)
            {
-             offs[j] = addrs[j] - phdr->p_vaddr + phdr->p_offset;
+             offs[j] = addrs[j] - (phdr->p_vaddr + main_bias) + phdr->p_offset;
              if (--unsolved == 0)
                break;
            }
@@ -720,7 +720,8 @@ find_dynsym (Dwfl_Module *mod)
 
          /* Translate pointers into file offsets.  */
          GElf_Off offs[i_max] = { 0, };
-         find_offsets (mod->main.elf, phnum, i_max, addrs, offs);
+         find_offsets (mod->main.elf, mod->main_bias, phnum, i_max, addrs,
+                       offs);
 
          /* Figure out the size of the symbol table.  */
          if (offs[i_hash] != 0)
diff --git a/tests/ChangeLog b/tests/ChangeLog
index dce6ebe..3f12728 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,12 @@
+2014-08-28  Jan Kratochvil  <jan.kratoch...@redhat.com>
+
+       * Makefile.am (check_PROGRAMS): Add deleted and deleted-lib.so.
+       (TESTS, EXTRA_DIST): Add run-deleted.sh.
+       (deleted_LDADD, deleted_lib_so_LDFLAGS, deleted_lib_so_CFLAGS): New.
+       * deleted-lib.c: New file.
+       * deleted.c: New file.
+       * run-deleted.sh: New file.
+
 2014-06-15  Mark Wielaard  <m...@redhat.com>
 
        * backtrace.c (frame_callback): Error on seeing more than 16 frames.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4cc81c9..be3494d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -50,7 +50,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames 
sectiondump \
                  test-elf_cntl_gelf_getshdr dwflsyms dwfllines \
                  dwfl-report-elf-align varlocs backtrace backtrace-child \
                  backtrace-data backtrace-dwarf debuglink debugaltlink \
-                 buildid
+                 buildid deleted deleted-lib.so
 
 asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
            asm-tst6 asm-tst7 asm-tst8 asm-tst9
@@ -109,7 +109,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile 
test-nlist \
        run-backtrace-core-s390x.sh run-backtrace-core-s390.sh \
        run-backtrace-core-aarch64.sh \
        run-backtrace-demangle.sh run-stack-d-test.sh run-stack-i-test.sh \
-       run-readelf-dwz-multi.sh run-allfcts-multi.sh
+       run-readelf-dwz-multi.sh run-allfcts-multi.sh run-deleted.sh
 
 if !BIARCH
 export ELFUTILS_DISABLE_BIARCH = 1
@@ -271,7 +271,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
             testfile-backtrace-demangle.core.bz2 \
             run-stack-d-test.sh run-stack-i-test.sh \
             testfiledwarfinlines.bz2 testfiledwarfinlines.core.bz2 \
-            run-readelf-zdebug.sh testfile-debug.bz2 testfile-zdebug.bz2
+            run-readelf-zdebug.sh testfile-debug.bz2 testfile-zdebug.bz2 \
+            run-deleted.sh
 
 if USE_VALGRIND
 valgrind_cmd='valgrind -q --error-exitcode=1 --run-libc-freeres=no'
@@ -406,6 +407,9 @@ backtrace_dwarf_LDADD = $(libdw) $(libelf)
 debuglink_LDADD = $(libdw) $(libelf)
 debugaltlink_LDADD = $(libdw) $(libelf)
 buildid_LDADD = $(libdw) $(libelf)
+deleted_LDADD = ./deleted-lib.so
+deleted_lib_so_LDFLAGS = -shared -rdynamic
+deleted_lib_so_CFLAGS = -fPIC
 
 if GCOV
 check: check-am coverage
diff --git a/tests/deleted-lib.c b/tests/deleted-lib.c
new file mode 100644
index 0000000..1ff411b
--- /dev/null
+++ b/tests/deleted-lib.c
@@ -0,0 +1,27 @@
+/* Test program for opening already deleted running binaries.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <unistd.h>
+
+void
+libfunc (void)
+{
+  sleep (60000);
+  /* Avoid tail call optimization for the sleep call.  */
+  asm volatile ("");
+}
diff --git a/tests/deleted.c b/tests/deleted.c
new file mode 100644
index 0000000..32a310b
--- /dev/null
+++ b/tests/deleted.c
@@ -0,0 +1,50 @@
+/* Test program for opening already deleted running binaries.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdio.h>
+#include <error.h>
+#include <errno.h>
+
+extern void libfunc (void);
+
+int
+main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)))
+{
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  pid_t pid = fork ();
+  assert (pid != -1);
+  if (pid == 0)
+    {
+      int err = close (0);
+      assert (!err);
+      err = close (1);
+      assert (!err);
+      err = close (2);
+      assert (!err);
+      libfunc ();
+      abort ();
+    }
+  printf ("%d\n", pid);
+  return EXIT_SUCCESS;
+}
diff --git a/tests/run-deleted.sh b/tests/run-deleted.sh
new file mode 100755
index 0000000..ca1130a
--- /dev/null
+++ b/tests/run-deleted.sh
@@ -0,0 +1,40 @@
+#! /bin/bash
+# Copyright (C) 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Older Linux (such as 2.6.32) required PTRACE_ATTACH to read /proc/PID/mem.
+sleep 60 & p=$!; sleep 0.1
+addr=0x$(cat /proc/$p/maps|sed -n 's#^\([0-9a-f]*\)-[0-9a-f]* r[^ ]* 00* 
.*/sleep$#\1#p'|head -n1)
+supported=$[$(dd if=/proc/$p/mem bs=1 skip=$[$addr] count=1|wc -c)]
+kill -9 $p
+if [ $supported -eq 0 ]; then
+  exit 77
+fi
+
+tempfiles deleted deleted-lib.so
+cp -p ${abs_builddir}/deleted ${abs_builddir}/deleted-lib.so .
+pid=$(testrun ${abs_builddir}/deleted)
+sleep 1
+rm -f deleted deleted-lib.so
+tempfiles bt
+testrun ${abs_top_builddir}/src/stack -p $pid >bt
+cat bt
+kill -9 $pid
+wait
+grep -qw libfunc bt
+grep -qw main bt
-- 
1.9.3

--- End Message ---

Reply via email to