From 6e06c911e1d2a0f9cbd07a6bcaa6f76d6d7648b4 Mon Sep 17 00:00:00 2001 From: Mark Wielaard 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 --- 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 + + * 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 * 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 #include #include +#include +#include #include ELFUTILS_HEADER(dwfl) #include @@ -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