diff options
author | Jan Kratochvil <jan.kratochvil@redhat.com> | 2012-11-12 21:21:58 +0100 |
---|---|---|
committer | Jan Kratochvil <jan.kratochvil@redhat.com> | 2012-11-12 21:21:58 +0100 |
commit | f670f296d076c8dd6694efff94902a013ee1acd1 (patch) | |
tree | 6cdd0e791cdcc040557913900c0a9cc33ae9ec73 | |
parent | 0ed122675b083c8e27e54fa84ffa39d748f5df3d (diff) | |
download | elfutils-f670f296d076c8dd6694efff94902a013ee1acd1.tar.gz |
+dwfl_core_filename_report
-rw-r--r-- | libdwfl/argp-std.c | 20 | ||||
-rw-r--r-- | libdwfl/core-file.c | 37 | ||||
-rw-r--r-- | libdwfl/libdwfl.h | 8 |
3 files changed, 48 insertions, 17 deletions
diff --git a/libdwfl/argp-std.c b/libdwfl/argp-std.c index f0c530f2..8aeb80a1 100644 --- a/libdwfl/argp-std.c +++ b/libdwfl/argp-std.c @@ -205,7 +205,6 @@ parse_opt (int key, char *arg, struct argp_state *state) { FILE *f = fopen (arg, "r"); if (f == NULL) - nofile: { int code = errno; argp_failure (state, EXIT_FAILURE, code, @@ -291,31 +290,18 @@ parse_opt (int key, char *arg, struct argp_state *state) if (opt->core) { - int fd = open64 (opt->core, O_RDONLY); - if (fd < 0) - goto nofile; - - Elf *core; - Dwfl_Error error = __libdw_open_file (&fd, &core, true, false); - if (error != DWFL_E_NOERROR) + if (dwfl_core_filename_report (dwfl, NULL, opt->core) == NULL) { + Dwfl_Error error = dwfl_errno (); argp_failure (state, EXIT_FAILURE, 0, _("cannot read ELF core file: %s"), INTUSE(dwfl_errmsg) (error)); return error == DWFL_E_ERRNO ? errno : EIO; } - int result = INTUSE(dwfl_core_file_report) (dwfl, core); - if (result < 0) - { - elf_end (core); - close (fd); - return fail (dwfl, result, opt->core); - } - /* From now we leak FD and CORE. */ - if (result == 0) + if (dwfl->modulelist == NULL) { argp_failure (state, EXIT_FAILURE, 0, _("No modules recognized in core file")); diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c index 1545ca86..f2178472 100644 --- a/libdwfl/core-file.c +++ b/libdwfl/core-file.c @@ -37,6 +37,7 @@ #include <endian.h> #include <byteswap.h> #include "system.h" +#include <fcntl.h> /* This is a prototype of what a new libelf interface might be. @@ -461,3 +462,39 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf) return sniffed == 0 || listed > sniffed ? listed : sniffed; } INTDEF (dwfl_core_file_report) + +Elf * +dwfl_core_filename_report (Dwfl *dwfl, int *fdp, const char *filename) +{ + int fd_storage = -1; + if (fdp == NULL) + fdp = &fd_storage; + + if (*fdp < 0) + { + *fdp = open64 (filename, O_RDONLY); + if (*fdp < 0) + { + __libdwfl_seterrno (DWFL_E_ERRNO); + return NULL; + } + } + + Elf *core; + Dwfl_Error error = __libdw_open_file (fdp, &core, true, false); + if (error != DWFL_E_NOERROR) + { + __libdwfl_seterrno (error); + return NULL; + } + + int result = INTUSE(dwfl_core_file_report) (dwfl, core); + if (result < 0) + { + elf_end (core); + close (*fdp); + return NULL; + } + return core; +} +INTDEF (dwfl_core_filename_report) diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index a2ab8246..c2b85f4b 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -355,6 +355,14 @@ extern int dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release, Returns the number of modules reported, or -1 for errors. */ extern int dwfl_core_file_report (Dwfl *dwfl, Elf *elf); +/* Call dwfl_core_file_report but providing FILENAME instead. Function returns + opened core file Elf * and its *FDP file descriptor which must be held valid + until dwfl_end is called for DWFL. FDP can be passed as NULL (but the + caller cannot close the file descriptor then). Function returns NULL for + errors, check dwfl_errmsg in such case. */ +extern Elf *dwfl_core_filename_report (Dwfl *dwfl, int *fdp, + const char *filename); + /* Call dwfl_report_module for each file mapped into the address space of PID. Returns zero on success, -1 if dwfl_report_module failed, or an errno code if opening the kernel binary failed. */ |