This is the mail archive of the mailing list for the elfutils 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]

[patch] Fix executable_for_core for non-dwfl_standard_argp

Hi Mark,

currently dwfl->executable_for_core is private.  It is set from
libdwfl/argp-std.c but it is used also from libdwfl/link_map.c.
Applications not using dwfl_standard_argp () cannot use executable_for_core.

This has effect for running jankratochvil/unwindx86 on RHEL-5.  RHEL-5 does
not have build-ids, therefore its core files do not contain the first page of
each ELF file.  I such case one needs dwfl->executable_for_core to find the
missing program headers (to find DYNAMIC segment).  src/stack.c was working
there (thanks to dwfl_standard_argp ()) but tests/backtrace.c was not, as it
calls dwfl_core_file_report () on its own.

Unfortunately jankratochvil/unwindx86 does not work yet on RHEL-5 but that is
unrelated (there is some race with SIGSTOPs, that will be a different patch).

No testcase here.  It should be reproducible with jankratochvil/unwindx86 on
RHEL-5 hosts.  I could provide a core file generated without the first ELF
page dumping with matching executable but I have not.


2013-10-29  Jan Kratochvil  <>

	* NEWS (Version 0.158): New.

2013-10-29  Jan Kratochvil  <>

	* (ELFUTILS_0.158): New.

2013-10-29  Jan Kratochvil  <>

	* argp-std.c (parse_opt): Use executable parameter of
	* core-file.c (dwfl_core_file_report): Add parameter executable.  Set
	it to DWFL.  Add NEW_VERSION for it.
	(_compat_without_executable_dwfl_core_file_report): New.  Twice.
	* libdwfl.h (dwfl_core_file_report): Add parameter executable, update
	the function comment.

diff --git a/NEWS b/NEWS
index 7236f66..9d73f09 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+Version 0.158
+libdwfl: dwfl_core_file_report has new parameter executable.
 Version 0.157
 libdw: Add new functions dwarf_getlocations, dwarf_getlocation_attr
diff --git a/libdw/ b/libdw/
index 09eae6a..5fb6660 100644
--- a/libdw/
+++ b/libdw/
@@ -267,3 +267,9 @@ ELFUTILS_0.157 {
 } ELFUTILS_0.156;
+ELFUTILS_0.158 {
+  global:
+    # Replaced ELFUTILS_0.146 version, which has a wrapper without executable.
+    dwfl_core_file_report;
+} ELFUTILS_0.157;
diff --git a/libdwfl/argp-std.c b/libdwfl/argp-std.c
index c884390..322cdf4 100644
--- a/libdwfl/argp-std.c
+++ b/libdwfl/argp-std.c
@@ -295,9 +295,6 @@ parse_opt (int key, char *arg, struct argp_state *state)
 	if (opt->core)
-	    if (opt->e)
-	      dwfl->executable_for_core = strdup (opt->e);
 	    int fd = open64 (opt->core, O_RDONLY);
 	    if (fd < 0)
@@ -317,7 +314,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
 		return error == DWFL_E_ERRNO ? errno : EIO;
-	    int result = INTUSE(dwfl_core_file_report) (dwfl, core);
+	    int result = INTUSE(dwfl_core_file_report) (dwfl, core, opt->e);
 	    if (result < 0)
 		elf_end (core);
diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c
index 7207591..37613b8 100644
--- a/libdwfl/core-file.c
+++ b/libdwfl/core-file.c
@@ -398,7 +398,7 @@ clear_r_debug_info (struct r_debug_info *r_debug_info)
-dwfl_core_file_report (Dwfl *dwfl, Elf *elf)
+dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
   size_t phnum;
   if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
@@ -407,6 +407,19 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf)
       return -1;
+  free (dwfl->executable_for_core);
+  if (executable == NULL)
+    dwfl->executable_for_core = NULL;
+  else
+    {
+      dwfl->executable_for_core = strdup (executable);
+      if (dwfl->executable_for_core == NULL)
+	{
+	  __libdwfl_seterrno (DWFL_E_NOMEM);
+	  return -1;
+	}
+    }
   /* First report each PT_LOAD segment.  */
   GElf_Phdr notes_phdr;
   int ndx = dwfl_report_core_segments (dwfl, elf, phnum, &notes_phdr);
@@ -524,3 +537,16 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf)
   return sniffed || listed >= 0 ? listed + sniffed : listed;
 INTDEF (dwfl_core_file_report)
+NEW_VERSION (dwfl_core_file_report, ELFUTILS_0.158)
+#ifdef SHARED
+int _compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf);
+COMPAT_VERSION_NEWPROTO (dwfl_core_file_report, ELFUTILS_0.146,
+			 without_executable)
+_compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf)
+  return dwfl_core_file_report (dwfl, elf, NULL);
diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h
index 2b70e28..2ba8234 100644
--- a/libdwfl/libdwfl.h
+++ b/libdwfl/libdwfl.h
@@ -349,11 +349,13 @@ extern int dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release,
    This can follow a dwfl_report_offline call to bootstrap the
    DT_DEBUG method of following the dynamic linker link_map chain, in
    case the core file does not contain enough of the executable's text
-   segment to locate its PT_DYNAMIC in the dump.  This might call
-   dwfl_report_elf on file names found in the dump if reading some
-   link_map files is the only way to ascertain those modules' addresses.
+   segment to locate its PT_DYNAMIC in the dump.  In such case you need to
+   supply non-NULL EXECUTABLE, otherwise dynamic libraries will not be loaded
+   into the DWFL map.  This might call dwfl_report_elf on file names found in
+   the dump if reading some link_map files is the only way to ascertain those
+   modules' addresses.
    Returns the number of modules reported, or -1 for errors.  */
-extern int dwfl_core_file_report (Dwfl *dwfl, Elf *elf);
+extern int dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable);
 /* Call dwfl_report_module for each file mapped into the address space of PID.
    Returns zero on success, -1 if dwfl_report_module failed,

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