+2015-12-01 Mark Wielaard <mjw@redhat.com>
+
+ * libdwflP.h (struct Dwfl_User_Core): New.
+ (struct DWfl): Replace executable_for_core with user_core.
+ * argp-std.c (parse_opt): Store core and fd in Dwfl user_core.
+ * core-file.c (dwfl_core_file_report): Check and store
+ executable_for_core in Dwfl user_core.
+ * dwfl_build_id_find_elf.c (dwfl_build_id_find_elf): Check and use
+ executable_for_core in Dwfl user_core.
+ * dwfl_end.c (dwfl_end): Release resources held in Dwfl user_core.
+ * link-map.c (report_r_debug): Check executable_for_core in Dwfl
+ user_core.
+ (dwfl_link_map_report): Likewise.
+
2015-11-16 Chih-Hung Hsieh <chh@google.com>
* dwfl_module_getdwarf.c (find_prelink_address_sync): Move nested
/* Standard argp argument parsers for tools using libdwfl.
- Copyright (C) 2005-2010, 2012 Red Hat, Inc.
+ Copyright (C) 2005-2010, 2012, 2015 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
/* Non-fatal to not be able to attach to core, ignore error. */
INTUSE(dwfl_core_file_attach) (dwfl, core);
- /* From now we leak FD and CORE. */
+ /* Store core Elf and fd in Dwfl to expose with dwfl_end. */
+ if (dwfl->user_core == NULL)
+ {
+ dwfl->user_core = calloc (1, sizeof (struct Dwfl_User_Core));
+ if (dwfl->user_core == NULL)
+ {
+ argp_failure (state, EXIT_FAILURE, 0,
+ _("Not enough memory"));
+ return ENOMEM;
+ }
+ }
+ dwfl->user_core->core = core;
+ dwfl->user_core->fd = fd;
if (result == 0)
{
return -1;
}
- free (dwfl->executable_for_core);
+ if (dwfl->user_core != NULL)
+ free (dwfl->user_core->executable_for_core);
if (executable == NULL)
- dwfl->executable_for_core = NULL;
+ {
+ if (dwfl->user_core != NULL)
+ dwfl->user_core->executable_for_core = NULL;
+ }
else
{
- dwfl->executable_for_core = strdup (executable);
- if (dwfl->executable_for_core == NULL)
+ if (dwfl->user_core == NULL)
+ {
+ dwfl->user_core = calloc (1, sizeof (struct Dwfl_User_Core));
+ if (dwfl->user_core == NULL)
+ {
+ __libdwfl_seterrno (DWFL_E_NOMEM);
+ return -1;
+ }
+ dwfl->user_core->fd = -1;
+ }
+ dwfl->user_core->executable_for_core = strdup (executable);
+ if (dwfl->user_core->executable_for_core == NULL)
{
__libdwfl_seterrno (DWFL_E_NOMEM);
return -1;
char **file_name, Elf **elfp)
{
*elfp = NULL;
- if (mod->is_executable && mod->dwfl->executable_for_core != NULL)
+ if (mod->is_executable
+ && mod->dwfl->user_core != NULL
+ && mod->dwfl->user_core->executable_for_core != NULL)
{
/* When dwfl_core_file_report was called with a non-NULL executable file
name this callback will replace the Dwfl_Module main.name with the
recorded executable file when MOD was identified as main executable
(which then triggers opening and reporting of the executable). */
- int fd = open (mod->dwfl->executable_for_core, O_RDONLY);
+ const char *executable = mod->dwfl->user_core->executable_for_core;
+ int fd = open (executable, O_RDONLY);
if (fd >= 0)
{
- *file_name = strdup (mod->dwfl->executable_for_core);
+ *file_name = strdup (executable);
if (*file_name != NULL)
return fd;
else
/* Finish a session using libdwfl.
- Copyright (C) 2005, 2008, 2012-2013 Red Hat, Inc.
+ Copyright (C) 2005, 2008, 2012-2013, 2015 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
not, see <http://www.gnu.org/licenses/>. */
#include "libdwflP.h"
+#include <unistd.h>
void
dwfl_end (Dwfl *dwfl)
__libdwfl_module_free (dead);
}
- free (dwfl->executable_for_core);
+ if (dwfl->user_core != NULL)
+ {
+ free (dwfl->user_core->executable_for_core);
+ elf_end (dwfl->user_core->core);
+ if (dwfl->user_core->fd != -1)
+ close (dwfl->user_core->fd);
+ free (dwfl->user_core);
+ }
free (dwfl);
}
/* Internal definitions for libdwfl.
- Copyright (C) 2005-2014 Red Hat, Inc.
+ Copyright (C) 2005-2015 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
extern int __libdwfl_canon_error (Dwfl_Error) internal_function;
extern void __libdwfl_seterrno (Dwfl_Error) internal_function;
+/* Resources we might keep for the user about the core file that the
+ Dwfl might have been created from. Can currently only be set
+ through std-argp. */
+struct Dwfl_User_Core
+{
+ char *executable_for_core; /* --executable if --core was specified. */
+ Elf *core; /* non-NULL if we need to free it. */
+ int fd; /* close if >= 0. */
+};
+
struct Dwfl
{
const Dwfl_Callbacks *callbacks;
GElf_Off lookup_tail_offset;
int lookup_tail_ndx;
- char *executable_for_core; /* --executable if --core was specified. */
+ struct Dwfl_User_Core *user_core;
};
#define OFFLINE_REDZONE 0x10000
if (name != NULL && name[0] == '\0')
name = NULL;
- if (iterations == 1 && dwfl->executable_for_core != NULL)
- name = dwfl->executable_for_core;
+ if (iterations == 1
+ && dwfl->user_core != NULL
+ && dwfl->user_core->executable_for_core != NULL)
+ name = dwfl->user_core->executable_for_core;
struct r_debug_info_module *r_debug_info_module = NULL;
if (r_debug_info != NULL)
bool in_ok = (*memory_callback) (dwfl, phdr_segndx, &in.d_buf,
&in.d_size, phdr, phnum * phent,
memory_callback_arg);
- if (! in_ok && dwfl->executable_for_core != NULL)
+ if (! in_ok
+ && dwfl->user_core != NULL
+ && dwfl->user_core->executable_for_core != NULL)
{
/* AUXV -> PHDR -> DYNAMIC
Both AUXV and DYNAMIC should be always present in a core file.
EXECUTABLE_FOR_CORE to find where DYNAMIC is located in the
core file. */
- int fd = open (dwfl->executable_for_core, O_RDONLY);
+ int fd = open (dwfl->user_core->executable_for_core, O_RDONLY);
Elf *elf;
Dwfl_Error error = DWFL_E_ERRNO;
if (fd != -1)