This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
Re: [PATCH] Add --core-pattern option to eu-stack
- From: Mark Wielaard <mjw at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Mon, 03 Nov 2014 14:22:23 +0100
- Subject: Re: [PATCH] Add --core-pattern option to eu-stack
On Thu, 2014-10-30 at 22:55 +0100, Mark Wielaard wrote:
> I did have to lookup how to use this though. And I couldn't make it work
> without adding an -o option to eu-stack to explicitly redirect output
> since it seems you cannot use normal shell redirections
> in /proc/sys/kernel/core_pattern. So I had to use something like
> --output=/proc/%p/cwd/%i.stack. Where does the stdout of the
> core_pattern end up otherwise?
For reference. Attached is the cleaned up -o support patch I added.
It is a little paranoid setting umask and using O_EXCL explicitly.
But I think that is correct behavior when used in cases where normal
shell redirection doesn't work.
Cheers,
Mark
From 6e06c911e1d2a0f9cbd07a6bcaa6f76d6d7648b4 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mjw@redhat.com>
Date: Mon, 3 Nov 2014 14:16:57 +0100
Subject: [PATCH] stack: Add --output, -o option.
-o, --output=FILE Place output into FILE. FILE should not yet exists and
will be created.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
---
src/ChangeLog | 10 ++++++++++
src/stack.c | 56 ++++++++++++++++++++++++++++++++++++--------------------
2 files changed, 46 insertions(+), 20 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index a252cdc..70d6325 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
+2014-19-03 Mark Wielaard <mjw@redhat.com>
+
+ * stack.c (fout): New static variable.
+ (module_callback): fprintf to fout.
+ (print_frame): Likewise.
+ (print_frames): Likewise.
+ (parse_opt): Handle 'o'.
+ (main): Add --output, -o to options. Set fout to stdout.
+ fprintf to fout.
+
2014-09-14 Petr Machata <pmachata@redhat.com>
* readelf.c (handle_relocs_rela): Typo fix, test DESTSHDR properly.
diff --git a/src/stack.c b/src/stack.c
index c277dfd..0b1d235 100644
--- a/src/stack.c
+++ b/src/stack.c
@@ -26,6 +26,8 @@
#include <string.h>
#include <locale.h>
#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include ELFUTILS_HEADER(dwfl)
#include <dwarf.h>
@@ -97,6 +99,9 @@ static char *demangle_buffer = NULL;
/* Whether any frames have been shown at all. Determines exit status. */
static bool frames_shown = false;
+/* Where --output/-o goes to (stdout by default). */
+static FILE *fout;
+
/* Program exit codes. All frames shown without any errors is GOOD.
Some frames shown with some non-fatal errors is an ERROR. A fatal
error or no frames shown at all is BAD. A command line USAGE exit
@@ -147,7 +152,7 @@ module_callback (Dwfl_Module *mod, void **userdata __attribute__((unused)),
assert (strcmp (modname, name) == 0);
int width = get_addr_width (mod);
- printf ("0x%0*" PRIx64 "-0x%0*" PRIx64 " %s\n",
+ fprintf (fout, "0x%0*" PRIx64 "-0x%0*" PRIx64 " %s\n",
width, start, width, end, basename (name));
const unsigned char *id;
@@ -155,17 +160,17 @@ module_callback (Dwfl_Module *mod, void **userdata __attribute__((unused)),
int id_len = dwfl_module_build_id (mod, &id, &id_vaddr);
if (id_len > 0)
{
- printf (" [");
+ fprintf (fout, " [");
do
- printf ("%02" PRIx8, *id++);
+ fprintf (fout, "%02" PRIx8, *id++);
while (--id_len > 0);
- printf ("]\n");
+ fprintf (fout, "]\n");
}
if (elf != NULL)
- printf (" %s\n", mainfile != NULL ? mainfile : "-");
+ fprintf (fout, " %s\n", mainfile != NULL ? mainfile : "-");
if (dwarf != NULL)
- printf (" %s\n", debugfile != NULL ? debugfile : "-");
+ fprintf (fout, " %s\n", debugfile != NULL ? debugfile : "-");
return DWARF_CB_OK;
}
@@ -219,10 +224,10 @@ print_frame (int nr, Dwarf_Addr pc, bool isactivation,
Dwarf_Die *die)
{
int width = get_addr_width (mod);
- printf ("#%-2u 0x%0*" PRIx64, nr, width, (uint64_t) pc);
+ fprintf (fout, "#%-2u 0x%0*" PRIx64, nr, width, (uint64_t) pc);
if (show_activation)
- printf ("%4s", ! isactivation ? "- 1" : "");
+ fprintf (fout, "%4s", ! isactivation ? "- 1" : "");
if (symname != NULL)
{
@@ -237,7 +242,7 @@ print_frame (int nr, Dwarf_Addr pc, bool isactivation,
symname = demangle_buffer = dsymname;
}
#endif
- printf (" %s", symname);
+ fprintf (fout, " %s", symname);
}
const char* fname;
@@ -247,7 +252,7 @@ print_frame (int nr, Dwarf_Addr pc, bool isactivation,
if (show_module)
{
if (fname != NULL)
- printf (" - %s", fname);
+ fprintf (fout, " - %s", fname);
}
if (show_build_id)
@@ -257,11 +262,11 @@ print_frame (int nr, Dwarf_Addr pc, bool isactivation,
int id_len = dwfl_module_build_id (mod, &id, &id_vaddr);
if (id_len > 0)
{
- printf ("\n [");
+ fprintf (fout, "\n [");
do
- printf ("%02" PRIx8, *id++);
+ fprintf (fout, "%02" PRIx8, *id++);
while (--id_len > 0);
- printf ("]@0x%0" PRIx64 "+0x%" PRIx64,
+ fprintf (fout, "]@0x%0" PRIx64 "+0x%" PRIx64,
start, pc_adjusted - start);
}
}
@@ -303,16 +308,16 @@ print_frame (int nr, Dwarf_Addr pc, bool isactivation,
if (sname != NULL)
{
- printf ("\n %s", sname);
+ fprintf (fout, "\n %s", sname);
if (line > 0)
{
- printf (":%d", line);
+ fprintf (fout, ":%d", line);
if (col > 0)
- printf (":%d", col);
+ fprintf (fout, ":%d", col);
}
}
}
- printf ("\n");
+ fprintf (fout, "\n");
}
static void
@@ -362,7 +367,7 @@ print_frames (struct frames *frames, pid_t tid, int dwflerr, const char *what)
if (frames->frames > 0)
frames_shown = true;
- printf ("TID %d:\n", tid);
+ fprintf (fout, "TID %d:\n", tid);
int frame_nr = 0;
for (int nr = 0; nr < frames->frames && (maxframes == 0
|| frame_nr < maxframes); nr++)
@@ -560,6 +565,14 @@ parse_opt (int key, char *arg __attribute__ ((unused)),
show_modules = true;
break;
+ case 'o':
+ umask (S_IWGRP | S_IWOTH);
+ fout = fopen (arg, "wx");
+ if (fout == NULL)
+ error (EXIT_BAD, errno,
+ N_("Cannot create and exclusively open output file '%s'"), arg);
+ break;
+
case ARGP_KEY_END:
if (core == NULL && exec != NULL)
argp_error (state,
@@ -658,6 +671,8 @@ main (int argc, char **argv)
N_("Additionally show inlined function frames using DWARF debuginfo if available (implies -d)"), 0 },
{ "module", 'm', NULL, 0,
N_("Additionally show module file information"), 0 },
+ { "output", 'o', "FILE", 0,
+ N_("Place output into FILE. FILE should not yet exists and will be created."), 0 },
{ "source", 's', NULL, 0,
N_("Additionally show source file information"), 0 },
{ "verbose", 'v', NULL, 0,
@@ -690,11 +705,12 @@ occured the program exits with return code 2. If the program was \
invoked with bad or missing arguments it will exit with return code 64.")
};
+ fout = stdout;
argp_parse (&argp, argc, argv, 0, NULL, NULL);
if (show_modules)
{
- printf ("PID %d - %s module memory map\n", dwfl_pid (dwfl),
+ fprintf (fout, "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));
@@ -727,7 +743,7 @@ invoked with bad or missing arguments it will exit with return code 64.")
}
else
{
- printf ("PID %d - %s\n", dwfl_pid (dwfl), pid != 0 ? "process" : "core");
+ fprintf (fout, "PID %d - %s\n", dwfl_pid (dwfl), pid != 0 ? "process" : "core");
switch (dwfl_getthreads (dwfl, thread_callback, &frames))
{
case DWARF_CB_OK:
--
1.8.3.1