[PATCH] stack: Add -l, --list-modules. Show module memory map, build-id and files.
Mark Wielaard
mjw at redhat.com
Sat Dec 28 22:31:44 UTC 2013
Use to list modules detected for process or core file by stack program
and to see build-ids and which main elf and debug files were recognized
by libdwfl callbacks.
Signed-off-by: Mark Wielaard <mjw at redhat.com>
---
src/ChangeLog | 11 +++++++
src/stack.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 92 insertions(+), 17 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 7911236..cb9c815 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
+2013-12-28 Mark Wielaard <mjw at redhat.com>
+
+ * stack.c (print_frames): Remove address width code and use...
+ (get_addr_width): ...this new function.
+ (show_modules): New static boolean.
+ (module_callback): New static function.
+ (parse_opt): Handle '-l'.
+ (main): Add 'l' to options. If show_modules then use dwfl_getmodules
+ with module_callback to show all detected modules and possible
+ build_id, elf and dwarf files.
+
2013-12-27 Mark Wielaard <mjw at redhat.com>
* stack.c (frames_shown): New static boolean.
diff --git a/src/stack.c b/src/stack.c
index d71d669..156455c 100644
--- a/src/stack.c
+++ b/src/stack.c
@@ -23,6 +23,7 @@
#include <inttypes.h>
#include <stdio.h>
#include <stdio_ext.h>
+#include <string.h>
#include <locale.h>
#include <fcntl.h>
#include ELFUTILS_HEADER(dwfl)
@@ -49,6 +50,7 @@ static bool show_quiet = false;
#ifdef USE_DEMANGLE
static bool show_raw = false;
#endif
+static bool show_modules = false;
static unsigned maxframes = 64;
@@ -103,6 +105,70 @@ static bool frames_shown = false;
#define EXIT_USAGE 64
static int
+get_addr_width (Dwfl_Module *mod)
+{
+ // Try to find the address wide if possible.
+ static int width = 0;
+ if (width == 0 && mod)
+ {
+ Dwarf_Addr bias;
+ Elf *elf = dwfl_module_getelf (mod, &bias);
+ if (elf)
+ {
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+ if (ehdr)
+ width = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16;
+ }
+ }
+ if (width == 0)
+ width = 16;
+
+ return width;
+}
+
+static int
+module_callback (Dwfl_Module *mod, void **userdata __attribute__((unused)),
+ const char *name, Dwarf_Addr start,
+ void *arg __attribute__((unused)))
+{
+ /* Forces resolving of main elf and debug files. */
+ Dwarf_Addr bias;
+ Elf *elf = dwfl_module_getelf (mod, &bias);
+ Dwarf *dwarf = dwfl_module_getdwarf (mod, &bias);
+
+ Dwarf_Addr end;
+ const char *mainfile;
+ const char *debugfile;
+ const char *modname = dwfl_module_info (mod, NULL, NULL, &end, NULL,
+ NULL, &mainfile, &debugfile);
+ assert (strcmp (modname, name) == 0);
+
+ int width = get_addr_width (mod);
+ printf ("0x%0*" PRIx64 "-0x%0*" PRIx64 " %s\n",
+ width, start, width, end, basename (name));
+
+ const unsigned char *id;
+ GElf_Addr id_vaddr;
+ int id_len = dwfl_module_build_id (mod, &id, &id_vaddr);
+ if (id_len > 0)
+ {
+ printf (" [");
+ do
+ printf ("%02" PRIx8, *id++);
+ while (--id_len > 0);
+ printf ("]\n");
+ }
+
+ if (elf != NULL)
+ printf (" %s\n", mainfile != NULL ? mainfile : "-");
+ if (dwarf != NULL)
+ printf (" %s\n", debugfile != NULL ? debugfile : "-");
+
+ return DWARF_CB_OK;
+}
+
+static int
frame_callback (Dwfl_Frame *state, void *arg)
{
struct frames *frames = (struct frames *) arg;
@@ -137,23 +203,7 @@ print_frames (struct frames *frames, pid_t tid, int dwflerr, const char *what)
if (mod && ! show_quiet)
symname = dwfl_module_addrname (mod, pc_adjusted);
- // Try to find the address wide if possible.
- static int width = 0;
- if (width == 0 && mod)
- {
- Dwarf_Addr bias;
- Elf *elf = dwfl_module_getelf (mod, &bias);
- if (elf)
- {
- GElf_Ehdr ehdr_mem;
- GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
- if (ehdr)
- width = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16;
- }
- }
- if (width == 0)
- width = 16;
-
+ int width = get_addr_width (mod);
printf ("#%-2u 0x%0*" PRIx64, nr, width, (uint64_t) pc);
if (show_activation)
@@ -350,6 +400,10 @@ parse_opt (int key, char *arg __attribute__ ((unused)),
}
break;
+ case 'l':
+ show_modules = true;
+ break;
+
case ARGP_KEY_END:
if (core == NULL && exec != NULL)
argp_error (state,
@@ -443,6 +497,8 @@ main (int argc, char **argv)
N_("Show the backtrace of only one thread"), 0 },
{ NULL, 'n', "MAXFRAMES", 0,
N_("Show at most MAXFRAMES per thread (default 64)"), 0 },
+ { "list-modules", 'l', NULL, 0,
+ N_("Show module memory map with build-id, elf and debug files detected"), 0 },
{ NULL, 0, NULL, 0, NULL, 0 }
};
@@ -461,6 +517,14 @@ invoked with bad or missing arguments it will exit with return code 64.")
argp_parse (&argp, argc, argv, 0, NULL, NULL);
+ if (show_modules)
+ {
+ printf ("PID %d - %s module memory map\n", dwfl_pid (dwfl),
+ pid != 0 ? "process" : "core");
+ if (dwfl_getmodules (dwfl, module_callback, NULL, 0) != 0)
+ error (EXIT_BAD, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));
+ }
+
struct frames *frames = malloc (sizeof (struct frames)
+ sizeof (struct frame) * maxframes);
frames->frames = 0;
--
1.8.4.2
More information about the elfutils-devel
mailing list